用什么方法解决这个数独?

首先要明确我们的任务。要想解数独,需要进行计算,图片格式的数字肯定是不行的,所以必须把图片上的数字转换为实实在在的数字才能进行计算。要得到实实在在的数字,我们需要做的是对图片上的数字进行提取和识别。本文先说第一步,图片中数字的提取。

在一年之前,我曾用 C++ 尝试过 opencv 解数独,但由于当时水平有限,未能完成。当时的成果就是透视变换的应用和方格数字的提取。现在稍微简化一下工作,不再从倾斜的数独图片中提取数独,而是直接用正拍且已经提取好的数独开始处理。这里用到的数独图片如下图所示:

从上图这样的九宫格图片中提取数字,我以前用的方法是,先利用轮廓提取,通过轮廓的面积进行筛选,得到所有的81个小方格;然后对检测小方格中是否有黑色像素以及像素的多少(排除噪音)来判定哪个小方格中有数字;最后对有数字的小方格再次进行轮廓提取得到数字的轮廓和轮廓外包矩形。

此方法实现起来相对来说比较麻烦,思路仅供参考。

在仔细研究了 opencv 轮廓提取函数findContours()之后,发现利用轮廓的层级结构会更加简单。作为本节最主要的函数,有必要稍微多说几句。

1.image 源图像,一般为8为单通道图像,更具体来说,二值图像。其他情况暂且不论。

2.mode 轮廓检索模式,简要介绍几种:

  • cv2.RETR_LIST 提取所有轮廓,并放置在list中,检测到的轮廓不建立等级关系。
  • cv2.RETR_TREE 提取所有轮廓,建立网状的轮廓结构。

3.method 轮廓的近似办法,是提取轮廓上所有像素点,还是只提取关键的一些点。比如一条线段是提取所有点还是只提取两个端点。

4.contours 检测到的轮廓,为组成轮廓的点集。

什么是层级结构呢?我们检测轮廓的时候,有时候可能会出现其中一个轮廓包含了另外一个轮廓,比如同心圆。这里我们认为外侧轮廓为父轮廓,内侧被包含的为子轮廓。同一级别的又有前一个轮廓后一个轮廓。总的来说,hierarchy表达的是不同轮廓之间的 关系和联系。

上面说到,cv2.RETR_EXTERNAL 只检测外轮廓。对所有轮廓设置hierarchy[i][2]=hierarchy[i][3]=-1。由于只检测最外围轮廓,所有检测到的轮廓肯定没有父轮廓和子轮廓,所有层级结构的第三个和第四个元素都设置为-1。

如果只检测最外围轮廓,那么只会检测到轮廓012

如果建立层级关系,以轮廓3为例,那么它的父轮廓是2a,子轮廓是3a,没有前一轮廓和后一轮廓,设为-1。所以它的hierarchy应该是[-1,-1,3a,2a]

如果是轮廓2,那么它的前一轮廓就是1,子轮廓是2a,没有后一轮廓和父轮廓。所以它的hierarchy应该是[-1,1,2a,-1]

有兴趣的可以仔细看看,没兴趣的可以略过。兴趣更浓的可以去看opencv文档,那里的讲解更加详细。

这里就说这么多,对于我们本节的内容来说,已经够了。

我觉得大部分人这个时候还会问,上面说了这么一堆到底是要干什么???因为这里确实不是那么清晰明了。

别忘了我们本节的目的是要提取数字,什么样的轮廓包含数字?

一般来说经过前面的阈值分割得到二值图像,然后从二值图像中提取的轮廓是这样的。这是处理的比较好的情况下:

显然最最外面的那个包围所有的就是0号轮廓,里面的九九八十一个小方格就是0号轮廓的子轮廓。而每一个已知数字的轮廓都是对应方格的子轮廓。

所有我们的办法就是先提取方格,然后提取数字。

八十一个小方格有什么特点?父轮廓都是0号轮廓!所以:

不记得的可以上翻看一下hierarchy是不是第四个元素表示父轮廓。

然后从小方格中提取数字轮廓。数字轮廓的有什么特点?其父轮廓有子轮廓,也即是说包含子轮廓的小方格里面就有数字。所以:

不记得的可以上翻看一下hierarchy是不是第三个元素表示子轮廓。不等于-1表示存在。

最后把检测到的数字画出来就可以得到下面的这幅图了。

## 对二值图像执行膨胀操作 ## 提取小方格,其父轮廓都为0号轮廓 ## 提取数字,其父轮廓都存在子轮廓

数字已经提取出来,下一步就该是数字的识别了......



亲爱的小朋友,你好!我是朱乐平名师工作站的王丽君老师。

今天与你来分享数独的知识。

准备好了吗?我们开始吧!

在下面的方格中,每行每列都有1-4这四个数,并且每个数在每行每列都只出现一次,A应该填几?

爱动脑筋的小朋友,你愿意和小天一起解决这个问题吗?

我们可以这样想:A所在的行和列已经出现了哪些不同的数,这样就能确定这个空格填的数。

A所在的行和列已经出现了1,2,3,所以A只能填4。

爷爷!爷爷!小朋友和我的解答对不对呀?

对的,对的!你们可真棒!

这是四宫格,最常见的数独是九宫格,你们看!

数独中每行、每列、每一宫内的数字为1-9且不重复!

小朋友们,你想先填哪里?

爷爷!爷爷!我想先填第5宫的E5格。

因为这个宫剩下的数最少,最容易确定!

原来要从已知数较多的行列宫开始填,排除已知的数,剩下的就是答案。

我们可以这样想:第4列,第6列,D行,F 行都只剩下两个数没填,所以我们可选择其中一个进行解题。

第4列还剩下4和7两个数字。由于G行以及第八宫都出现了数字4,所以G4不能填4,只能填7,因此C4就是4。

通过行、列、宫里已知的数进行排除,是最常用的数独方法!

在这个数独里,E5是几呢?

E5是6,因为它所在的行列已经出现了9个数中的8个不同的数,还剩6,根据规则,E5不能重复已经出现过的数,所以E5是6。

只要仔细全面地观察数独的行列宫,利用排除法依据数独规则解题,数独也没有那么难呢!

有兴趣的同学可以尝试用上面的方法解开这个数独剩下的数哦!

       我们来回顾一下今天研究的“数独,你玩得转吗?”。我们知道了用排除法(通过行、列、宫排除)可以解决大部分的数独问题!

快乐的时光总是很短暂~

把你今天的收获和小伙伴们分享一下吧!

美妙数学天天见,每天进步一点点。亲爱的小朋友,今天的话题我们就讲到这里,咱们明天再见!

聪明出于勤奋,天才在于积累。

求解数独直观法问题的技巧主要有唯一解法、基本块法、块块法、唯余解法、矩形块法、单元块法、剩余测试法等。 数独解法都是由规则派生出来的。 基本解法分为两种思路,一种是排除法,另一种是唯一法。 更复杂的解法,最终也归结为这两个范畴。

基本块法是利用1~9的数字每行、列、九宫格只出现一次的规则来解决问题的方法。 基本块法可分为行块、列块、九宫格块。

当某行填写数字的宫格达到8个时,该行剩下的宫格可以填写的数字只有还没有出现的数字。 成为唯一的解。

唯余解法是,某个宫格可以追加的数已经排除了8个,所以这个宫格的数字只能追加那个没有出现的数字。

分块分块法是基础分块法的改进方法,是直观法中使用频率最高的方法之一。 分块是指将行分成3个相连的小方块来构成,列也分成3个相连的小方块来构成。 九宫格也被认为同样由三个相连的小方块构成。 如下图所示,块-块方法的核心思想解释如下,行也是如此。

当某个小九宫格中已经有三个数字的行时,这三个数字的行就叫“支撑”。 此时,在该行的另外两个小九宫格上的另外两行中寻找该小九宫格中没有的数字,将其数量的位置称为“点”。 那么,“点”的数字在有“支撑”的九宫格中一定位于与有“支撑”和“点”的行不同的行。 另外,“点”的数字在“支撑”和“点”以外的其他九宫格中位于“支撑”所在的行。

剩余测试法是指,在某行或列中记入九宫格的数字较多,在剩下的2个或3个时,对剩下的宫格进行赋值测试的方法。

候补数法解决问题的过程是指排除不合适的候补数的过程。 当某宫格的候补数只排除在一个数上时,该数是该宫格的唯一候补数,该候补数可以求解。

找到某列、某行或某九宫格中某三个宫格候补数中不同数字为三个以下的情况,并从其他宫格候补数中删除这三个数字的方法称为三链数删除法。 隐藏三链数削减法:在某一行中,3个数字出现在同一宫格内,本行其他宫格中不包含这3个数字。 这个数被称为看不见的三链数。 这三个宫格的候补数中,其他数字都可以排除。

如果某个候选数在某两行中只出现在相同的两列中,则该候选数可以从该两列中的其他小区中删除。 可替换地,如果某个备选数字在某两列中仅出现在相同的两行中,则可以从该两行中的其它小区中删除该备选数字。

我要回帖

更多关于 困难的数独怎么解 的文章

 

随机推荐