이번엔 http://opencvexamples.blogspot.com/p/learning-opencv-functions-step-by-step.html에 있는 8번째 예제를 공부하자.
8. Sobel Edge Detection
Sobel 엣지 검출은 1차 미분을 기반으로 한 유명한 엣지 검출 방법이다. Sobel라는 사람이 1970년에 제안한 방법이다. Sobel랑 Priwitt 방법은 거의 비슷한데, Sobel가 좀 더 나은 노이즈 억제를 보여준다고 한다. Sobel 필터 커널은 수직 엣지를 검출하는 것, 수평 엣지를 검출하는 것, 대각 엣지를 검출하는 것들로 구분지을 수 있다. 그림 1은 3 x 3 사이즈의 Sobel 커널들을 보여준다.
그림 1. Sobel 커널들
수직 엣지 검출용 커널로 지난 예제 7 때 활용한 수직 엣지가 있는 이미지를 컨볼루션하면 아래 그림 2와 같이 엣지 부분만 검출됨을 확인할 수 있다. 대각 엣지 커널들로도 엣지가 검출된다. 반면 수평 엣지 커널로는 검출되지 않는다.
그림 2. Sobel 커널들로 단순한 수직 엣지가 있는 이미지를 필터링한 결과
그렇다면 수직 엣지 커널과 대각 엣지 커널이 같은 역할은 한 것인가? 결과 이미지 매트릭스를 확인해보면 그렇지 않다 (그림 3). 수직 커널로 필터링했을 때 주변 픽셀들값과의 차이가 좀 더 크다. 수직 커널은 400의 차이를 보이는 반면, 대각 커널은 300의 차이를 보인다. Sobel 커널 입장에서 좀 더 확신을 가지고 엣지로 판별했다고 볼 수 있다.
그림 3. Sobel 수직 커널과 대각 커널들로 필터링한 결과 이미지 매트릭스
opencv에서 Sobel 엣지 검출은 Sobel 함수로 가능하다.
void Sobel(InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize=3, double scale=1, double delta=0, int borderType=BORDER_DEFAULT )
src - 입력 이미지
dst - 목적 이미지
ddepth - output image depth
xorder - x에 대한 미분 차수
yorder - y에 대한 미분 차수
ksize - Sobel 커널의 사이즈. 1, 3, 5, 7만 가능.
scale - optional scale factor for the computed derivative values.
delta - optional delta value that is added to the results prior to storing them in dst.
borderType - 픽셀 외삽 방법.
이제 이 함수를 이용해서 다른 이미지에서 Sobel 엣지를 검출해보자.
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"
using namespace cv;
using namespace std;
int main()
{
Mat src1;
src1 = imread("fig8.bmp", CV_LOAD_IMAGE_COLOR);
namedWindow("Original image", CV_WINDOW_AUTOSIZE);
imshow("Original image", src1);
Mat grey;
cvtColor(src1, grey, CV_BGR2GRAY); // 그레이 영상으로 변환
Mat sobelx, sobely;
Sobel(grey, sobelx, CV_32F, 1, 0); // Sobel 엣지 검출
Sobel(grey, sobely, CV_32F, 0, 1);
///
namedWindow("vertical edge", CV_WINDOW_AUTOSIZE);
imshow("vertical edge", sobelx);
namedWindow("horizontal edge", CV_WINDOW_AUTOSIZE);
imshow("horizontal edge", sobely);
waitKey(0);
return 0;
}
필터된 결과는 아래와 같다 (그림 4). 수직 엣지와 수평 엣지를 각각 검출해봤는데, 그럭저럭 잘 검출했지만 그렇지 못한 부분들도 있다.
그림 4. Sobel 엣지 검출 결과
<참고 자료>
[1] 곤잘레스, digital image processing, 3판, p.728-736.
'Dev > C, C++' 카테고리의 다른 글
[opencv와 C++로 컴퓨터 비전] 영상 읽고, 띄우고, 축소하고, 좌우반전하고, 저장하기 (0) | 2018.01.29 |
---|---|
C언어의 메모리 구조: 데이터(Data), 스택(Stack) 그리고 힙(Heap) 영역 (2) | 2017.10.16 |
포인터의 이해 (6) | 2017.10.09 |
opencv에서 픽셀값 접근하기 (2) | 2017.07.05 |
[Learn opencv by examples] 7. 2D 컨볼루션 / 새로운 필터 만들기 (0) | 2017.06.14 |
[Learn opencv by examples] 6. Gaussian 필터, Bilateral 필터, Median 필터 (2) | 2017.06.03 |
[Learn opencv by examples] 5. 영상 이진화, Threshold operation (0) | 2017.06.02 |
[Learn opencv by examples] 4. RGB 이미지를 그레이 영상 또는 다른 컬러 공간으로 전환하기 (0) | 2017.06.02 |