DY N DY
opencv dilate/erode 연산 정리 본문
Erode, Dilate 연산을 보통 모폴로지 기법이라고 한다.
위키에서 morphology에 대해 찾아보면...
를 타고 들어가면 https://en.wikipedia.org/wiki/Mathematical_morphology에 자세히 설명이 되어있는데 영어인지라...
대충... 기하학적인 구조의 분석과 처리를 위한 이론 및 기술이라고 한다.
영상내의 특정한 객체의 형태를 변형시킴으로써 작은 노이즈를 제거한다던가 미세하게 검출된 무언가를 키운다던가 등등...을 위해 사용한다.
보통은 이진영상에서 주로 사용한다.
Erode 연산 : 필터 내부의 가장 낮은(어두운) 값으로 변환(and) - 침식연산
Dilate 연산 : 필터 내부의 가장 높은(밝은) 값으로 변환(or) - 팽창연산
두 연산은 순서에 따라 서로 다른 기능을 한다.
Erode - Dilate = Opening 연산 : 주로 작은 노이즈들을 제거하는데 사용한다.
Dilate - Erode = Closing 연산 : 보통 한 객체를 추출했을 때 두개 이상의 작은 부분으로 나올 경우 큰 객체로 합칠 때 사용한다.
아래는 opencv(3.1에서 사용하였음.) 코드이다.
mask는 erode, dilate를 적용할 필터로 여기서는 3x3 사각형 구조의 필터를 사용한다.
일반적으로 타원형, 십자형도 있지만 주로 사각형을 많이 사용한다.
필터 크기를 크게 할 수록 변화량이 많아질 것이다.. 실험을 통해 확인해보면 쉽게 이해할 수 있다.
erode, dilate 연산은 반복하여 수행할 수 있다. 마지막 인자 3은 3번 반복수행한다는 뜻이다.
3번째 인자는 mask의 중심점인데 default로 -1,-1이 들어간다.
1 2 3 | cv::Mat mask = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3), cv::Point(1, 1)); cv::erode(src, dst, mask, cv::Point(-1, -1), 3); cv::dilate(src, dst, mask, cv::Point(-1, -1), 3); | cs |
이외에 morphologyEx함수가 opening, closing을 수행할 수 있다고 한다.
http://docs.opencv.org/3.1.0/d4/d86/group__imgproc__filter.html#ga67493776e3ad1a3df63883829375201f
문서를 살펴보면... 대략
1 2 3 4 5 6 7 8 9 | void cv::morphologyEx (InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar & borderValue = morphologyDefaultBorderValue() ) | cs |
라고 나와있는데... 거의 다르지 않아보인다. 결국 뭐 뒤에는 다 default가 있으니..
1 2 | cv::morphologyEx(src, dst, cv::MORPH_OPEN, mask) cv::morphologyEx(src, dst, cv::MORPH_CLOSE, mask) | cs |
이렇게 사용하면 될 것 같다...
아래와 같은 코드로 실험해 보았다. (위의 연산들을 사용하기 위해서는 imgproc.hpp를 include해야 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <imgproc.hpp> #include <iostream> using namespace cv; using namespace std; int main() { Mat image; image = imread("simple.jpg", IMREAD_COLOR); // Read the file if (!image.data) // Check for invalid input { cout << "Could not open or find the image" << std::endl; return -1; } namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display. imshow("Display window", image); // Show our image inside it. Mat mask = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3), cv::Point(1, 1)); Mat eroded, dilated, opened, closed; erode(image, eroded, mask, cv::Point(-1, -1), 3); imshow("Eroded", eroded); dilate(image, dilated, mask, cv::Point(-1, -1), 3); imshow("Dilated", dilated); morphologyEx(image, opened, cv::MorphTypes::MORPH_OPEN, mask); imshow("open", opened); morphologyEx(image, closed, cv::MorphTypes::MORPH_CLOSE, mask); imshow("close", closed); waitKey(0); // Wait for a keystroke in the window return 0; } | cs |
simple.jpg는 유명한 lena이미지의 이진화 영상이다. (혹시 연습할 분들을 위해 첨부하였다. - 구글에서 쉽게 구할 수도 있다.)
결과는 아래와 같다.
눈으로 확인해보면 어떤 연산인지 조금 더 쉽게 이해할 수 있을 것 같다.
simple.jpg
아마 오른쪽클릭하여 이미지 저장하면 저장 될 것이다.
'PARK > 영상처리 관련' 카테고리의 다른 글
opencv를 이용한 영상 합치기 (0) | 2016.11.17 |
---|---|
bomi 개발 시작 (0) | 2016.11.17 |
YOLO: Real-Time Object Detection 실습해보기 (6) | 2016.10.19 |
우분투 16.04.1에 darknet 설치 (2) | 2016.10.19 |
우분투 16.04.1에 opencv 3.1 설치 (2) | 2016.10.18 |