05-12 07:57
Notice
Recent Posts
Recent Comments
관리 메뉴

Scientific Computing & Data Science

[OpenCV] Sobel Edge Detector 본문

Programming/OpenCV

[OpenCV] Sobel Edge Detector

cinema4dr12 2015. 7. 21. 22:50

이번 글에서는 Edge Detector 중의 하나인 Sobel Operator를 이용하여 Edge Detection을 구현하는 방법에 대하여 알아보도록 하겠습니다.



1. Sobel Operator

(1) Theory

Sobel Operator는 1968년도에 "Isotropic 3×3 Image Gradeient Operator"라는 아이디어를 발표한 Irwin Sobel과 그의 Gary Feldman의 이름을 따르는 Edge Detection Algorithm입니다.[Wikipedia]

여타 Image Processing Fileter와 마찬가지로 회선처리(Convolution)에 의해 계산되며 수평 및 수직 Sobel Kernel은 다음과 같습니다:


\( G_x = \begin{bmatrix} -1 & 0 & +1 \\ -2 & 0 & +2 \\ -1 & 0 & +1 \end{bmatrix} \)  및  \( G_y = \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ +1 & +2 & +1 \end{bmatrix} \)


통상적으로 수평 Kernel과 수직 Kernel에 대한 회선처리를 한 후 각 결과값에 대해 Weighted Sum을 하여 픽셀값을 정합니다.

(2) Implementation

OpenCV에서 Sobel Operator를 이용하여 Edge Detection을 하는 Procedure는 다음과 같습니다: 


(1)  이미지를 로딩한다. (cv::imread())

(2)  Gaussian Blur 연산을 한다. (cv::GaussianBlur())

(3)  RGB에서 Grayscale로 변환한다. (cv::cvtColor())

(4)  Sobel Kernel을 이용하여 회선처리한다. (cv::Sobel())

(5)  회선처리하여 계산된 결과를 8-bit unsigned integer로 변환한다. (cv::convertScaleAbs())

(6)  이미지를 띄운다.

(3) Source Code

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <opencv2/opencv.hpp>
 
#include <stdlib.h>
#include <stdio.h>
 
using namespace std;
using namespace cv;
 
/* @ function main */
int main( int argc, char** argv )
{
  cv::Mat src, src_gray;
  cv::Mat grad;
  int scale = 1;
  int delta = 0;
  int ddepth = CV_16S;
 
  /// Load an image
  src = cv::imread( {YOUR_IMAGE_PATH}, 1 );
 
  /// Create window & show it
  cv::namedWindow( "Image Original", CV_WINDOW_AUTOSIZE );
  cv::imshow( "Image Original", src );
 
  if!src.data ) { return -1; }
 
  cv::GaussianBlur( src, src, Size(3,3), 00, BORDER_DEFAULT );
 
  /// Convert it to gray
  cv::cvtColor( src, src_gray, CV_RGB2GRAY );
 
  /// Generate grad_x and grad_y
  cv::Mat grad_x, grad_y;
  cv::Mat abs_grad_x, abs_grad_y;
   
  /// Gradient X
  cv::Sobel( src_gray, grad_x, ddepth, 103, scale, delta, BORDER_DEFAULT );
 
  cv::convertScaleAbs( grad_x, abs_grad_x );
 
  /// Gradient Y
  cv::Sobel( src_gray, grad_y, ddepth, 013, scale, delta, BORDER_DEFAULT );
   
  cv::convertScaleAbs( grad_y, abs_grad_y );
   
  /// Total Gradient (approximate)
  cv::addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.50, grad );
   
  /// Create window & show it
  cv::namedWindow( "Sobel Edge Detector", CV_WINDOW_AUTOSIZE );
  cv::imshow( "Sobel Edge Detector", grad );
   
  waitKey(0);
 
  return 0;
 
}
cs


cv::Sobel() 함수에 대한 자세한 설명은 다음 링크를 참고합니다:

http://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#gacea54f142e81b6758cb6f375ce782c8d

(4) Results

Original Image


Sobel Operator 적용



2. Scharr Operator

Scharr Operator는 Sobel Operator가 축대칭에 대한 Edge 검출이 완벽하지 않은 것을 보완하기 위해 Hanno Scharr가 2000년에 발표한 것이며, Scharr Kernel은 다음과 같습니다:


\( G_x = \begin{bmatrix} +3 & +10 & +3 \\ 0 & 0 & 0 \\ -3 & -10 & -3 \end{bmatrix} \)  및  \( G_y =  \begin{bmatrix} +3 & 0 & -3 \\ +10 & 0 & -10 \\ +3 & 0 & -3  \end{bmatrix} \)

(1) Source Code

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <opencv2/opencv.hpp>
 
#include <stdlib.h>
#include <stdio.h>
 
using namespace std;
using namespace cv;
 
/* @ function main */
int main( int argc, char** argv )
{
  cv::Mat src, src_gray;
  cv::Mat grad;
  int scale = 1;
  int delta = 0;
  int ddepth = CV_16S;
 
  /// Load an image
  src = cv::imread( {YOUR_IMAGE_PATH}, 1 );
 
  /// Create window & show it
  cv::namedWindow( "Image Original", CV_WINDOW_AUTOSIZE );
  cv::imshow( "Image Original", src );
 
  if!src.data ) { return -1; }
 
  cv::GaussianBlur( src, src, Size(3,3), 00, BORDER_DEFAULT );
 
  /// Convert it to gray
  cv::cvtColor( src, src_gray, CV_RGB2GRAY );
 
  /// Generate grad_x and grad_y
  cv::Mat grad_x, grad_y;
  cv::Mat abs_grad_x, abs_grad_y;
   
  /// Gradient X
  cv::Scharr( src_gray, grad_x, ddepth, 10, scale, delta, BORDER_DEFAULT );
 
  cv::convertScaleAbs( grad_x, abs_grad_x );
 
  /// Gradient Y
  cv::Scharr( src_gray, grad_y, ddepth, 01, scale, delta, BORDER_DEFAULT );
   
  cv::convertScaleAbs( grad_y, abs_grad_y );
   
  /// Total Gradient (approximate)
  cv::addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.50, grad );
   
  /// Create window & show it
  cv::namedWindow( "Scharr Edge Detector", CV_WINDOW_AUTOSIZE );
  cv::imshow( "Scharr Edge Detector", grad );
   
  waitKey(0);
 
  return 0;
 
}
cs


cv::Scharr() 함수에 대한 자세한 설명은 다음 링크를 참고한다:

http://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#gaa13106761eedf14798f37aa2d60404c9

(2) Results

Original Image


Scharr Operator 적용


'Programming > OpenCV' 카테고리의 다른 글

[OpenCV] Laplace Operator  (0) 2015.07.25
[OpenCV] WebCam Frame Capture  (0) 2015.07.23
[OpenCV] RGB Color를 Grayscale로 변환하기  (3) 2015.07.21
[OpenCV] Gaussian Blur  (4) 2015.07.18
[OpenCV] 원본 이미지 상에 컬러 입히기  (0) 2015.07.08
Comments