OpenCV
Published:
该程序可以提取魔方各个面的颜色分布,下面是一个展示视频:
魔方图片:
边缘检测
第一步是加载图像,使其变灰,稍微模糊,然后使用Canny边缘检测来定位所有边缘。
self.image = cv2.imread(filename)
gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
canny = cv2.Canny(blurred, 20, 40)
扩张
下一步是稍微扩张线条,使得线条更粗,从而更容易找到正方形的轮廓。
kernel = np.ones((3,3), np.uint8)
dilated = cv2.dilate(canny, kernel, iterations=2)
轮廓
每个正方形周围都有漂亮的粗线,Opencv能够在图像中找到所有的轮廓
(contours, hierarchy) = cv2.findContours(dilated.copy(),
cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
轮廓近似
我们需要降低轮廓形状的复杂型。我们可以通过opencv的 approxPolyDP做到这一点,简而言之,它近似于轮廓的形状。在下面的图像中,轮廓再次为蓝色,但它们的近似值为红色。
正方形轮廓的近似值
在计算哪些是正方形方面,近似值看起来更容易使用。我们查看每个近似值,并使用以下三条规则来确定它是否是一个正方形: 1、一定有四个角落 2、所有四行的长度必须大致相同 3、所有四个角落必须大约90度 在下面的图像中,如果该等高线的近似值符合我们作为正方形的规则,则该等高线是绿色而不是蓝色。
在这一点上,我们可以消除所有不是正方形的轮廓,这些轮廓会清理很多东西
正方形内的正方形
消除这些外部方块,这给我们留下了:
立方体尺寸和边界
我们现在可以分析剩余的轮廓,并找出两个关键信息 1、我们正在处理一个4x4x4立方体 2、我们可以找到立方体的边界 既然我们知道立方体的边界,我们可以扔掉边界之外的任何轮廓,这给我们留下了
处理错误
有时立方体的正方形有凹痕,或者贴纸正在剥落,或者有一些非常糟糕的眩光,或者它在阴影中,或者其他的一些问题,使得轮廓近似失败了,不满足规则之一“它是一个正方形吗”,而实际上它是一个正方形。这发生在下面的图像中,第3行第5列的正方形有一个看起来不像正方形的轮廓。在这里,我们看到近似值是一个三角形,所以它显然没有通过“必须有四个角”的检查。
首先确定这是一个6x6x6的立方体,而且我们缺少一个方块
然后,我们查看立方体边界内的所有非正方形轮廓,看看它们是否位于第3行的6个正方形的位置。下面黄色的轮廓(浅蓝色的近似值)满足了该条件。
颜色提取
一旦我们处理了所有六边的图像,我们就会得到每个正方形的RGB(红色,绿色蓝色)值。我们示例中的4x4x4图像是下面立方体中的F面,显示的颜色是从图像中提取的平均RGB值。注意有多少变化……40比17深一点,但这些都是黄色的正方形。