I'm trying to write an algorithm for detecting checkerboard patterns. I know that MATLAB has a built-in function for this but I want to do it on my own.
Anyway, I have like 30 pictures of a checkerboard pattern that are shown to the camera in different positions. I have already developed an algorithm for finding the region of interest using regionprops which is working reasonably well. However, when I apply a canny filter on the photo for detecting the edges and then finding the lines, the Hough transform fails to detect some of the lines that must be detected in few photos. See figure 1 and figure 2 for example.
Here is an MCV of my code to see my preprocessing step and my current parameters of the Hough transform:
img = imread('checkerboard13.jpg');
bw = im2bw(img, graythresh(img));
bw = medfilt2(bw, [9,9]);
BW = edge(bw);
[H,T,R] = hough(BW);
P = houghpeaks(H, 100,'NHoodSize',[1 1],'threshold',ceil(0.01*max(H(:))));
lines = houghlines(BW, T, R, P, 'FillGap', 80, 'MinLength', 400);
x = T(P(:,2)); y = R(P(:,1));
figure;
imagesc(I);hold on;colormap gray;
axis image;
max_len = 0;
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');
len = norm(lines(k).point1 - lines(k).point2);
if ( len > max_len)
max_len = len;
xy_long = xy;
end
end
答案 0 :(得分:2)
因此,正如我在评论中所说,您必须使用用于膨胀和粗糙度的参数。
问题:您要寻找的线(特别是棋盘格的线)非常细且没有连接。因此,可以仅使用Houghlines,但需要大量调整参数。
解决方案:在应用霍夫线之前先对图像进行扩张,并相应地调整霍夫线的参数。
扩散本质上是一种形态运算,如果内核下至少一个像素为“ 1”,则像素元素为“ 1”。因此,它会增加图像中的白色区域或增加前景对象的大小。另外,您也可以尝试使用开放,它基本上是侵蚀(与扩张相反)+扩张。
粗线参数:
lines = cv.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]])
您情况下最重要的参数是:
阈值-确定要考虑的行,仅选择强度>阈值的行。
minLineLength -顾名思义,这确定了将分类为线的线的最小长度(以像素为单位)
maxLineGap -可能是第二个最重要的参数,如果不是最重要的参数(艰难的比赛vs阈值),则它定义了应归类为两行之间的最大差距一行。
其他参数:
rho :距离分辨率(以像素为单位,此处为1)
θ:弧度角分辨率,此处为1
要获得良好的教程,请查看how hough transform works?
使用带有以下代码的OpenCV:
import cv2
import numpy as np
image1 = cv2.imread('lines.jpg')
output = image1
image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
canny = cv2.Canny(image1, 100, 200)
canny = cv2.dilate(canny, (5,5), 7)
lines = cv2.HoughLinesP(canny, 1, np.pi/360, 120, minLineLength=200, maxLineGap=30)
for line in lines:
for x1,y1,x2,y2 in line:
cv2.line(output, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.imwrite("lines_res.jpg", output)
原始图片:
结果:
希望有帮助!让我知道您的想法!