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

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

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

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刪除
最新教學 更多>
  • \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    答案: 在大多數現代編譯器中,while(1)和(1)和(;;)之間沒有性能差異。編譯器: perl: 1 輸入 - > 2 2 NextState(Main 2 -E:1)V-> 3 9 Leaveloop VK/2-> A 3 toterloop(next-> 8 last-> 9 ...
    程式設計 發佈於2025-03-17
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP將...
    程式設計 發佈於2025-03-17
  • 對象擬合:IE和Edge中的封面失敗,如何修復?
    對象擬合:IE和Edge中的封面失敗,如何修復?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    程式設計 發佈於2025-03-17
  • 如何從PHP中的數組中提取隨機元素?
    如何從PHP中的數組中提取隨機元素?
    從陣列中的隨機選擇,可以輕鬆從數組中獲取隨機項目。考慮以下數組:; 從此數組中檢索一個隨機項目,利用array_rand( array_rand()函數從數組返回一個隨機鍵。通過將$項目數組索引使用此鍵,我們可以從數組中訪問一個隨機元素。這種方法為選擇隨機項目提供了一種直接且可靠的方法。
    程式設計 發佈於2025-03-17
  • HTML格式標籤
    HTML格式標籤
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    程式設計 發佈於2025-03-17
  • 為什麼我會收到MySQL錯誤#1089:錯誤的前綴密鑰?
    為什麼我會收到MySQL錯誤#1089:錯誤的前綴密鑰?
    mySQL錯誤#1089:錯誤的前綴鍵錯誤descript [#1089-不正確的前綴鍵在嘗試在表中創建一個prefix鍵時會出現。前綴鍵旨在索引字符串列的特定前綴長度長度,可以更快地搜索這些前綴。 了解prefix keys `這將在整個Movie_ID列上創建標準主鍵。主密鑰對於唯一識...
    程式設計 發佈於2025-03-17
  • Java是否允許多種返回類型:仔細研究通用方法?
    Java是否允許多種返回類型:仔細研究通用方法?
    在Java中的多個返回類型:一種誤解類型:在Java編程中揭示,在Java編程中,Peculiar方法簽名可能會出現,可能會出現,使開發人員陷入困境,使開發人員陷入困境。 getResult(string s); ,其中foo是自定義類。該方法聲明似乎擁有兩種返回類型:列表和E。但這確實是如此嗎...
    程式設計 發佈於2025-03-17
  • 如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    postgresql:為每個唯一標識符提取最後一行,在Postgresql中,您可能需要遇到與在數據庫中的每個不同標識相關的信息中提取信息的情況。考慮以下數據:[ 1 2014-02-01 kjkj 在數據集中的每個唯一ID中檢索最後一行的信息,您可以在操作員上使用Postgres的有效效率: ...
    程式設計 發佈於2025-03-17
  • 如何使用不同數量列的聯合數據庫表?
    如何使用不同數量列的聯合數據庫表?
    合併列數不同的表 當嘗試合併列數不同的數據庫表時,可能會遇到挑戰。一種直接的方法是在列數較少的表中,為缺失的列追加空值。 例如,考慮兩個表,表 A 和表 B,其中表 A 的列數多於表 B。為了合併這些表,同時處理表 B 中缺失的列,請按照以下步驟操作: 確定表 B 中缺失的列,並將它們添加到表的...
    程式設計 發佈於2025-03-17
  • 為什麼不使用CSS`content'屬性顯示圖像?
    為什麼不使用CSS`content'屬性顯示圖像?
    在Firefox extemers屬性為某些圖像很大,&& && && &&華倍華倍[華氏華倍華氏度]很少見,卻是某些瀏覽屬性很少,尤其是特定於Firefox的某些瀏覽器未能在使用內容屬性引用時未能顯示圖像的情況。這可以在提供的CSS類中看到:。 googlepic { 內容:url(&...
    程式設計 發佈於2025-03-17
  • 如何從Python中的字符串中刪除表情符號:固定常見錯誤的初學者指南?
    如何從Python中的字符串中刪除表情符號:固定常見錯誤的初學者指南?
    從python import codecs import codecs import codecs 導入 text = codecs.decode('這狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#帶有...
    程式設計 發佈於2025-03-17
  • 在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    程式設計 發佈於2025-03-17
  • 如何使用PHP從XML文件中有效地檢索屬性值?
    如何使用PHP從XML文件中有效地檢索屬性值?
    從php $xml = simplexml_load_file($file); foreach ($xml->Var[0]->attributes() as $attributeName => $attributeValue) { echo $attributeName,...
    程式設計 發佈於2025-03-17
  • Python讀取CSV文件UnicodeDecodeError終極解決方法
    Python讀取CSV文件UnicodeDecodeError終極解決方法
    在試圖使用已內置的CSV模塊讀取Python中時,CSV文件中的Unicode Decode Decode Decode Decode decode Error讀取,您可能會遇到錯誤的錯誤:無法解碼字節 在位置2-3中:截斷\ uxxxxxxxx逃脫當CSV文件包含特殊字符或Unicode的路徑逃...
    程式設計 發佈於2025-03-17
  • 如何干淨地刪除匿名JavaScript事件處理程序?
    如何干淨地刪除匿名JavaScript事件處理程序?
    刪除匿名事件偵聽器將匿名事件偵聽器添加到元素中會提供靈活性和簡單性,但是當要刪除它們時,可以構成挑戰,而無需替換元素本身就可以替換一個問題。 element? element.addeventlistener(event,function(){/在這里工作/},false); 要解決此問題,請考...
    程式設計 發佈於2025-03-17

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

Copyright© 2022 湘ICP备2022001581号-3