我有以下图片
我正在尝试找到主矩形的像素坐标(白线之间的像素坐标)。我尝试了一些东西,但我无法获得足够好的解决方案。如果没有检测到所有矩形(特别是那些非常小的矩形),解决方案就不一定非常完美。虽然角落位置必须尽可能精确,特别是那些更大的模糊(我正在尝试编写一些简单的AR引擎)。
我可以澄清只有4级灰阶:0,110,180和255(打印时,没有屏幕会因闪电和阴影而变化)
到目前为止,我尝试过几件事:
看起来将两者结合起来会以某种方式产生更好的结果。或者也许有人有不同的想法?
我还在考虑做洪水填充,但很难找到确定好的种子点和阈值(背景中可能还有其他一些白色物体)。此外,我希望稍后对GPU进行优化,而泛洪算法则不适合这种情况。
以下是我到目前为止尝试的一些示例代码:
image = cv2.imread('data/image.jpg');
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imshow('image', gray)
adaptive = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 601, 0)
cv2.imshow('adaptive', adaptive)
gradx = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=3)
grady = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=3)
abs_gradx = cv2.convertScaleAbs(grady)
abs_grady = cv2.convertScaleAbs(grady)
grad = cv2.addWeighted(abs_gradx, 0.5, abs_grady, 0.5, 0)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
grad = cv2.morphologyEx(grad, cv2.MORPH_OPEN, kernel)
grad = cv2.morphologyEx(grad, cv2.MORPH_CLOSE, kernel)
cv2.imshow('sobel',grad)
#kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(7,7))
#grad = cv2.morphologyEx(grad, cv2.MORPH_OPEN, kernel)
retval, grad = cv2.threshold(grad, 10, 255, cv2.THRESH_BINARY)
cv2.imshow('sobel+morph+thrs',grad)
cv2.waitKey()
答案 0 :(得分:3)
我相信你的答案在于使用Hough变换来检测线条,延伸这些线条以跨越较暗的正方形之间的断点,然后寻找标记出角落的交叉点。我已经在Matlab中快速发挥并提出了以下内容,它并不完美,但应该显示出潜力:
% Open image
i = imread('http://i.stack.imgur.com/kwcXm.jpg');
% Use a sharpening filter to enhance some of the edges
H = fspecial('unsharp');
i = imfilter(i, H, 'replicate');
% Detect edge segments using canny
BW = edge(i, 'canny');
% Apply hough transform to edges
[H, T, R] = hough(BW, 'RhoResolution', 0.5, 'Theta', -90:0.5:89.5);
% Find peaks in hough transform
P = houghpeaks(H, 5, 'threshold', ceil(0.1*max(H(:))));
% Extract lines from peaks, extending partial lines
lines = houghlines(BW, T, R, P, 'FillGap', 100, 'MinLength', 5);
% Plot detected lines on image
imshow(i); hold on;
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
end
最终结果:
显然还有改进的余地,还有许多线路要检测,但是如果调整各种参数不起作用,你可以采取初始结果并搜索更多具有相似角度的线条以获得更完整的设置。然后可以从交叉点找到角点,这应该足够简单以便提取。
答案 1 :(得分:0)
我会尝试以下方法:
有一些事情会让你的问题变得比它需要的更棘手:
如果你可以尽量减少上述问题,它可能有助于解决问题。