ホームページ >バックエンド開発 >Python チュートリアル >Pythonデジタル画像処理の高度な形態学的処理
この記事では主にPythonデジタル画像処理の高度な形態学的処理を紹介し、参考として提供します。一緒に見てみましょう
形態学的処理には、最も基本的な拡張、腐食、開閉操作、ブラック/ホワイトハット処理に加えて、凸包、接続領域のマーキング、削除などのより高度なアプリケーションもあります。小さなブロック領域など
1. 凸包
凸包とは、画像内のすべての白いピクセルを含む凸多角形を指します。
関数は次のとおりです:
skimage.morphology.convex_hull_image(image)
入力はバイナリ イメージで、出力は論理バイナリ イメージです。凸包内の点は True、それ以外の場合は False です
例:
import matplotlib.pyplot as plt from skimage import data,color,morphology #生成二值测试图像 img=color.rgb2gray(data.horse()) img=(img<0.5)*1 chull = morphology.convex_hull_image(img) #绘制轮廓 fig, axes = plt.subplots(1,2,figsize=(8,8)) ax0, ax1= axes.ravel() ax0.imshow(img,plt.cm.gray) ax0.set_title('original image') ax1.imshow(chull,plt.cm.gray) ax1.set_title('convex_hull image')
convex_hull_image() は画像内のすべてのターゲットを全体として扱うため、最小の凸多角形が 1 つだけ計算されます。画像内に複数のターゲット オブジェクトがあり、各オブジェクトが最小の凸多角形を計算する必要がある場合は、convex_hull_object() 関数を使用する必要があります。
関数形式: skimage.morphology.convex_hull_object(image,neighbors=8)
入力パラメータ画像はバイナリ画像であり、近傍は4-connectedを使用するか、またはを使用するかを示します8 接続 デフォルトは 8 接続です。
例:
import matplotlib.pyplot as plt from skimage import data,color,morphology,feature #生成二值测试图像 img=color.rgb2gray(data.coins()) #检测canny边缘,得到二值图片 edgs=feature.canny(img, sigma=3, low_threshold=10, high_threshold=50) chull = morphology.convex_hull_object(edgs) #绘制轮廓 fig, axes = plt.subplots(1,2,figsize=(8,8)) ax0, ax1= axes.ravel() ax0.imshow(edgs,plt.cm.gray) ax0.set_title('many objects') ax1.imshow(chull,plt.cm.gray) ax1.set_title('convex_hull image') plt.show()
2. 連結領域マーク
2値画像において、2つのピクセルが隣接しており、同じ値(両方とも0または1)を持っている場合、これら 2 つのピクセルは接続された領域にあります。同じ接続領域内のすべてのピクセルは同じ値でマークされます。このプロセスは接続領域マーキングと呼ばれます。 2 つのピクセルが隣接しているかどうかを判断する場合、通常は 4 連結または 8 連結の判断が使用されます。画像の最小単位はピクセルであり、各ピクセルは隣接する 8 つのピクセルで囲まれます。一般的な隣接関係には、4 隣接と 8 隣接の 2 つがあります。 4は、下図左のように上下左右の計4点に隣接しています。 8 隣接する点は、下図右のように対角位置の点も含めて合計 8 点あります。
skimage パッケージでは、measure サブモジュールの下で label() 関数を使用して、接続領域のラベル付けを実装します。
関数の形式:
skimage.measure.label(image,connectivity=None)
パラメーター内のイメージは処理する必要があるバイナリ イメージを表し、接続性は接続モードを表します。1 は 4 つの隣接関係を表し、2 は 8 つの隣接関係を表します。
0から始まるラベル(ラベル)の配列を出力します。
import numpy as np import scipy.ndimage as ndi from skimage import measure,color import matplotlib.pyplot as plt #编写一个函数来生成原始二值图像 def microstructure(l=256): n = 5 x, y = np.ogrid[0:l, 0:l] #生成网络 mask = np.zeros((l, l)) generator = np.random.RandomState(1) #随机数种子 points = l * generator.rand(2, n**2) mask[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1 mask = ndi.gaussian_filter(mask, sigma=l/(4.*n)) #高斯滤波 return mask > mask.mean() data = microstructure(l=128)*1 #生成测试图片 labels=measure.label(data,connectivity=2) #8连通区域标记 dst=color.label2rgb(labels) #根据不同的标记显示不同的颜色 print('regions number:',labels.max()+1) #显示连通区域块数(从0开始标记) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4)) ax1.imshow(data, plt.cm.gray, interpolation='nearest') ax1.axis('off') ax2.imshow(dst,interpolation='nearest') ax2.axis('off') fig.tight_layout() plt.show()
コードでは、所々に 1 を掛けることで bool 配列を int 配列に素早く変換できます。
結果は図に示すとおりです: 0-9 のマークが付いた 10 個の接続領域があります
面積、外接長方形、凸包領域などの計算など、各接続領域を個別に操作したい場合.、measureサブモジュールのregionprops()関数を呼び出す必要があります。この関数の形式は次のとおりです:
skimage.measure.regionprops(label_image)
接続されているすべてのブロックの属性リストを返します。一般的に使用される属性リストは次のとおりです。
area
bbox | tuple | |
centroid | array | |
convex_area | int | |
convex_image | ndarray | |
座標 | ndarray | |
離心率 | float | |
equivalent_diameter | float | |
euler _number | int | |
範囲 | float | |
filled_area | int | |
perimeter | float | |
label | int | |
3、删除小块区域 有些时候,我们只需要一些大块区域,那些零散的、小块的区域,我们就需要删除掉,则可以使用morphology子模块的remove_small_objects()函数。 函数格式:skimage.morphology.remove_small_objects(ar,min_size=64,connectivity=1,in_place=False) 参数: ar: 待操作的bool型数组。 min_size: 最小连通区域尺寸,小于该尺寸的都将被删除。默认为64. connectivity: 邻接模式,1表示4邻接,2表示8邻接 in_place: bool型值,如果为True,表示直接在输入图像中删除小块区域,否则进行复制后再删除。默认为False. 返回删除了小块区域的二值图像。 import numpy as np import scipy.ndimage as ndi from skimage import morphology import matplotlib.pyplot as plt #编写一个函数来生成原始二值图像 def microstructure(l=256): n = 5 x, y = np.ogrid[0:l, 0:l] #生成网络 mask = np.zeros((l, l)) generator = np.random.RandomState(1) #随机数种子 points = l * generator.rand(2, n**2) mask[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1 mask = ndi.gaussian_filter(mask, sigma=l/(4.*n)) #高斯滤波 return mask > mask.mean() data = microstructure(l=128) #生成测试图片 dst=morphology.remove_small_objects(data,min_size=300,connectivity=1) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4)) ax1.imshow(data, plt.cm.gray, interpolation='nearest') ax2.imshow(dst,plt.cm.gray,interpolation='nearest') fig.tight_layout() plt.show() 在此例中,我们将面积小于300的小块区域删除(由1变为0),结果如下图: 4、综合示例:阈值分割+闭运算+连通区域标记+删除小区块+分色显示 import numpy as np import matplotlib.pyplot as plt import matplotlib.patches as mpatches from skimage import data,filter,segmentation,measure,morphology,color #加载并裁剪硬币图片 image = data.coins()[50:-50, 50:-50] thresh =filter.threshold_otsu(image) #阈值分割 bw =morphology.closing(image > thresh, morphology.square(3)) #闭运算 cleared = bw.copy() #复制 segmentation.clear_border(cleared) #清除与边界相连的目标物 label_image =measure.label(cleared) #连通区域标记 borders = np.logical_xor(bw, cleared) #异或 label_image[borders] = -1 image_label_overlay =color.label2rgb(label_image, image=image) #不同标记用不同颜色显示 fig,(ax0,ax1)= plt.subplots(1,2, figsize=(8, 6)) ax0.imshow(cleared,plt.cm.gray) ax1.imshow(image_label_overlay) for region in measure.regionprops(label_image): #循环得到每一个连通区域属性集 #忽略小区域 if region.area < 100: continue #绘制外包矩形 minr, minc, maxr, maxc = region.bbox rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr, fill=False, edgecolor='red', linewidth=2) ax1.add_patch(rect) fig.tight_layout() plt.show()
|
以上がPythonデジタル画像処理の高度な形態学的処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。