Get biggest coherent area – StackOverflow
処理としては,(必要ならば数理形態学的な前処理をした後で)ラベリングして,
カウントして,最大領域のインデックスを得る.その為のモジュールとしては,
Numpy/Scipy/scikit-imageを用いるか,OpenCVを用いるか.
Numpy/Scipy/Scikit-Imageを用いる場合
回答の通り.ただ,「skimage.measure.label」よりも,
「scipy.ndimage.label」の方が効率が良いので(1.5倍位速い),
それだけ置き換える.
import numpy as np from scipy import ndimage from skimage import io import matplotlib.pyplot as plt img = io.imread('https://i.stack.imgur.com/6ptZC.png', as_grey=True) l = ndimage.label(img)[0] out = (l==np.bincount(l.ravel())[1:].argmax()+1).astype(np.uint8) plt.imshow(out) plt.axis('off')
OpenCVを用いる場合
import cv2 nLabels, labelImages, data, center = cv2.connectedComponentsWithStats(img) out = (labelImages==data[1:, 4].argmax()+1).astype(np.uint8) plt.imshow(out) plt.axis('off')
Runtime Test
%%timeit l = label(img) # from skimage.measure import label out = (l==np.bincount(l.ravel())[1:].argmax()+1).astype(np.uint8)
100 loops, best of 3: 3.36 ms per loop
%%timeit l = ndimage.label(img)[0] out = (l==np.bincount(l.ravel())[1:].argmax()+1).astype(np.uint8)
100 loops, best of 3: 2.23 ms per loop
%%timeit nLabels, labelImages, data, center = cv2.connectedComponentsWithStats(img) out = (labelImages==data[1:, 4].argmax()+1).astype(np.uint8)
1000 loops, best of 3: 1.75 ms per loop
色々比較した訳ではないけど,Scipy, Scikit-Image, OpenCV等々,
手軽に使えるモジュールの中でOpenCVが最も時間効率が良いイメージ.
幾つかのベンチマークをみるに,その感覚は尤もらしいと思う.
参考:
[1] Pythonの画像読み込み: PIL, OpenCV, scikit-image – Qiita
[2] Fast benchmark: Pillow vs OpenCV – kaggle
[3] Python image processing libraries performance: OpenCV vs Scipy vs Scikit-Image – mmas.github.io
ただ,ちょっとした作業の場合,OpenCVよりも「scipy.ndimage」や
「Scikit-Image」の方が簡便なので,まあ使い分ければ良い.
ピンバック: 2D Numpy配列で最初の要素が重複している行の平均 – 2Dなnumpy.ndarrayの最初の要素(1列目)で各行をグルーピングして集計(平均を算出) | 粉末@それは風のように (日記)
ピンバック: 1-dimのビット配列から、特定の2-dimの1のシーケンスの配列を取得する[Python] – 0/1の1次元配列から1をグルーピングして各グループごとに行方向へ展開し2次元配列を作成 | 粉末@それは風
ピンバック: データフレーム各行の連続したゼロをカウント | 粉末@それは風のように (日記)
ピンバック: pandasデータフレーム列内のNaNに基づいて累積和をリセット – 任意の条件に基づいた範囲で累積和を求める | 粉末@それは風のように (日記)
ピンバック: データフレーム列内の連続した値の和(任意長の範囲で合計) | 粉末@それは風のように (日記)
ピンバック: 2次元配列で同じ値を持つ隣接要素を見つける – 配列内のフィーチャにラベル付け(Flood fill) | 粉末@それは風のように (日記)
ピンバック: 粉末@それは風のように (日記)