용어
에지 검출 방법
종류
선행조건: 잡음이 있을 경우 미분값이 정확하지 않으므로 noise filtering 후 에지 검출을 수행
sobel operator
canny edge detector
순서
가우시안 필터를 사용하여 영상 내 잡음 제거
소벨 에지 마스크 활용하여 gradient 크기와 각도 계산
nonmaxima suppression 수행 --> edge가 두꺼워지는 것을 방지하여 edge를 얇게 유지해줌
double thresholding 수행 & connectivity analysis to detect and link edges
1. M(x,y) >= Th -> edge
1. Th, Tl은 사용자가 정의
int main() {
Mat image, canny;
image = imread("lena.png", 0);
//performs canny edge detection
//image: input Mat, canny: output Mat
//190: Thresh_low of double thresholding
//200: Thresh_high of double thresholding
//3: aperture size of the Sobel operation
Canny(image, canny, 190, 200, 3);
imshow("Input image", image);
imshow("canny", canny);
waitKey(0);
}
위의 canny edge detector 경우 소벨 에지보다 적은 수의 픽셀만 에지라고 판단됨
허프 변환 개념
알고리즘
원 검출
코드
HoughLines
int main() {
Mat image, edge, result;
float rho, theta, a, b, x0, y0;
Point p1, p2;
vector<Vec2f> lines;
image = imread("chess_pattern.png");
result = image.clone();
cvtColor(image, image, CV_BGR2GRAY);
Canny(image, edge, 50, 200, 3); // line detection 전에 edge detection 수행
//applying Hough Transform to find lines in the image
//edge: input Mat, lines: output vector of lines
//1: (rho) distance resolution of the accumulator in pixels
//CV_PI/180: (theta) angle resolution of the accumulator in radians
//150: (threshold) accumulator threshold parameter
//minimum angle to check for lines. Must fall between 0 and max_theta.
//maximum angle to check for lines. Must fall between min_theta and CV_PI
HoughLines(edge, lines, 1, CV_PI / 180, 150,0,CV_PI);
for (int i = 0; i < lines.size(); i++) { // line 그리는 작업
rho = lines[i][0];
theta = lines[i][1];
a = cos(theta);
b = sin(theta);
x0 = a * rho;
y0 = b * rho;
p1 = Point(cvRound(x0 + 1000 * (-b)), cvRound(y0 + 1000 * a));
p2 = Point(cvRound(x0 - 1000 * (-b)), cvRound(y0 - 1000 * a));
line(result, p1, p2, Scalar(0, 0, 255), 3, 8);
}
imshow("Input image", image);
imshow("edge", edge);
imshow("Hough Transform", result);
waitKey(0);
}
HoughLinesP
int main() { Mat image, edge, result; vector<Vec4i> lines;
image = imread("chess_pattern.png"); result = image.clone();
cvtColor(image, image, CV_BGR2GRAY);
Canny(image, edge, 50, 200, 3);
//edge: input Mat, lines: output vector of lines
//1: (rho) distance resolution of the accumulator in pixels
//CV_PI/180: (theta) angle resolution of the accumulator in radians
//50: (threshold) accumulator threshold parameter
//10: (minLineLength) minimum line length.
//300: (maxLineGap) Maximum allowed gap between points on the sa me line to link them
HoughLinesP(edge, lines, 1, CV_PI / 180, 50, 10, 300);
for (int i = 0; i < lines.size(); i++) {
Vec4i l = lines[i];
line(result, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, 8);
}
imshow("Input image", image);
imshow("edge", edge);
imshow("Hough Transform", result);
waitKey(0);
}
HoughLines()와 HoughLinesP()의 차이