파이썬 - OpenCV의 형태 학적 연산 (팽창과 침식)

구조 요소의 정의

코어 요소는 구조 요소를 정의하기 위해 직접 ndarray NumPy와 사용될 수있다 자체 getStructuringElement 기능을 사용할 수 OpenCV의-파이썬 형태 구조를 정의하는 것이다. 
프로토 타입 :

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의-파이썬 타원 (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()

개폐 동작이 실수 노이즈 화상 형성 스페 클 제거 용으로 작은 물체와 개방 동작, 상기 복수의 접속된다. 따라서, 어떤 경우에는 모두 연속 작업을 사용하여. 이러한 연속 개폐 동작을 이용하여 얻어진 화상에서 주 피사체의 동작을 개방 이진 이미지로. 그림에 노이즈 (즉 화상 "점")을 제거하고 싶은 경우에 마찬가지로, 제 화상은 개방 동작 및 폐쇄 동작에 사용될 수 있지만, 또한 세분화 객체의 일부를 제거한다.

원 화상 개방 동작 및 폐쇄 동작의 결과는 다음과 같다 :

쓰기 사진은 여기에 설명

형태 학적 연산 코너 에지를 검출함으로써 및

여기서, 화상의 가장자리 모서리를 검출하는 형태 연산자를 사용하는 방법보다 복잡한 예에 의해 (본원에 기재된 바와 같은 형태의 처리, 사용 또는 캐니 알고리즘 해리스 실용 등의 예에 불과하다).

에지 검출 
형태 에지 검출 원리는 매우 간단하고, 확장하는 경우, 피사체의 화상은 "확장"주위 할 것이다 부식이 될 이미지 오브젝트들 "축소." 두 이미지의 비교 변화 만 발생하는 가장자리의 영역. 그러므로 두 이미지를 감산, 에지 이미지 오브젝트 얻어진다. 여기에 여전히 참조에 사용 된 그림의 관련 섹션을 "요리 책을 프로그래밍 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 자형으로 더와 팽창비 코너 측면이다. 부식 코너 반발이 두 번째 블록 측면보다 에칭하면서 때. 두 이미지가 차감되는 경우에만 코너를 떠나. 아래 그림 ( "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의 메일 링리스트를 언급 대한 이해가 정확하지 볼 수있는 시간을 할애하고있다. 
우리는, 예를 들어, 확인 코드에 두 줄의 코드를 삽입 할 수 있습니다, 당신은 결과를 알 수 있습니다 :

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