반응형


Canny Edge Detector를 구현하기 위해 필요한 이론과 OpenCV에서 제공하는 Canny 함수 사용방법을 다룹니다.




  1. 캐니 에지 디텍터(Canny Edge Detector) 이론


     2. OpenCV Canny 함수


         2-1. Python 기본 예제


                트랙바 사용 예제


         2-2. C++ 기본 예제


                트랙바 사용 예제


     3. 참고




2018. 11. 14. 최초 작성.



1. 캐니 에지 디텍터(Canny Edge Detector) 이론




2. OpenCV Canny 함수

OpenCV에서는 하나의 함수 Canny만 호출하면 캐니 에지를 얻을 수 있습니다.


2-1. Python 기본 예제


img_canny = cv2.Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)


  • 첫번째 아규먼트 image는 입력 이미지입니다.

  • 두번째, 세번째 아규먼트 threshold1, threshold2는 최소 스레숄드와 최대 스레숄드입니다.

  • 네번째 아규먼트 edges에 Canny 결과를 저장할 변수를 적어줍니다.  파이썬에선 Canny 함수 리턴으로 받을 수 있기 때문에 필요없는 항목입니다.

  • 다섯번째 아규먼트 apertureSize는 이미지 그레디언트를 구할때 사용하는 소벨 커널 크기입니다. 디폴트는 3입니다.

  • 여섯번째 아규먼트 L2gradient가 True이면 그레디언트 크기를 계산할 때 sqrt{(dI/dx)^2 + (dI/dy)^2}를 사용합니다.

False라면 근사값인 |dI/dx|+|dI/dy|를 사용합니다.  디폴트값은 False입니다.



import cv2


img_gray = cv2.imread('house.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow("Original", img_gray)

img_canny = cv2.Canny(img_gray, 50, 150)
cv2.imshow("Canny Edge", img_canny)

cv2.waitKey(0)
cv2.destroyAllWindows()



트랙바 사용 예제


import cv2


def nothing():
   pass



img_gray = cv2.imread('house.jpg', cv2.IMREAD_GRAYSCALE)


cv2.namedWindow("Canny Edge")
cv2.createTrackbar('low threshold', 'Canny Edge', 0, 1000, nothing)
cv2.createTrackbar('high threshold', 'Canny Edge', 0, 1000, nothing)

cv2.setTrackbarPos('low threshold', 'Canny Edge', 50)
cv2.setTrackbarPos('high threshold', 'Canny Edge', 150)

cv2.imshow("Original", img_gray)

while True:

   low = cv2.getTrackbarPos('low threshold', 'Canny Edge')
   high = cv2.getTrackbarPos('high threshold', 'Canny Edge')

   img_canny = cv2.Canny(img_gray, low, high)
   cv2.imshow("Canny Edge", img_canny)

   if cv2.waitKey(1)&0xFF == 27:
       break


cv2.destroyAllWindows()




..


..


2-2. C++ 기본 예제


void cv::Canny(InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false )


  • 첫번째 아규먼트 image는 입력 이미지입니다.

  • 두번째 아규먼트 edges에 Canny 결과를 저장할 변수를 적어줍니다.

  • 세번째, 네번째 아규먼트 threshold1, threshold2는 최소 스레숄드와 최대 스레숄드입니다.

  • 다섯번째 아규먼트 apertureSize는 이미지 그레디언트를 구할때 사용하는 소벨 커널 크기입니다. 디폴트는 3입니다.

  • 여섯번째 아규먼트 L2gradient가 True이면 그레디언트 크기를 계산할 때 sqrt{(dI/dx)^2 + (dI/dy)^2}를 사용합니다.

False라면 근사값인 |dI/dx|+|dI/dy|를 사용합니다.  디폴트값은 False입니다.


#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>

using namespace cv;


Mat src_gray;
Mat dst, detected_edges;

int lowThreshold = 50;
int highThreshold = 150;


int main(int argc, char** argv)
{

Mat src = imread("house.jpg", IMREAD_COLOR); // Load an image
if (src.empty())
{
std::cout << "Could not open or find the image!\n" << std::endl;
std::cout << "Usage: " << argv[0] << " <Input image>" << std::endl;
return -1;
}

cvtColor(src, src_gray, COLOR_BGR2GRAY);
blur(src_gray, detected_edges, Size(3, 3));
Canny(detected_edges, detected_edges, lowThreshold, highThreshold, 3);

namedWindow("Canny Edge", WINDOW_AUTOSIZE);
imshow("Canny Edge", detected_edges);


waitKey(0);
return 0;
}



트랙바 사용 예제


#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>

using namespace cv;



Mat src_gray;
Mat dst, detected_edges;

int lowThreshold = 50;
int highThreshold = 150;


static void CannyThreshold(int, void*)
{
blur(src_gray, detected_edges, Size(3, 3));
Canny(detected_edges, detected_edges, lowThreshold, highThreshold, 3);

imshow("Canny Edge", detected_edges);
}


int main(int argc, char** argv)
{

Mat src = imread("house.jpg", IMREAD_COLOR); // Load an image
if (src.empty())
{
std::cout << "Could not open or find the image!\n" << std::endl;
std::cout << "Usage: " << argv[0] << " <Input image>" << std::endl;
return -1;
}


cvtColor(src, src_gray, COLOR_BGR2GRAY);

namedWindow("Canny Edge", WINDOW_AUTOSIZE);
createTrackbar("Min Threshold:", "Canny Edge", &lowThreshold, 1000, CannyThreshold);
createTrackbar("Max Threshold:", "Canny Edge", &highThreshold, 1000, CannyThreshold);
CannyThreshold(0, 0);

waitKey(0);
return 0;
}



3. 참고

https://docs.opencv.org/3.4.3/da/d22/tutorial_py_canny.html


https://docs.opencv.org/3.4.3/da/d5c/tutorial_canny_detector.html

반응형

포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.

여러분의 응원으로 좋은 컨텐츠가 만들어집니다.
지금 본 내용이 도움이 되었다면 유튜브 구독 부탁드립니다. 감사합니다 : )

유튜브 구독하기


제가 쓴 책도 한번 검토해보세요.

  1. 쉬운게 하나도 없네 2019.06.10 17:40

    덕분에 많이 배우고있습니다. 좋은 자료들 감사합니다.

    Video를 불러와서 출력하는데 트랙바를 붙여서 Contrast 랑 Brightness를 변경시켜 볼려고 하는데

    정상적으로 출력은 되는데 트랙바를 움직이면 동영상이 느려지네요. 디폴트값으로 맞춰주면 다시 정상속도로

    실행되고 트랙바를 움직이면 다시 느려지는데 왜 그런지 혹시 아시나요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.06.10 19:39 신고

      혹시 포스트의 C++ 코드를 참고하여 작성했다면

      파이썬 예제처럼 트랩바에서 지정한 콜백함수는 더미로 만들어두는 방식으로 변경해보세요.


  2. 코딩왕 2020.07.09 03:53

    openCV 관련 거의 모든 글을 정독하고 있습니다. 정말 많이 배우고 있네요 감사합니다.

  3. SJC 2020.08.18 09:42

    안녕하세요 혹시 0도 45도 90도 135도로 근사한건 어떻게 하셨는지 알 수 있을까요?
    소스코드 공유해주시면 제일 좋을것 같구요...ㅎ 항상 잘 보고 있습니다 감사합니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.08.18 18:46 신고

      x방향, y방향 소벨 연산자로 gx.. gy를 구한후

      atan2로 각도를 구했습니다.

      atan2(gy, gx)


      각도가 45도에 +-20 일정값을 더하고 뺀 범위내면 해당 각도를 45도로 하면 됩니다.

+ Recent posts