티스토리 뷰

OpenCV

[OpenCV] sobel 미분을 통한 edge extraction

생각많은 소심남 2012. 8. 21. 11:41

지난 포스트에서는 Threshold값을 조절함으로써 이미지의 경계값을 추출하는 예제를 해봤습니다. 그런데 사실은 그런 방법이외에도 여러가지 경계 추출법이 있습니다. 그중 하나가 이번 포스트에서 등장하는 Sobel derivative 입니다. 사용 방법은 다음과 같습니다.

void cvSobel(

const CvArr* src,                -     sobel 처리를 하려는 원래 IplImage

CvArr*         dst,                 -    처리한 결과를 담는 IplImage

int               xorder,            -    x방향으로 어느 차수만큼 미분할 것인가

int               yorder,            -    y방향으로 어느 차수만큼 미분할 것인가

int               aperture_size   -    마스크의 크기 (aperture_size * aperture_size)



일단 서두에 등장하는 내용이나 들어가는 인자의 경우로도 알겠지만 전체적으로 도함수를 활용한 함수입니다. 직선과 같이 기울기가 항상 일정한 선을 미분하면 상수가 나오고 곡선은 픽셀이 이동할수록 기울기가 변하기때문에 또 하나의 방정식이 등장할 겁니다. 그런 특성을 이용해서 경계 값에 대한 선을 쭉 그려주는 것이 바로 이 소벨함수의 역할이 되겠습니다. 우선 xorder와 yorder의 차이에 따른 결과값을 보겠습니다.

<order = 1, aperture_size = 3>


위 이미지에서 좌측은 X축 기점으로 1차 미분을 한 경우고 우측은 Y축 방향으로 동일한 작업을 수행했을 때의 결과입니다.

원래 이미지에서도 아시겠지만 배경에 패턴이 있습니다. 이걸 통하면 정확히 어느쪽 방향이 우선시되는지를 확인할 수 있지요. 좌측이미지에서는 x 방향에 대한 미분이 진행되었으므로 남는 성분은 y 성분일겁니다. 반대도 마찬가지 일것이겠고요. 이런 성향들을 적절히 조합하면 다음 이미지를 뽑아낼 수 있습니다.


이게 아마 우리가 뽑아내려는 목적이 아니었을까요? 물론 배경에 희미한 방향성분이 남아있겠지만 지난 포스트에서 언급한 Threshold를 조절한다면 충분히 없앨 수 있는 값이 됩니다. 다음은 aperture_size에 따른 결과값입니다.

<xorder = 1 yorder = 0>


좌측부터 aperture_size가 1,3,5씩 증가하는 변화입니다. 보면 size를 크게 할수록 무언가 세밀한 depth가 결과에 표현되고 있는 것을 볼 수 있습니다. 참고로 aperture_size가 1로 지정되면 마스크의 크기가 1x1이 되는 것이 아니라 1x3이나 3x1이 됩니다.이렇게 해서 조절한 값은 보통 결과에 대한 근사에 영향을 끼치게 됩니다. 보통 크기를 작게하면 결과가 러프하게 나타나고 키우게 되면 조그만 변화에도 결과를 표현하게 됩니다. 다음은 차수에 따른 결과값입니다.

<yorder = 1 , aperture_size = 5>


지금 위의 결과는 x미분 차수를 변화시켰을 때 어떤 결과가 나타나는 건지를 보고 있습니다. 차수는 최대 2차까지만 지원되고 맨 우측 이미지가 바로 order를 2로 했을 때 결과입니다. 점차적으로 배경이 없어지는 효과가 나타납니다. 하지만 2차에 가면서 손의 외곽선이 2개로 분리되는 것을 확인할 수 있습니다.

https://dl.dropbox.com/u/96808368/OpenCV/cvSobel.cpp

 지금 단순한 이미지만 가지고 sobel 미분 처리를 하고 있지만 키넥트에서 나오는 depthFrame을 여기에 적용시킨다면 역시 손에 대한 경계선도 추출할 수 있겠지요. 

댓글