「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Python で正規化カット (NCut) を使用した教師なし画像セグメンテーションのガイド

Python で正規化カット (NCut) を使用した教師なし画像セグメンテーションのガイド

2024 年 11 月 8 日に公開
ブラウズ:369

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

導入

画像セグメンテーションは視覚データの理解と分析において重要な役割を果たしており、正規化カット (NCut) はグラフベースのセグメンテーションに広く使用されている方法です。この記事では、スーパーピクセルを使用したセグメンテーション品質の向上に重点を置き、Microsoft Research のデータセットを使用して、Python で教師なし画像セグメンテーションに NCut を適用する方法を検討します。
データセットの概要
このタスクに使用されるデータセットは、MSRC オブジェクト カテゴリ画像データベースのリンクからダウンロードできます。このデータセットには、元の画像と、その 9 つのオブジェクト クラスへのセマンティック セグメンテーションが含まれています (「_GT」で終わる画像ファイルで示されます)。これらの画像はテーマ別のサブセットにグループ化されており、ファイル名の最初の数字はクラス サブセットを表します。このデータセットは、セグメンテーション タスクを実験するのに最適です。

問題提起

NCut アルゴリズムを使用して、データセット内の画像に対して画像セグメンテーションを実行します。ピクセルレベルでのセグメンテーションは計算コストが高く、多くの場合ノイズが発生します。これを克服するために、SLIC (単純線形反復クラスタリング) を使用してスーパーピクセルを生成します。これにより、類似したピクセルがグループ化され、問題のサイズが小さくなります。セグメンテーションの精度を評価するために、さまざまな指標 (例: Intersection over Union、SSIM、Rand Index) を使用できます。

実装

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 によって検出されたセグメントの数は、実際のグラウンド トゥルース領域の数を超える場合があります。その結果、セグメンテーションの品質を評価するための堅牢な指標が必要になります。

Intersection over Union (IoU) は、特にコンピューター ビジョンでセグメンテーション タスクを評価するために広く使用されているメトリックです。これは、予測されたセグメント化された領域とグランド トゥルース領域の間の重複を測定します。具体的には、IoU は、予測されたセグメンテーションとグランド トゥルースの間の重複領域の、結合領域に対する比率を計算します。

構造類似性指数 (SSIM) は、輝度、コントラスト、構造の点で 2 つの画像を比較することによって、画像の知覚品質を評価するために使用される指標です。

これらのメトリクスを適用するには、予測とグラウンド トゥルース画像が同じラベルを持つ必要があります。ラベルを計算するために、地面と予測でマスクを計算し、画像上で見つかった各色に 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 Index メトリクスは、セグメンテーションの品質に関する有意義な洞察を提供しますが、マルチクラス シナリオを効果的に処理するにはさらに改良する必要があります。
最後に、完全な例が私のノートブックにあります。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/sopralapanca/a-guide-to-unsupervised-image-segmentation-using-normalized-cuts-ncut-in-python-13pk?1 侵害がある場合は、 Study_golang@163 .comdelete に連絡してください
最新のチュートリアル もっと>
  • CSSは、属性値に基づいてHTML要素を見つけることができますか?
    CSSは、属性値に基づいてHTML要素を見つけることができますか?
    をCSS の属性値でHTML要素をターゲットとするCSSのターゲティング、以下の例に示すように、特定の属性に基づいてターゲット要素をターゲットにすることが可能です: [型]入力[型]入力[タイプ] { フォントファミリー:コンソラ。 } input[type=text] { ...
    プログラミング 2025-06-29に投稿されました
  • CSSを使用してChromeとFirefoxのコンソール出力を着色できますか?
    CSSを使用してChromeとFirefoxのコンソール出力を着色できますか?
    javaScriptコンソールの色の表示 は、クロムのコンソールを使用してエラー用の赤、警告用のオレンジ、コンソール用グリーンなどの色のテキストを表示することは可能です。メッセージ? 回答 はい、CSSを使用して、ChromeとFirefox(バージョン31以降)のコンソールに表示さ...
    プログラミング 2025-06-29に投稿されました
  • FASTAPIカスタム404ページ作成ガイド
    FASTAPIカスタム404ページ作成ガイド
    custom 404 Fastapi を備えたPage not foundページを作成するためのカスタム404が作成されていないページを作成すると、Fastapiはいくつかのアプローチを提供します。適切な方法は、特定の要件に依存します。 call_next(リクエスト) respons...
    プログラミング 2025-06-29に投稿されました
  • CSSは言語分析を強く入力しました
    CSSは言語分析を強く入力しました
    プログラミング言語を分類する方法の1つは、それがどれほど強くまたは弱く入力されているかによってです。ここで、「タイプされた」とは、変数がコンパイル時に既知の場合を意味します。これの例は、整数(1)が整数( "1")を含む文字列に追加されるシナリオです: result = 1 ...
    プログラミング 2025-06-29に投稿されました
  • PHP Future:適応と革新
    PHP Future:適応と革新
    PHPの将来は、新しいテクノロジーの傾向に適応し、革新的な機能を導入することで達成されます。1)クラウドコンピューティング、コンテナ化、マイクロサービスアーキテクチャに適応し、DockerとKubernetesをサポートします。 2)パフォーマンスとデータ処理の効率を改善するために、JITコンパイ...
    プログラミング 2025-06-29に投稿されました
  • オブジェクトフィット:IEとEdgeでカバーが失敗します、修正方法は?
    オブジェクトフィット:IEとEdgeでカバーが失敗します、修正方法は?
    object-fit:カバーがIEとEDGEで失敗します。 CSSでは、一貫した画像の高さを維持するために、ブラウザ全体でシームレスに動作します。ただし、IEとEdgeでは、独特の問題が発生します。ブラウザをスケーリングすると、画像は高さをズームするのではなく幅でサイズを変更し、外観を歪め...
    プログラミング 2025-06-29に投稿されました
  • 年と四半期の列をパンダの1つの定期的な列にマージする方法は?
    年と四半期の列をパンダの1つの定期的な列にマージする方法は?
    新しい期間の列の列の連結 問題ステートメント: 2000 Q2 2001 Q3 目的は、「年」と「四分の一」の列を組み合わせて「期間」と呼ばれる新しい列を作成して、次の結果を取得することです。 2001q3 ソリューション: はpythonで文字列列を連結するために、...
    プログラミング 2025-06-29に投稿されました
  • オブジェクトがPythonに特定の属性を持っているかどうかを確認する方法は?
    オブジェクトがPythonに特定の属性を持っているかどうかを確認する方法は?
    メソッドオブジェクト属性の存在を決定するメソッド この問い合わせは、オブジェクト内の特定の属性の存在を検証する方法を求めています。未定義のプロパティにアクセスしようとする試みがエラーを提起する次の例を考えてみましょう: >>> a = SomeClass() >&g...
    プログラミング 2025-06-29に投稿されました
  • ユーザーローカルタイムフォーマットとタイムゾーンオフセットディスプレイガイド
    ユーザーローカルタイムフォーマットとタイムゾーンオフセットディスプレイガイド
    をタイムオフセットでユーザーのロケール形式で表示する をエンドユーザーに提示する場合、ローカルタイムゾーンとフォーマットに表示することが重要です。これにより、さまざまな地理的位置にわたって明確でシームレスなユーザーエクスペリエンスが保証されます。 JavaScriptを使用してこれを達成す...
    プログラミング 2025-06-29に投稿されました
  • 1つのトランザクションでデータを複数のMySQLテーブルに効率的に挿入する方法は?
    1つのトランザクションでデータを複数のMySQLテーブルに効率的に挿入する方法は?
    mysqlは複数のテーブルに挿入されます 単一のMySQLクエリを持つ複数のテーブルにデータを挿入しようとすると、予期しない結果が得られる場合があります。複数のクエリが問題を解決するように思われるかもしれませんが、プロファイルテーブルのユーザーテーブルからマニュアルユーザーIDに自動イン...
    プログラミング 2025-06-29に投稿されました
  • PHPで空の配列を効率的に検出する方法は?
    PHPで空の配列を効率的に検出する方法は?
    チェックアレイ空虚のphp の空の配列は、さまざまなアプローチを通じてPHPで決定できます。アレイ要素の存在を確認する必要がある場合、PHPのルーズタイピングにより、配列自体の直接評価が可能になります。 //リストは空です。 } if (!$playerlist) { ...
    プログラミング 2025-06-29に投稿されました
  • Microsoft Visual C ++が2フェーズテンプレートのインスタンス化を正しく実装できないのはなぜですか?
    Microsoft Visual C ++が2フェーズテンプレートのインスタンス化を正しく実装できないのはなぜですか?
    Microsoft Visual Cの「壊れた」2フェーズテンプレートのインスタンス化の謎 問題声明: ユーザーは、Microsoft Visual C(MSVC)の懸念を表現する一般的な懸念を表明します。メカニズムの特定の側面は、予想どおりに動作できませんか?ただし、このチェックがテンプ...
    プログラミング 2025-06-29に投稿されました
  • 偽のウェイクアップは本当にJavaで起こりますか?
    偽のウェイクアップは本当にJavaで起こりますか?
    Javaの偽りの目覚め:現実か神話ですか?そのような動作の可能性は存在しますが、問題は残ります:それらは実際に実際に発生しますか?プロセスが信号を受信すると、EINTRで突然戻ってきて、ブロッキングシステムの呼び出しを早期に終了させる可能性があります。その結果、POSIX信号はスプリアスウェ...
    プログラミング 2025-06-29に投稿されました
  • 動的にサイズの親要素内の要素のスクロール範囲を制限する方法は?
    動的にサイズの親要素内の要素のスクロール範囲を制限する方法は?
    垂直スクロール要素のcss高さ制限の実装 インタラクティブインターフェイスで、要素のスクロール挙動を制御することは、ユーザーエクスペリエンスとアクセシビリティを確保するために不可欠です。そのようなシナリオの1つは、動的にサイズの親要素内の要素のスクロール範囲を制限することです。ただし、マッ...
    プログラミング 2025-06-29に投稿されました
  • Python環境変数のアクセスおよび管理方法
    Python環境変数のアクセスおよび管理方法
    Python の環境変数へのアクセスPythonの環境変数にアクセスするには、 os.environ オブジェクトを利用します。デフォルトでは、マッピング内の変数にアクセスすると、インタープリターにPython辞書の値を検索するように促します。 print(os.environ [&#...
    プログラミング 2025-06-29に投稿されました

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3