我有以下图片
我正在尝试查找主矩形(白线之间的那些)的像素坐标。我尝试了几件事,但我无法获得足够好的解决方案。解决方案不一定是完美的,如果不是所有矩形都被检测到(尤其是那些非常小的矩形),那也没关系。虽然角落的位置必须尽可能准确,尤其是那些更大的模糊(我正在尝试编写一些简单的 AR 引擎)。
我可以澄清一下,只有 4 级灰度:0、110、180 和 255(打印时,没有屏幕会因为闪电和阴影而变化)
到目前为止,我尝试了几件事:
- 手动多级阈值(因为阴影和不同的闪电它不起作用)
- 自适应阈值:2个问题:
- 它将 180 和 255 色组合成白色,将 0、110 组合成黑色
- 模糊(较大)矩形的边缘/角位置不准确(它会为矩形区域添加模糊)
- sobel 边缘检测(模糊矩形的角更清晰,但它也检测矩形中的内边缘,这些边缘轮廓也不总是闭合的
看起来将这两者结合起来会以某种方式产生更好的结果。或者也许有人有不同的想法?
我也在考虑做floodfill,但是很难自动找到确定好的种子点和阈值(背景中可能还有一些其他的白色物体)。此外,我稍后将要针对 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()