KによるRGB画像の画像セグメンテーションはPythonでのクラスタリングを意味します


8

kを使用して土地被覆のRGB画像をセグメント化したいのですが、画像の異なる領域が異なる色でマークされ、可能であれば異なる領域を区切る境界が作成されるような方法でクラスタリングを行います。私は次のようなものが欲しい:

ここに画像の説明を入力してください

これから :

ここに画像の説明を入力してください

K平均クラスタリングによってこれを達成することは可能ですか?私はインターネット全体を検索しており、多くのチュートリアルではkでクラスタリングを行っていますが、画像をグレースケールに変換した後でのみです。RGB画像のみでやりたい。私がそれを始めるのに役立つソースはありますか?何か提案してください。


こんにちは、このリンクを試してください。少し前に試してみましたが、成功は限られていました。たぶん、あなたはそれを少し良く機能させることができます。幸運を。opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/...
Jcstay

こんにちは、@ Jcstayの提案に感謝しますが、すでにリンクを試しましたが、役に立ちませんでした。ありがとう、結構です。
2015

3
他のすべてのクラスタリング手法と同様に、K平均アルゴリズムは、kのニーズと最適な適合を指摘します。参照データのすべてにクラスが割り当てられるため、kが最適化されていないと、結果のクラスがサポートされず、結果が誤っている可能性があります。これらの場合、特定のクラスは、データ内のノイズまたは限界効果以外に何も表すことができません。通常、マージンシルエット値は、最適なkを選択するために使用されます。
Jeffrey Evans

回答:


9

私はこれに対する解決策をまとめてハッキングし、非常によく似たトピックについてブログ記事をしばらく書きました。ここで要約します。このスクリプトは、画像のセグメンテーションと分類のアプローチを使用して、4バンドのNAIP画像から川を抽出することを目的としています。

  1. 画像を派手な配列に変換する
  2. 迅速なシフトセグメンテーションを実行する(画像2)
  3. セグメントをラスター形式に変換する
  4. NDVIを計算する
  5. セグメントとNDVIを使用して平均ゾーン統計を実行し、NDVI値をセグメントに転送します(画像3)
  6. NDVI値に基づいてセグメントを分類する
  7. 結果を評価する(画像4)

この例では、K平均クラスタリングを使用するのではなく、4バンド(赤、緑、青、NIR)のカラー(x、y)空間でクイックシフトクラスタリングを使用して画像をセグメント化します。画像分割は、scikit-imageパッケージを使用して実行されました。scikit-imageのさまざまな画像セグメンテーションアルゴリズムの詳細については、こちらをご覧ください。便宜上、arcpy以前はGIS作業の多くを行っていましたが、GDALへの移植はかなり簡単です。


ここに画像の説明を入力してください


from __future__ import print_function

import arcpy
arcpy.CheckOutExtension("Spatial")

import matplotlib.pyplot as plt
import numpy as np
from skimage import io
from skimage.segmentation import quickshift

# The input 4-band NAIP image
river = r'C:\path\to\naip_image.tif'

# Convert image to numpy array
img = io.imread(river)

# Run the quick shift segmentation
segments = quickshift(img, kernel_size=3, convert2lab=False, max_dist=6, ratio=0.5)
print("Quickshift number of segments: %d" % len(np.unique(segments)))

# View the segments via Python
plt.imshow(segments)

# Get raster metrics for coordinate info
myRaster = arcpy.sa.Raster(river)

# Lower left coordinate of block (in map units)
mx = myRaster.extent.XMin
my = myRaster.extent.YMin
sr = myRaster.spatialReference

# Note the use of arcpy to convert numpy array to raster
seg = arcpy.NumPyArrayToRaster(segments, arcpy.Point(mx, my),
                               myRaster.meanCellWidth,
                               myRaster.meanCellHeight)

outRaster = r'C:\path\to\segments.tif'
seg_temp = seg.save(outRaster)
arcpy.DefineProjection_management(outRaster, sr)

# Calculate NDVI from bands 4 and 3
b4 = arcpy.sa.Raster(r'C:\path\to\naip_image.tif\Band_4')
b3 = arcpy.sa.Raster(r'C:\path\to\naip_image.tif\Band_3')
ndvi = arcpy.sa.Float(b4-b3) / arcpy.sa.Float(b4+b3)

# Extract NDVI values based on image object boundaries
zones = arcpy.sa.ZonalStatistics(outRaster, "VALUE", ndvi, "MEAN")
zones.save(r'C:\path\to\zones.tif')

# Classify the segments based on NDVI values
binary = arcpy.sa.Con(zones < 20, 1, 0)
binary.save(r'C:\path\to\classified_image_objects.tif')

2
これは素晴らしい解決策であり、k-meansの問題の一部を回避して最適なkを見つけることです。
Jeffrey Evans

これはすごくいい仕事です!!
Jcstay 2015

7

scikit-learnクラスタリングを確認できます。データをnumpy配列に読み込む必要があります(ラスタリオをお勧めします)。そこからデータを操作して、各バンドが分類用の変数になるようにします。たとえば、3つのバンドとしてのpythonに読み込ま持っていると仮定するとredgreenbluenumpyの配列:

import numpy as np
import sklearn.cluster

original_shape = red.shape # so we can reshape the labels later

samples = np.column_stack([red.flatten(), green.flatten(), blue.flatten()])

clf = sklearn.cluster.KMeans(n_clusters=5)
labels = clf.fit_predict(samples).reshape(original_shape)

import matplotlib.pyplot as plt

plt.imshow(labels)
plt.show()

KMeansクラスタリングは、データセット内の接続を考慮しないことに注意してください。


+1すばらしい答え。特にrasterio;)を使用してカラー画像を派手な配列に変換する例を示すとよいでしょう
アーロン

1
@アーロンありがとう!を使用したデータの読み取りを含む少し長い例を投稿しましたrasterio
om_henners 2015

@om_hennersあなたの解決策は素晴らしいですが、質問があります。プログラムがkを使用して返したセグメント化された画像は、クラスタリングが2Dであることを意味します。ここで、元の画像(R、G、Bバンドに分割する前の3D画像)とセグメント化された画像の間のダイス類似度係数を計算する必要がありますが、2つが同じ寸法である必要があります。この問題を解決するにはどうすればよいですか?
2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.