パイソン - OpenCVのモルフォロジー演算(膨張と収縮)

構造要素の定義

コア要素は、構成要素を定義するために直接ndarray numpyのを使用することができる独自getStructuringElement関数を使用することができるOpenCVの、Pythonで形態学的構造を定義することです。 
プロトタイプ:

Mat getStructuringElement(int shape, //核的形状  0:矩形  1:十字交叉形  2: 椭圆 
                          Size ksize,//核大小
                          Point anchor=Point(-1,-1) //核中心位置,默认位于形状中心处
                          );

要素はgetStructuringElement機能と構造を定義します。

element = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))

これは以下のように、5×5の要素の十字形構造を定義します。

書き込み絵は、ここで説明しました

次のようにnumpyのはまた、構造要素を定義するために使用することができます。

NpKernel = np.uint8(np.zeros((5,5)))
for i in range(5):
    NpKernel[2, i] = 1
    NpKernel[i, 2] = 1

両方のこの構造要素はまったく同じように定義されます:

[[0 0 1 0 0]
 [0 0 1 0 0]
 [1 1 1 1 1]
 [0 0 1 0 0]
 [0 0 1 0 0]]

ここに内蔵した定OpenCVの-Pythonのそれは、見ることができる楕円(MORPH_ELLIPSE)と十字型構造を定義する(MORPH_CROSS)要素は、矩形(MORPH_RECT)の定義およびカスタム構成要素場合、簡単で、両方とも同じ。

この記事では、画像の各章の「クックブックプログラミングOpencv2コンピュータビジョンアプリケーション」テスト基準を行います。 
書き込み絵は、ここで説明しました

収縮と膨張

以下は、構造要素を使用する方法をエッチングする前に画像の例です。

#coding=utf-8
import cv2
import numpy as np

img = cv2.imread('D:/binary.bmp',0)
#OpenCV定义的结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))

#腐蚀图像
eroded = cv2.erode(img,kernel)
#显示腐蚀后的图像
cv2.imshow("Eroded Image",eroded);

#膨胀图像
dilated = cv2.dilate(img,kernel)
#显示膨胀后的图像
cv2.imshow("Dilated Image",dilated);
#原图像
cv2.imshow("Origin", img)

#NumPy定义的结构元素
NpKernel = np.uint8(np.ones((3,3)))
Nperoded = cv2.erode(img,NpKernel)
#显示腐蚀后的图像
cv2.imshow("Eroded by NumPy kernel",Nperoded);

cv2.waitKey(0)
cv2.destroyAllWindows()

機能する(...)を各コールcv2.erode(...)とcv2.dilate、単に構成要素を設定し、浸食および拡張のプロセスは非常に単純であり、上記に示した、前記第一のパラメータは、処理される画像であります第二の構造要素。良好な画像処理を返します。

結果は以下の通りであります: 
書き込み絵は、ここで説明しました

操作を開くと操作を閉じます

学生の形態を理解する基本的な処理、開動作と開閉動作が収縮と膨張を知っているが、特定の順序で処理されています。しかし、二人は前と閉じて、元の画像を得ることができない、可逆的ではありません。次のようにコード例は以下のとおりです。

#coding=utf-8
import cv2
import numpy as np

img = cv2.imread('D:/binary.bmp',0)
#定义结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5))

#闭运算
closed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
#显示腐蚀后的图像
cv2.imshow("Close",closed);

#开运算
opened = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
#显示腐蚀后的图像
cv2.imshow("Open", opened);

cv2.waitKey(0)
cv2.destroyAllWindows()

開閉動作を誤っに小さな複数のオブジェクトに接続されており、ノイズ画像により形成されるスペックルを除去する操作を開いています。したがって、いくつかのケースでは、両方の連続動作を使用。そのような得られた画像中の主要被写体の連続閉動作及び開動作を使用してバイナリ画像として。あなたは、画像内のノイズ(すなわち、画像「ドット」)を排除したい場合は、同様に、最初の画像は、開動作及び閉動作で使用することができるが、それはまた、壊れたオブジェクトのいくつかを排除します。

原画像の開動作及び閉動作の結果、以下のように:

書き込み絵は、ここで説明しました

モルフォロジー演算のコーナーエッジを検出することにより、および

ここで、画像のエッジやコーナーを検出するために、形態学的演算子を使用する方法のより複雑な例により(本明細書に記載されるような形態学的処理、使用またはキャニーアルゴリズムハリス実用等の一例に過ぎません)。

エッジ検出 
、形態学的エッジ検出原理は非常に簡単で、拡張されたときに、対象物の画像は、「拡張」を周りたいと思う;腐食は、します画像内のオブジェクトと、「縮小します。」これら2枚の画像の比較、変化のみエッジで発生する領域。それでは、2枚の画像を減算し、エッジ画像はオブジェクトで得られます。ここでは、静止画の関連セクションを「クックブックプログラミングOpencv2コンピュータビジョンアプリケーション」を参照して使用されます。 
書き込み絵は、ここで説明しました

コードは以下の通りであります:

#coding=utf-8
import cv2
import numpy

image = cv2.imread("D:/building.jpg",0);
#构造一个3×3的结构元素 
element = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
dilate = cv2.dilate(image, element)
erode = cv2.erode(image, element)

#将两幅图像相减获得边,第一个参数是膨胀后的图像,第二个参数是腐蚀后的图像
result = cv2.absdiff(dilate,erode);

#上面得到的结果是灰度图,将其二值化以便更清楚的观察结果
retval, result = cv2.threshold(result, 40, 255, cv2.THRESH_BINARY); 
#反色,即对二值图每个像素取反
result = cv2.bitwise_not(result); 
#显示图像
cv2.imshow("result",result); 
cv2.waitKey(0)
cv2.destroyAllWindows()

次のように処理した結果は以下のとおりです。 
書き込み絵は、ここで説明しました

検出コーナー 
及びエッジ検出は少し複雑検出処理の異なるコーナーです。しかし、同じ原理は、十字状の第1のエッジのみで、この場合には、「拡張」と膨張要素の画素構造ことを除いて、コーナーポイントは変化しません。次いで、ストレートエッジ変化のどれも「縮小しない」であろう唯一のコーナーで、その結果、ダイヤモンドの構造要素と原画像をエッチングします。

第二のステップは、原画像の拡大、X字状の複数であることと膨張比角側です。腐食有する場合、この第二のブロック、コーナー反発、側よりエッチングされるつつ。2枚の画像が減算されると、角部のみを残します。下記の図(「Opencv2コンピュータビジョンアプリケーションがクックブックのプログラミング」のスキーム参照): 
書き込み絵は、ここで説明しました

コードは以下の通りであります:

#coding=utf-8
import cv2

image = cv2.imread("D:/building.jpg", 0)
origin = cv2.imread("D:/building.jpg")
#构造5×5的结构元素,分别为十字形、菱形、方形和X型
cross = cv2.getStructuringElement(cv2.MORPH_CROSS,(5, 5))
#菱形结构元素的定义稍麻烦一些
diamond = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5))
diamond[0, 0] = 0
diamond[0, 1] = 0
diamond[1, 0] = 0
diamond[4, 4] = 0
diamond[4, 3] = 0
diamond[3, 4] = 0
diamond[4, 0] = 0
diamond[4, 1] = 0
diamond[3, 0] = 0
diamond[0, 3] = 0
diamond[0, 4] = 0
diamond[1, 4] = 0
square = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5))
x = cv2.getStructuringElement(cv2.MORPH_CROSS,(5, 5))
#使用cross膨胀图像
result1 = cv2.dilate(image,cross)
#使用菱形腐蚀图像
result1 = cv2.erode(result1, diamond)

#使用X膨胀原图像 
result2 = cv2.dilate(image, x)
#使用方形腐蚀图像 
result2 = cv2.erode(result2,square)

#result = result1.copy()
#将两幅闭运算的图像相减获得角 
result = cv2.absdiff(result2, result1)
#使用阈值获得二值图
retval, result = cv2.threshold(result, 40, 255, cv2.THRESH_BINARY)

#在原图上用半径为5的圆圈将点标出。
for j in range(result.size):
    y = j / result.shape[0] 
    x = j % result.shape[0] 

    if result[x, y] == 255:
        cv2.circle(image, (y, x), 5, (255,0,0))

cv2.imshow("Result", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

パッケージに、システムと異なる座標系で使用numpyのOpenCVのパラメータの関数座標ndarrayにより、なお、ライン46に見ることができます。私は、OpenCVのメーリングリストに言及私の理解が間違っている見るために時間を取っています。 
私たちは、例えば、検証コードに2行のコードを挿入することができ、あなたは結果を知ることができます。

cv2.circle(image, (5, 10), 5, (255,0,0))
image[5, 10] = 0

画像のコーナーに上記のコードによって検出されてマークすることができ、次のような効果がある。 
書き込み絵は、ここで説明しました 
もちろん、これは形態学的処理の一例であり、検出結果は良好ではありません。

参考:https://blog.csdn.net/JohinieLi/article/details/8104127

公開された352元の記事 ウォンの賞賛115 ビュー130 000 +

おすすめ

転載: blog.csdn.net/Aidam_Bo/article/details/104469098