IT/C

영상처리-C++로 이미지 Sobel 경계 검출 및 영상 이진화

김효랑이 2018. 10. 30. 16:00
728x90
반응형

 호야의 블로그 

[C++] 영상처리-이미지 Sobel 경계 검출 및 영상 이진화

자신의 사진을 통해 직접 Sobel 경계 검출 실습과 영상 이진 변환 실습을 합니다.


Sobel 경계 검출

Sobel 경계 검출의 알고리즘은 3*3크기의 행렬을 사용하여 연산을 하였을 때 중심을 기준으로 각방향의 앞뒤의 값을 비교하여서 변화량을 검출하는 알고리즘입니다. 3x3크기의 행렬을 수직(X), 수평(Y) 방향별로 각각의 행렬을 가지는 데 형태는 다음과 같이 수직, 수평 밝기 변화에 따릅니다. 쉽게 말하면 점을 기준으로 수직(X) 필터는 좌우 비교, 수평(Y) 필터는 위아래를 비교하여 결정합니다.

<Sobel 경계 검출 3x3 마스크>

소벨 마스크는 모든 방향의 에지를 추출하며, 잡음에 강한 편입니. 또한 수직 수평 방향 에지보다 대각선 방향 에지에 더 민감하게 반응하며 마스크가 커질수록 효과는 약해집니.


영상 이진화

영상 이진화는 RGB 값으로 다양하게 분포되어 있는 색상 값을 0 1 만의 값으로 표현하는 것입니. 실제적으로는 RGB 컬러 영상을 흑백(Gray channel)영상으로 바꾼 뒤 특정 임계값(Threshold)을 기준으로 초과 값은 255(흰색), 이하 값은 0(검정색)으로 변환하게 됩니. 이는 명령어에 따라 아래와 같이 다른 기능을 갖게 되는데 ‘CV_THRESH_BINARY’를 여기서 사용하였습니다.

CV_THRESH_BINARY : threshold 값 초과는 255, 이하는 0

CV_THRESH_BINARY_INV : threshold 값 초과는 0, 이하는 255

CV_THRESH_TRUNC : threshold 값 초과는 threshold, 이하는 유지

CV_THRESH_TOZERO : threshold 값 초과는 유지, 이하는 0

CV_THRESH_TOZERO_INV : threshold 값 초과는 0, 이하는 유지 

위 그림은 좌측부터 수직(X) 필터, 수평(Y) 필터를 통한 경계 검출, 그리고 Sobel 경계 검출을 통해 얻은 표준 사진입니다. 확실히 수직 필터와 수평 필터를 적용했을 때 차이가 큽니다. 점을 기준으로 좌우를 비교한 수직 경계 검출은 세로 선에 흰 색(0)이 많이 보이고, 반면 수평 경계 검출은 가로 선에서 흰 색(0)을 많이 찾을 수 있습니다. 두 과정을 통해 Sobel 경계 검출의 표준(Norm)을 얻을 수 있습니.


실습

Visual Studio 2017에서 진행하였으며 C++Open CV(3.4.1 x64)를 이용하였습니. 사진을 불러와서 흑백으로 변환한 이후에 X, Y 필터를 통해 경계를 검출합니다. 이후에 영상 이진화를 통해 임계점이 낮은 영상부터 높은 영상까지 실습을 통해 비교 분석하였습니.

<Sobel 경계 검출을 위한 원본 사진과 흑백화시킨 사진>


Sobel 수직, 수평 경계 검출

<Sobel XY 경계 검출>

Sobel Norm에 대한 영상 이진화 과정을 간단히 요약하자면 임계값을 정하고 그 값에 따라 0, 255 즉 흑과 백을 결정하여 두 가지의 색으로 표현하는 것 입니다. 이를 이용해 사진에 대한 스케치를 간단히 얻을 수 있습니다. 여기서는 여러 가지 설정 중 ‘CV_THRESH_BINARY’를 선택하여 진행하였습니다. 이 설정은 threshold값이 임계값을 초과하면 255, 이하는 0으로 설정됩니다.


표준을 이용한 영상 이진화

위 그림은 좌측부터 낮음, 중간, 높음의 임계값으로 설정한 후에 확인한 결과입니다. LOW 결과의 값은 235로 설정하여 0~235의 색들은 모두 0, 즉 검정색으로 설정되며 꽤 넓은 검정색의 범위를 가져 약간 거칠게 스케치된 느낌입니다. HIGH 결과의 값은 200으로 설정하여 흰색의 범위가 더 넓어져 형태가 무너져 보기에 불편합니다. 마지막으로 MID의 결과 값은 220으로 설정하였는데 거칠지도 형태가 무너지지도 않아 딱 보기좋게 설정된 모습입니다. 이렇게 각기 다른 임계치 설정을 통해 자신이 원하는 스케치 결과를 도출할 수 있습니다.

<영상 이진화의 범위 구조>

<영상 이진화 3가지 결과>


소스

#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> int main() { cv::Mat image = cv::imread("image.jpg", 0); //흑백 처리 cv::namedWindow("Gray-scale Image"); cv::imshow("Gray-scale Image", image); cv::Mat sobelX, sobelY; cv::Sobel(image, sobelX, CV_8U, 1, 0, 3, 1.0, 128); // 수평 필터 호출(커널 사이즈 3) 각도 0.4 cv::Sobel(image, sobelY, CV_8U, 0, 1, 3, 1.0, 128); // 수직 필터 호출(커널 사이즈 3) // 0값은 128인 그레이레벨에 해당 // 음수 값은 어두운 화소로 표현, 양수 값은 밝은 값을 표현 cv::namedWindow("Sobel image X"); cv::imshow("Sobel image X", sobelX); cv::namedWindow("Sobel image Y"); cv::imshow("Sobel image Y", sobelY); // 소벨 필터의 결과는 일반적으로 16비트 부호 있는 정수영상(CV_16S)에서 계산 // 소벨 놈(norm) 계산 (수직과 수평 두 결과의 소벨 필터 놈을 얻기 위해 조합) cv::Sobel(image, sobelX, CV_16S, 1, 0, 3); cv::Sobel(image, sobelY, CV_16S, 0, 1, 3); cv::Mat sobel; sobel = abs(sobelX) + abs(sobelY); // L1 놈 계산 // 소벨 놈은 0인 값을 흰색으로, 높은 값을 어두운 회색 음영으로 할당한 영상을 얻기 위해 // converTo 메소드의 부가적인 재스케일링 파라미터를 사용 double sobmin, sobmax; cv::minMaxLoc(sobel, &sobmin, &sobmax); // 소벨 최댓값 찾기 // sobelImage = -alpha*sobel + 255 // 8비트 영상 변환 cv::Mat sobelImage; sobel.convertTo(sobelImage, CV_8U, -255.0 / sobmax, 255); cv::namedWindow("Sobel Image Norm"); cv::imshow("Sobel Image Norm", sobelImage); // 영상의 경계값을 처리 cv::Mat sobelThresholded; cv::threshold(sobelImage, sobelThresholded, 235, 255, cv::THRESH_BINARY); // 소벨 놈에 대한 경계값 적용(낮은 경계값) 임계 235보다 낮으면 00(검정) : 0~235 검정, 236~255 흰색 cv::namedWindow("Binary Sobel Image LOW"); cv::imshow("Binary Sobel Image LOW", sobelThresholded); cv::threshold(sobelImage, sobelThresholded, 220, 255, cv::THRESH_BINARY); // 소벨 놈에 대한 경계값 적용(적당한 경계값) 임계 220보다 낮으면 00(검정) : 0~220 검정, 221~255 흰색 cv::namedWindow("Binary Sobel Image MID"); cv::imshow("Binary Sobel Image MID", sobelThresholded); cv::threshold(sobelImage, sobelThresholded, 200, 255, cv::THRESH_BINARY); // 소벨 놈에 대한 경계값 적용(높은 경계값) 임계 200보다 낮으면 00(검정) : 0~235 검정, 200~255 흰색 cv::namedWindow("Binary Sobel Image HIGH"); cv::imshow("Binary Sobel Image HIGH", sobelThresholded); cv::waitKey(0); return 0; }


후기 및 정리

Sobel 경계 검출을 공부하다보니 이 방법 외에도 수많은 경계 검출 방법이 있었다는 것을 알게 됐습니다. 조사하다가 한 가지 알게 된 것은 Sobel 알고리즘 외에도 캐니 검출 방법이 많이 거론되는 것 입니다. 다른 에지 검출기 보다 우월하고 명확하게 검출되는 방법으로 유명하며 잡음에도 민감하지 않고 강한 에지를 추출하는 목적을 가진다고 합니다. 여러분들도 직접 한 번 테스트 해보시길 바라겠습니다. 감사합니다.



조금의 도움이 되셨다면 로그인 없이도 가능한 댓글과

왼쪽 아래 ♥공감 버튼을 꾹 눌러주세요! 




728x90
반응형