[再版] OpenCV-Pythonシリーズの開閉操作(21)

画像の腐食と膨張がこのチュートリアルの中心です。開閉操作の基本です。構造要素が円形の場合、膨張操作により、構造要素よりも小さい画像の穴と画像の端にある小さなくぼみを埋めることができます。腐食は、画像のバリや小さな接続コンポーネントを排除し、画像を縮小して、その補色を拡大することができます。ただし、膨張と腐食は互いに逆の操作ではないため、組み合わせて使用​​できます。収縮と拡張の2つの基本演算に基づいて、拡張演算と収縮演算の組み合わせで構成されるすべての演算と集合演算(和集合、交差、補数など)で構成される形態論演算クラスタを構築できます。たとえば、同じ構造要素を使用して、最初に画像を腐食してから結果を展開する(オープン操作と呼ばれる)か、最初に画像を展開してから結果を腐食する(クローズ操作と呼ばれる)ことができます。開いた操作と閉じた操作は、形態素操作ファミリの2つの最も重要な操作です。
画像Xと構造要素Sの場合、記号はSが画像Xに対して開いた操作を実行すること示すために使用され、記号はSが画像X に対して閉じた操作を実行すること示すために使用されます。
ここに画像の説明を挿入

最初に関数を理解する必要があります:

cv2.morphologyEx(src、op、kernel)

パラメータの説明:

src着信画像

オペレーションの変化

カーネルは、定義されたたたみ込みカーネルのサイズと形状を表します

op = cv2.MORPH_OPENで操作を開きます。つまり、最初に腐食操作を実行してから、拡張操作を実行します。

op = cv2.MORPH_CLOSEは、最初に膨張操作を参照し、次に腐食操作を参照する閉鎖操作を実行します。

オープンオペレーション

開く操作は、画像の最初の腐食操作、次に拡大操作を指します。通常、画像の明るい領域で操作して、画像のホワイトノイズを除去します。次に、例を見てみましょう。画像:
ここに画像の説明を挿入

ここで、画像の黒いバリを取り除きたいのですが、開く操作は画像の明るい領域を操作するためのものなので、画像を直接開く操作を実行することはできません。開く操作が直接どのような影響を与えるかを確認してください:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('open.jpg',0)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))  
open =cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)  
cv2.imshow("img",img)  
cv2.imshow("result", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

ここに画像の説明を挿入

ご覧のとおり、画像のバリは削除されていません。形態処理を容易にするために、元の画像にしきい値を設定する必要があります。つまり、白黒を反転させます。前のセクションでしきい値について説明しましたが、ここでは説明しません。 、コードを直接見てください:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('open.jpg',0)  
threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|  
                          cv2.THRESH_OTSU)[1]  
cv2.imshow("img",img)  
cv2.imshow("thres",threshold)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

ここに画像の説明を挿入

画像が白黒から反転したので、オープニング操作を開始できます。もちろん、コンボリューションカーネルも定義する必要があります。これは、前のチュートリアルで説明されています。ここでは、3 * 3の長方形のボリュームを定義します。製品コア:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('open.jpg',0)  
threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|  
                          cv2.THRESH_OTSU)[1]  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))  
open =cv2.morphologyEx(threshold,cv2.MORPH_OPEN,kernel)  
cv2.imshow("img",img)  
cv2.imshow("thres",threshold)  
cv2.imshow("result", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

ここに画像の説明を挿入

この効果は、畳み込みカーネルを5 * 5に変更すると明らかです。

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('open.jpg',0)  
threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|  
                          cv2.THRESH_OTSU)[1]  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))  
open =cv2.morphologyEx(threshold,cv2.MORPH_OPEN,kernel)  
cv2.imshow("thres",threshold)  
cv2.imshow("result", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows() 

ここに画像の説明を挿入

これは、操作が過剰であることを示しているため、形態学的処理のための畳み込みカーネルを適切に選択することが非常に重要です。ここで、処理された画像を復元します。

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('open.jpg',0)  
threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|  
                          cv2.THRESH_OTSU)[1]  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))  
open =cv2.morphologyEx(threshold,cv2.MORPH_OPEN,kernel)  
result = cv2.threshold(open,0,255,cv2.THRESH_BINARY_INV|  
                          cv2.THRESH_OTSU)[1]  
cv2.imshow("img",img)  
cv2.imshow("thres",threshold)  
cv2.imshow("open", open)  
cv2.imshow("result",result)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

最終的な復元の結果を見てください。
ここに画像の説明を挿入

実際、たたみ込みカーネルを柔軟に使用すると、画像の形態学的処理が非常に容易になります。実際の戦いを実行してみましょう。たとえば、画像を指定します。
ここに画像の説明を挿入

open操作を使用して、水平線と垂直線をそれぞれ抽出し、13 * 1たたみ込みカーネルを使用して実験します。

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('hengshu.jpg',0)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(13,1))  
open =cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)  
cv2.imshow("img",img)  
cv2.imshow("open", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

ここに画像の説明を挿入

それは素晴らしいことではありませんか?次に、1 * 13のたたみ込みカーネルを使用して実験します。

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('hengshu.jpg',0)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(1,13))  
open =cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)  
cv2.imshow("img",img)  
cv2.imshow("open", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

ここに画像の説明を挿入

垂直線も完全に抽出されています。今後のプロジェクトの実際の戦闘では、この知識を使用して、画像内の冗長な情報を合理的に除外します。実際、処理された画像は暗く、元の画像は非常に明るいため、次のチュートリアルのシルクハットとブラックハットの操作で処理できます。

クローズドオペレーション

私たちは長い間、オープン操作について投げてきました。次に、クローズ操作で遊んでみましょう。クローズ操作は、オープン操作の逆です。これは、拡大してから腐食します。通常、画像の明るい領域のノイズを除去するために使用されます。画像を見てみましょう:
ここに画像の説明を挿入

次に、クローズ操作を使用して、画像の明るい領域内の黒い点を削除し、7 * 7のたたみ込みカーネルを定義します。コードを見てみましょう。

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('close.jpg',0)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7))  
open =cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel)  
cv2.imshow("img",img)  
cv2.imshow("open", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

ここに画像の説明を挿入

ご覧のとおり、効果は非常に良好です。次に、実用的な意味を持つ別の実験を実行してみましょう。まず図を見てください。
ここに画像の説明を挿入

これらの文字の輪郭を抽出し、ボックスでマークする必要があります。単語の各行はボックスでマークされます。もちろん、これには、後で説明するアウトライン抽出とアウトライン近似が含まれますが、ここでは最初に実験を行います。単語の各行をボックスでマークする場合、最初に満たさなければならない条件は、OpenCVを使用して全体的なアウトラインを抽出し、それを調整できるように、各行の単語を接続して全体を形成する必要があることです。しかし、これらの単語は独立しており、互いに接続されていないことがわかりました。今回は、閉じた操作を使用できます。コードを見てみましょう:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('text1.jpg',0)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(21,5))  
open =cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel)  
cv2.imshow("img",img)  
cv2.imshow("open", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

ここに画像の説明を挿入

このようにして、すべてのフォントが接続され、後の輪郭抽出も容易になります。

私はここに包括的なコードを与えます、あなたはそれで遊ぶことができます:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread('text1.jpg')  
test = img.copy()  
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (19, 5))  
close = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)  
contour, _ = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  
cv2.drawContours(test, contour, -1, (0, 0, 255), 2)  
for c in contour:  
    x, y, w, h = cv2.boundingRect(c)  
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)  
cv2.imshow("result", img)  
cv2.imshow("test",test)  
cv2.imshow("close", close)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

ここに画像の説明を挿入

最初の画像は画像の輪郭を抽出するためのもので、2番目の画像は輪郭の外接矩形を抽出するためのものです。興味深いですか?これについては、後でゆっくりと説明します。

通常、閉じた操作は内部のノイズ条件を処理するために使用され、開いた操作は外部ノイズ条件を処理するために使用されるため、それらを合理的に使用することが非常に重要です。

記事の概要ページを確認してくださいhttps://blog.csdn.net/weixin_44237705/article/details/107864965
openvinoの技術情報はグループで交換できます〜
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_44237705/article/details/108334759
おすすめ