"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > पायथन में नॉर्मलाइज्ड कट्स (NCut) का उपयोग करके अनसुपरवाइज्ड इमेज सेगमेंटेशन के लिए एक गाइड

पायथन में नॉर्मलाइज्ड कट्स (NCut) का उपयोग करके अनसुपरवाइज्ड इमेज सेगमेंटेशन के लिए एक गाइड

2024-11-08 को प्रकाशित
ब्राउज़ करें:800

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

परिचय

दृश्य डेटा को समझने और उसका विश्लेषण करने में छवि विभाजन एक महत्वपूर्ण भूमिका निभाता है, और ग्राफ़-आधारित विभाजन के लिए सामान्यीकृत कट्स (एनसीयूटी) एक व्यापक रूप से उपयोग की जाने वाली विधि है। इस लेख में, हम सुपरपिक्सल का उपयोग करके विभाजन की गुणवत्ता में सुधार पर ध्यान देने के साथ, माइक्रोसॉफ्ट रिसर्च के डेटासेट का उपयोग करके पायथन में अनपर्यवेक्षित छवि विभाजन के लिए NCut को कैसे लागू किया जाए, इसका पता लगाएंगे।
डेटासेट अवलोकन
इस कार्य के लिए उपयोग किए गए डेटासेट को निम्नलिखित लिंक से डाउनलोड किया जा सकता है: एमएसआरसी ऑब्जेक्ट श्रेणी छवि डेटाबेस। इस डेटासेट में मूल छवियों के साथ-साथ नौ ऑब्जेक्ट वर्गों में उनका अर्थ विभाजन शामिल है ("_GT" के साथ समाप्त होने वाली छवि फ़ाइलों द्वारा दर्शाया गया है)। इन छवियों को विषयगत उपसमुच्चय में समूहीकृत किया गया है, जहां फ़ाइल नाम में पहला नंबर एक वर्ग उपसमुच्चय को संदर्भित करता है। यह डेटासेट विभाजन कार्यों के साथ प्रयोग करने के लिए बिल्कुल उपयुक्त है।

समस्या का विवरण

हम NCut एल्गोरिदम का उपयोग करके डेटासेट में एक छवि पर छवि विभाजन करते हैं। पिक्सेल स्तर पर विभाजन कम्प्यूटेशनल रूप से महंगा और अक्सर शोर वाला होता है। इसे दूर करने के लिए, हम सुपरपिक्सेल उत्पन्न करने के लिए एसएलआईसी (सिंपल लीनियर इटरेटिव क्लस्टरिंग) का उपयोग करते हैं, जो समान पिक्सल को समूहित करता है और समस्या के आकार को कम करता है। विभाजन की सटीकता का मूल्यांकन करने के लिए विभिन्न मेट्रिक्स (उदाहरण के लिए, यूनियन, एसएसआईएम, रैंड इंडेक्स पर इंटरसेक्शन) का उपयोग किया जा सकता है।

कार्यान्वयन

1. आवश्यक पुस्तकालय स्थापित करें
हम छवि प्रसंस्करण के लिए स्किमेज, संख्यात्मक गणना के लिए 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. एसएलआईसी का उपयोग करके सुपरपिक्सेल उत्पन्न करें और एक क्षेत्र निकटवर्ती ग्राफ़ बनाएं

हम NCut लगाने से पहले सुपरपिक्सेल की गणना करने के लिए SLIC एल्गोरिदम का उपयोग करते हैं। उत्पन्न सुपरपिक्सेल का उपयोग करके, हम औसत रंग समानता के आधार पर एक क्षेत्र निकटवर्ती ग्राफ़ (आरएजी) का निर्माण करते हैं:

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 सुपरपिक्सेल (या सेगमेंट) की संख्या को नियंत्रित करता है जिसे एसएलआईसी एल्गोरिदम छवि में उत्पन्न करने का प्रयास करता है। मूलतः, यह विभाजन का समाधान निर्धारित करता है।
उच्च मान: एक उच्च n_segments मान अधिक सुपरपिक्सल बनाता है, जिसका अर्थ है कि प्रत्येक सुपरपिक्सल छोटा होगा और विभाजन अधिक बारीक होगा। यह तब उपयोगी हो सकता है जब छवि में जटिल बनावट या छोटी वस्तुएं हों।
कम मान: कम n_segments मान कम, बड़े सुपरपिक्सेल उत्पन्न करता है। यह तब उपयोगी होता है जब आप छवि का मोटा विभाजन चाहते हैं, बड़े क्षेत्रों को एकल सुपरपिक्सेल में समूहीकृत करते हैं।

4. सामान्यीकृत कट्स (एनसीयूटी) लागू करें और परिणाम देखें

# 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 अनुमानित विभाजन और जमीनी सच्चाई के बीच ओवरलैप के क्षेत्र और उनके मिलन के क्षेत्र के अनुपात की गणना करता है।

स्ट्रक्चरल समानता सूचकांक (एसएसआईएम) एक मीट्रिक है जिसका उपयोग चमक, कंट्रास्ट और संरचना के संदर्भ में दो छवियों की तुलना करके एक छवि की कथित गुणवत्ता का आकलन करने के लिए किया जाता है।

इन मेट्रिक्स को लागू करने के लिए हमें यह आवश्यक है कि भविष्यवाणी और जमीनी सच्चाई की छवि के लेबल समान हों। लेबल की गणना करने के लिए हम जमीन पर एक मास्क की गणना करते हैं और भविष्यवाणी पर छवि पर पाए गए प्रत्येक रंग के लिए एक आईडी निर्दिष्ट करते हैं
हालाँकि, 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 और रैंड इंडेक्स मेट्रिक्स विभाजन की गुणवत्ता में सार्थक अंतर्दृष्टि प्रदान करते हैं, हालांकि बहु-वर्ग परिदृश्यों को प्रभावी ढंग से संभालने के लिए और अधिक शोधन की आवश्यकता है।
अंत में, एक संपूर्ण उदाहरण यहां मेरी नोटबुक में उपलब्ध है।

विज्ञप्ति वक्तव्य यह आलेख यहां पुन: प्रस्तुत किया गया है: https://dev.to/sopralapanca/a-guide-to-unsupervised-image-segmentation-using-normalized-cuts-ncut-in-python-13pk?1 यदि कोई उल्लंघन है, तो कृपया स्टडी_गोलंग@163 .comडिलीट से संपर्क करें
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3