」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 在 Python 中使用標準化剪切 (NCut) 進行無監督影像分割的指南

在 Python 中使用標準化剪切 (NCut) 進行無監督影像分割的指南

發佈於2024-11-08
瀏覽:567

A Guide to Unsupervised Image Segmentation using Normalized Cuts (NCut) in Python

介绍

图像分割在理解和分析视觉数据方面起着至关重要的作用,而归一化剪切(NCut)是一种广泛使用的基于图的分割方法。在本文中,我们将探索如何使用 Microsoft Research 的数据集在 Python 中应用 NCut 进行无监督图像分割,重点是使用超像素提高分割质量。
数据集概述
用于此任务的数据集可以从以下链接下载:MSRC 对象类别图像数据库。该数据集包含原始图像及其语义分割为九个对象类(由以“_GT”结尾的图像文件表示)。这些图像被分组为主题子集,其中文件名中的第一个数字指的是类别子集。该数据集非常适合试验分割任务。

问题陈述

我们使用 NCut 算法对数据集中的图像进行图像分割。像素级分割的计算成本很高,而且通常存在噪声。为了克服这个问题,我们使用 SLIC(简单线性迭代聚类)来生成超像素,它将相似的像素分组并减少问题的大小。为了评估分割的准确性,可以使用不同的指标(例如,并集交集、SSIM、兰德指数)。

执行

1。安装所需的库
我们使用 skimage 进行图像处理,使用 numpy 进行数值计算,使用 matplotlib 进行可视化。

pip install numpy matplotlib
pip install scikit-image==0.24.0
**2. Load and Preprocess the Dataset**

下载并提取数据集后,加载图像并进行地面实况分割:

wget http://download.microsoft.com/download/A/1/1/A116CD80-5B79-407E-B5CE-3D5C6ED8B0D5/msrc_objcategimagedatabase_v1.zip -O msrc_objcategimagedatabase_v1.zip
unzip msrc_objcategimagedatabase_v1.zip
rm msrc_objcategimagedatabase_v1.zip

现在我们准备开始编码了。

from skimage import io, segmentation, color, measure
from skimage import graph
import numpy as np
import matplotlib.pyplot as plt

# Load the image and its ground truth
image = io.imread('/content/MSRC_ObjCategImageDatabase_v1/1_16_s.bmp')
ground_truth = io.imread('/content/MSRC_ObjCategImageDatabase_v1/1_16_s_GT.bmp')

# show images side by side
fig, ax = plt.subplots(1, 2, figsize=(10, 5))
ax[0].imshow(image)
ax[0].set_title('Image')
ax[1].imshow(ground_truth)
ax[1].set_title('Ground Truth')
plt.show()

3.使用 SLIC 生成超像素并创建区域邻接图

我们在应用 NCut 之前使用 SLIC 算法来计算超像素。使用生成的超像素,我们基于平均颜色相似度构建区域邻接图(RAG):

from skimage.util import img_as_ubyte, img_as_float, img_as_uint, img_as_float64

compactness=30 
n_segments=100 
labels = segmentation.slic(image, compactness=compactness, n_segments=n_segments, enforce_connectivity=True)
image_with_boundaries = segmentation.mark_boundaries(image, labels, color=(0, 0, 0))
image_with_boundaries = img_as_ubyte(image_with_boundaries)
pixel_labels = color.label2rgb(labels, image_with_boundaries, kind='avg', bg_label=0

紧凑性控制形成超像素时像素的颜色相似度和空间接近度之间的平衡。它决定了对保持超像素紧凑(在空间方面更接近)与确保它们按颜色更均匀分组的重视程度。
较高的值:较高的紧凑度值会导致算法优先创建空间紧凑且大小均匀的超像素,而较少关注颜色相似性。这可能会导致超像素对边缘或颜色渐变不太敏感。
较低的值:较低的紧凑度值允许超像素在空间尺寸上变化更大,以便更准确地考虑颜色差异。这通常会导致超像素更紧密地遵循图像中对象的边界。

n_segments 控制 SLIC 算法尝试在图像中生成的超像素(或段)的数量。本质上,它设置了分割的分辨率。
较高的值:较高的 n_segments 值会创建更多的超像素,这意味着每个超像素会更小,分割会更细粒度。当图像具有复杂纹理或小对象时,这非常有用。
较低的值:较低的 n_segments 值会产生更少、更大的超像素。当您想要对图像进行粗分割,将较大的区域分组为单个超像素时,这非常有用。

4。应用标准化剪切 (NCut) 并可视化结果

# using the labels found with the superpixeled image
# compute the Region Adjacency Graph using mean colors
g = graph.rag_mean_color(image, labels, mode='similarity')

# perform Normalized Graph cut on the Region Adjacency Graph
labels2 = graph.cut_normalized(labels, g)
segmented_image = color.label2rgb(labels2, image, kind='avg')
f, axarr = plt.subplots(nrows=1, ncols=4, figsize=(25, 20))

axarr[0].imshow(image)
axarr[0].set_title("Original")

#plot boundaries
axarr[1].imshow(image_with_boundaries)
axarr[1].set_title("Superpixels Boundaries")

#plot labels
axarr[2].imshow(pixel_labels)
axarr[2].set_title('Superpixel Labels')

#compute segmentation
axarr[3].imshow(segmented_image)
axarr[3].set_title('Segmented image (normalized cut)')

5。评估指标
无监督分割的关键挑战是 NCut 不知道图像中类别的确切数量。 NCut 找到的分段数量可能超过实际的地面实况区域数量。因此,我们需要强大的指标来评估细分质量。

并集交集 (IoU) 是一种广泛使用的评估分割任务的指标,特别是在计算机视觉领域。它测量预测分割区域和地面真实区域之间的重叠。具体来说,IoU 计算预测分割和真实数据之间的重叠面积与其并集面积的比率。

结构相似性指数 (SSIM) 是一种用于通过比较两个图像的亮度、对比度和结构来评估图像感知质量的指标。

要应用这些指标,我们需要预测和地面实况图像具有相同的标签。为了计算标签,我们在地面上计算一个掩模,并在预测时为图像上找到的每种颜色分配一个 ID
然而,使用 NCut 进行分割可能会发现比地面实况更多的区域,这会降低准确性。

def compute_mask(image):
  color_dict = {}

  # Get the shape of the image
  height,width,_ = image.shape

  # Create an empty array for labels
  labels = np.zeros((height,width),dtype=int)
  id=0
  # Loop over each pixel
  for i in range(height):
      for j in range(width):
          # Get the color of the pixel
          color = tuple(image[i,j])
          # Check if it is in the dictionary
          if color in color_dict:
              # Assign the label from the dictionary
              labels[i,j] = color_dict[color]
          else:
              color_dict[color]=id
              labels[i,j] = id
              id =1

  return(labels)
def show_img(prediction, groundtruth):
  f, axarr = plt.subplots(nrows=1, ncols=2, figsize=(15, 10))

  axarr[0].imshow(groundtruth)
  axarr[0].set_title("groundtruth")
  axarr[1].imshow(prediction)
  axarr[1].set_title(f"prediction")
prediction_mask = compute_mask(segmented_image)
groundtruth_mask = compute_mask(ground_truth)

#usign the original image as baseline to convert from labels to color
prediction_img = color.label2rgb(prediction_mask, image, kind='avg', bg_label=0)
groundtruth_img = color.label2rgb(groundtruth_mask, image, kind='avg', bg_label=0)

show_img(prediction_img, groundtruth_img)

现在我们计算准确度分数

from sklearn.metrics import jaccard_score
from skimage.metrics import structural_similarity as ssim

ssim_score = ssim(prediction_img, groundtruth_img, channel_axis=2)
print(f"SSIM SCORE: {ssim_score}")

jac = jaccard_score(y_true=np.asarray(groundtruth_mask).flatten(),
                        y_pred=np.asarray(prediction_mask).flatten(),
                        average = None)

# compute mean IoU score across all classes
mean_iou = np.mean(jac)
print(f"Mean IoU: {mean_iou}")

结论

标准化剪切是一种强大的无监督图像分割方法,但它也面临着过度分割和调整参数等挑战。通过合并超像素并使用适当的指标评估性能,NCut 可以有效地分割复杂图像。 IoU 和 Rand 指数指标为分割质量提供了有意义的见解,尽管需要进一步细化才能有效处理多类场景。
最后,我的笔记本中提供了一个完整的示例。

版本聲明 本文轉載於:https://dev.to/sopralapanca/a-guide-to-unsupervised-image-segmentation-using-normalized-cuts-ncut-in-python-13pk?1如有侵犯,請聯絡study_golang@163 .com刪除
最新教學 更多>
  • 過去的爆炸:使用 Python 建立您自己的太空入侵者遊戲 - 逐步教程
    過去的爆炸:使用 Python 建立您自己的太空入侵者遊戲 - 逐步教程
    設定您的開發環境 在使用 Python 編寫 Space Invaders 之前,請確保您的開發環境設定正確。您需要在電腦上安裝 Python。建議使用 Python 3.8 或更高版本,以更好地相容於庫。此外,安裝 Pygame,它是一組專為編寫視訊遊戲而設計的 Python 模...
    程式設計 發佈於2024-11-09
  • SQL Server 中的日期時間和時間戳記有什麼不同?
    SQL Server 中的日期時間和時間戳記有什麼不同?
    了解SQL Server 中日期時間和時間戳記之間的差異雖然SQL Server 中的日期時間和時間戳記資料型別都處理日期和時間,但它們表現出根本的區別。 Datetime 是專為儲存日期和時間資訊而設計的資料類型。它支援多種格式和日期/時間計算。另一方面,Timestamp 並不是用來儲存日期和時...
    程式設計 發佈於2024-11-09
  • 如何在Python中尋找清單中的元素數量(列表長度)?
    如何在Python中尋找清單中的元素數量(列表長度)?
    在Python中查找列表中的元素數量(列表長度)在Python中,確定列表中的元素數量,也稱為列表長度,是一個常見的操作。為了實現這一點,我們可以利用 len() 函數。 例如,考慮列表 items = ["apple", "orange", "ba...
    程式設計 發佈於2024-11-09
  • 快速 HTML - ** 伺服器錯誤 NotFoundError:需要 k**
    快速 HTML - ** 伺服器錯誤 NotFoundError:需要 k**
    快速 HTML - 500 伺服器錯誤 NotFoundError:需要 2 pk 如果有人在使用快速 HTML 時遇到此問題,他們試圖從具有多個主鍵的表中獲取行並獲得需要 2 PK 或需要兩個主鍵的一些變化 問題 500 伺服器錯誤 NotFoundError: ...
    程式設計 發佈於2024-11-09
  • 如何有效率地檢索MySQL中最後插入的行?
    如何有效率地檢索MySQL中最後插入的行?
    檢索 MySQL 中最後插入的行:高效方法高效檢索 MySQL 中最後插入的行是資料庫程式設計中的常見任務。以下是實現此目的的兩種有效方法:1。時間戳列:理想的解決方案是建立一個 TIMESTAMP 列,在行插入時自動捕獲當前時間戳記。這提供了一種可靠且準確的方法來確定最近的記錄。 2。 ORDER...
    程式設計 發佈於2024-11-09
  • 在 Python 中處理 CSV 檔案時如何跳過標頭?
    在 Python 中處理 CSV 檔案時如何跳過標頭?
    使用Python 處理CSV 檔案時跳過標頭處理包含標頭的CSV(逗號分隔值)檔案時,通常需要在處理過程中排除這些標頭。本文解決了嘗試在 Python 中跳過標題時遇到的常見問題。 提供的程式碼片段遇到標題行受應用函數影響的問題。要修正此問題,讀者應注意 reader 變數會迭代 CSV 檔案中的行...
    程式設計 發佈於2024-11-09
  • 如何使用 PHP 中的 CURL 檢索 SSL 憑證資訊
    如何使用 PHP 中的 CURL 檢索 SSL 憑證資訊
    如何在PHP 中使用CURL 獲取SSL 證書信息在PHP 中使用SSL 證書時,通常需要訪問有關證書的信息,例如發行人、主題和到期日期。 Stream_context_create() 函數可用來建立指定要使用的 SSL 憑證的流上下文。然後可以使用stream_context_get_param...
    程式設計 發佈於2024-11-09
  • Java 已經到來 有什麼新功能?
    Java 已經到來 有什麼新功能?
    Java 23已正式发布!这是一个非 LTS(长期支持)版本。尽管它是一个短暂的版本,但 Java 23 包含了令人兴奋的改进、错误修复,并且还删除了您可能需要注意的功能和选项。 让我们深入了解新增内容以及它如何基于 JDK 21 和 JDK 22 等早期版本的功能构建。 范围值:基...
    程式設計 發佈於2024-11-09
  • 單一責任原則
    單一責任原則
    每個軟體元件應該只有一個且一個職責 軟體元件可以是類別、方法或模組 例如,瑞士軍刀是一種多用途工具,違反了軟體開發的單一責任原則,相反,刀是遵循單一責任的一個很好的例子(因為與瑞士軍刀不同,它只能用於切割可用於切割、打開罐頭、作為萬能鑰匙、剪刀等) 由於無論是現實世界或軟體開發,變化都是不變的,單...
    程式設計 發佈於2024-11-09
  • 如何在 Python 中列出定義的變數:「listout」的替代品?
    如何在 Python 中列出定義的變數:「listout」的替代品?
    在 Python 中存取定義的變數在 Python 中,追蹤所有定義的變數對於保持清晰度和調試至關重要。雖然 Python shell 缺乏用於顯示完整變數清單的內建功能(如 MATLAB 的「listout」命令),但有幾種替代方法可以實現此功能。 dir() dir() 函數提供目前作用域中定義...
    程式設計 發佈於2024-11-09
  • 如何在不中斷內容流的情況下將 Div 絕對放置在右側:解決 Float:right 與 Position:absolute 的困境
    如何在不中斷內容流的情況下將 Div 絕對放置在右側:解決 Float:right 與 Position:absolute 的困境
    右浮動和絕對定位困境已解決在您追求一個div 能夠無縫地將其自身與其父級右側對齊,同時避免干擾其他內容,您偶然發現了一個障礙:float:right 和position:absolute 的衝突行為。 Float 和 Absolute 的衝突本質Float :right 透過將其他元素推到左側來將元...
    程式設計 發佈於2024-11-09
  • Darshan Hiranandani 的解釋:如何使用 PHP 連接到 MySQL 資料庫?
    Darshan Hiranandani 的解釋:如何使用 PHP 連接到 MySQL 資料庫?
    大家好,我是 Darshan Hiranandani,我正在解釋如何使用 PHP 連接到 MySQL 資料庫? 要使用 PHP 連線到 MySQL 資料庫,您可以使用 mysqli 擴充或 PDO(PHP 資料物件)擴充。以下是這兩種方法的範例: 使用 mysqli 擴充
    程式設計 發佈於2024-11-09
  • 如何掌握 CSS 盒子模型以實現完美的網站佈局(+ Codepen 範例)
    如何掌握 CSS 盒子模型以實現完美的網站佈局(+ Codepen 範例)
    嘿,了不起的人!欢迎回到我的博客。 ?今天,我们将深入研究 CSS 盒子模型,揭秘如何确定每个元素的大小,以及如何使用这些知识来创建精确、现代和简洁的设计(本文末尾的实际示例)。 盒子模型简介 CSS 盒子模型是网页设计的基础,它规定了每个 HTML 元素如何在网页中占据空间。 盒子...
    程式設計 發佈於2024-11-09
  • 如何在空手道的讀取方法中參數化請求檔名?
    如何在空手道的讀取方法中參數化請求檔名?
    在Karate的讀取方法中參數化請求檔名嘗試使用Karate進行自動化API測試時,您可能會在嘗試透過時遇到問題將XML 檔案傳送到Read 方法,收到類似問題中提到的異常。當您在 Read 方法中使用變數表示檔案路徑(例如 read(varXmlFile))時,會發生這種情況。 要解決此問題,請確...
    程式設計 發佈於2024-11-09
  • 如何在 Pandas 中基於 If-Else-Else 條件建立列?
    如何在 Pandas 中基於 If-Else-Else 條件建立列?
    在 Pandas 中使用 If-Else-Else 條件建立列根據 if-elif-else條件建立新列,主要有兩種方法:非向量化方法此方法涉及定義一個對行進行操作的函數:def f(row): if row['A'] == row['B']: val = 0 eli...
    程式設計 發佈於2024-11-09

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3