这是这个问题的延续: Finding Squares in Image
我在那里按照我的回答中的步骤操作:https://dsp.stackexchange.com/a/7526/818 ,我得到的答案如下:
但是在那个答案的最后,我已经解释了一个问题,这就是我的问题。
解释:
我已经有了上一个链接中步骤 1 中检测到的正方形的质心(这些检测到的正方形在下面的 mask_image 中标记):
我创建了如下网格图像(我也知道它们的质心值):
我还发现网格图像中的哪个点映射到 mask_image 中的对应点。
有了这些信息,我申请了 scipy.interpolate.griddata() ,然后是 OpenCV 的 cv2.remap() 函数。
其结果如下:
如您所见,除了中心的两个正方形外,所有正方形都被剪裁了。就像,输出仅包含连接 mask_image 的所有质心的边界内的区域。
下面的场景变得更糟:
当第一步没有检测到最后一个正方形(黄色)或四个角的任何其他正方形时,情况会更糟。考虑未检测到最后一个。然后下面是我得到的结果,你可以在底部看到一个斜切(用黄色标记):
问题:
为什么重新映射功能不能超出我给出的点?我应该怎么做才能在不剪裁的情况下重新映射它?
我认为即使我给出一些不在边缘的点,它也适用于完整图像。
预期输出:
以下是我在操作结束时预期的输出。 (红色边界内的区域是我现在实际得到的)
寻找一些好的建议...
更新:
我也在这里添加代码。仅添加重新映射零件代码。完整代码太大,无法在此处添加:
# ideal - the grid image - http://i.stack.imgur.com/3QudG.png
# centroids - list of centroids of the squares in mask_image - http://i.stack.imgur.com/jh6bQ.png
# match_pts - list of centroids of the squares in grid image corresponding to squares in mask_image
# warped - the final image obtained after remap - http://i.stack.imgur.com/O26ZA.png
grid_x,grid_y = np.meshgrid(np.arange(ideal.shape[1]),np.arange(ideal.shape[0]))
dst = np.array(centroids)
src = np.array(match_pts)
grid_z = griddata(dst,src,(grid_x,grid_y),method='cubic')
map_x_32 = grid_z[:,:,0].astype('float32')
map_y_32 = grid_z[:,:,1].astype('float32')
warped = cv2.remap(ideal, map_x_32, map_y_32, cv2.INTER_CUBIC)
最佳答案
第 1 步:无论您从 B、G、R、H、S、V 平面中分析得到的最终二进制图像是什么,都在该图像中执行 blob 计数算法。
第 2 步:根据面积或轮廓长度找到最大的 Blob 。由于您的 Blob 将主要是平行四边形类型,因此面积或轮廓,任何一个都可以。
第 3 步:使用最大的 blob(因为最大的 blob 是类似于现实世界正方形的最佳 blob)尝试找到 blob 的方向......这可以通过拟合最佳拟合矩形来获得,或者您可以获得角点...获取连接它们的线的斜率(在水平方向和垂直方向上)。
第4步:一旦你得到两个斜坡,画两条穿过 Blob 轴的线。对于轴,您可以平均角点,也可以使用质心(质心)...我会使用角点的平均值...
第5步:由于在每个水平和垂直方向上,间距都是相等的(理想的水平和垂直间距也相等,因为它来自您理想的方形图片,但我们不会假设它..)只需要找到另一个可能的质心平行四边形
底线:如果任何一个正方形被完美地检测到,您就可以制作整个网格。只需沿最大 Blob 的水平轴以 2H 的间隔(H = 最大 Blob 的水平宽度)保持标记中心,并沿 Blob 的垂直轴垂直保持 2V 的间隔(V = 最大 Blob 的垂直高度)。
一些图片支持
https://stackoverflow.com/questions/14343745/