本文方向
就是想通过一张照片检测魔方是否还原,整个CSDN上找不到方法,经过探索,找到了一个还算靠谱的方法,在这里介绍给大家,同时也讲讲我当时的心路历程,测试过但最终放弃的一些方法,如果网友们有改进方案,欢迎评论,最后的方法比较鲁棒,但是背景过于复杂时误差比较大,这是由于HSV颜色空间本身具有不稳定性,比如红色和棕色的区域在一起,而我们有的时候(测试图片)的背景板就是棕色的,通过颜色空间并无法区别。
本文操作环境:win10+opencv3.4.1+vs2017,语言:C++
原图如下(当然我测试了五十张)效果不一
前后思路
1.计数色块数量
首先,我想到的是数不同颜色色块的个数,这样做首先是要提取色块,实际上要做到比较稳定的提取色块极其的困难,尤其是对于有些测试图片的侧面很小,很多颜色的色块很小,容易两块相邻的混在一起,干扰计数,其次,我采用先针对一个颜色,提取所有色块并用findcontours()函数找到轮廓,然后用sizeof(),得出轮廓的数量,如果照片范围内的轮廓数量等于9或等于0,则测试下一种颜色,知道一种颜色色块数量属于0~9,则可以判断未还原,如果全是0或9,则还原。
思路是没什么问题,测试过程却不是很顺利,首先是色块的提取,有两种方案,一是在原图取阈值大约150左右的定阈值(自适应阈值试过效果很差),这个值是我创建滑动条对多张图片测试得到的,在得到的二值图中提取轮廓,用函数中的参量选RETR_TREE,拿到魔方的大轮廓,然后把大轮廓用矩形(不用旋转矩形)框出来作为感兴趣区域,在原图对ROI进行分析,这样基本可以去除背景只对魔方分析,在ROI内用inrange函数(这个函数是所有方法的核心),可以直接把对应的颜色提取出来得到二值图,然后进行findcontours并计数轮廓
各个颜色的范围测试如下,橙色红色经常混,但蓝绿黄很清晰
inRange(imgHSV, Scalar(90, 43,46 ), Scalar(125, 255, 255), imgThresholded1); /*判断九个块是否有 **蓝色** */
inRange(imgHSV, Scalar(