ホームページ  >  記事  >  バックエンド開発  >  Pythonデジタル画像処理の高度な形態学的処理

Pythonデジタル画像処理の高度な形態学的処理

不言
不言オリジナル
2018-04-27 10:10:394167ブラウズ

この記事では主に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(&#39;original image&#39;)

ax1.imshow(chull,plt.cm.gray)
ax1.set_title(&#39;convex_hull image&#39;)

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(&#39;many objects&#39;)
ax1.imshow(chull,plt.cm.gray)
ax1.set_title(&#39;convex_hull image&#39;)
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(&#39;regions number:&#39;,labels.max()+1) #显示连通区域块数(从0开始标记)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
ax1.imshow(data, plt.cm.gray, interpolation=&#39;nearest&#39;)
ax1.axis(&#39;off&#39;)
ax2.imshow(dst,interpolation=&#39;nearest&#39;)
ax2.axis(&#39;off&#39;)

fig.tight_layout()
plt.show()

コードでは、所々に 1 を掛けることで bool 配列を int 配列に素早く変換できます。

結果は図に示すとおりです: 0-9 のマークが付いた 10 個の接続領域があります

面積、外接長方形、凸包領域などの計算など、各接続領域を個別に操作したい場合.、measureサブモジュールのregionprops()関数を呼び出す必要があります。この関数の形式は次のとおりです:

skimage.measure.regionprops(label_image)

接続されているすべてのブロックの属性リストを返します。一般的に使用される属性リストは次のとおりです。

area

intエリア内のピクセルの総数boundingバウンディングボックス(min_row, min_col, max_row, max_col)重心座標凸包内のピクセルの総数境界ボックスと同じサイズの凸包領域内のピクセルの座標eccentricity 面積と同じ面積の円の直径面積オイラー数値area sum 境界ボックスの面積の比率 領域と境界ボックスの間で塗りつぶされたピクセルの総数エリア境界エリアマーカー
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=&#39;nearest&#39;)
ax2.imshow(dst,plt.cm.gray,interpolation=&#39;nearest&#39;)

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=&#39;red&#39;, linewidth=2)
  ax1.add_patch(rect)
fig.tight_layout()
plt.show()


以上がPythonデジタル画像処理の高度な形態学的処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。