我正在做一个有趣的项目:使用OpenCV从输入图像中解决数独(如Google护目镜等).我完成了任务,但最后我发现了一个问题,我来到这里.
我使用OpenCV 2.3.1的Python API进行编程.
以下是我的所作所为:
找到角点.
例如,如下:

(请注意,绿线正确地与Sudoku的真实边界重合,因此可以正确扭曲数独.查看下一张图片)
将图像扭曲成完美的正方形
例如:

执行OCR(我使用我在OpenCV-Python中的简单数字识别OCR中给出的方法)
而且方法效果很好.
问题:
看看这个图像.
在此图像上执行第4步,结果如下:

绘制的红线是原始轮廓,它是数独边界的真实轮廓.
绘制的绿线是近似轮廓,它将是扭曲图像的轮廓.
当然,在数独的上边缘绿线和红线之间存在差异.因此,在翘曲时,我没有得到数独的原始边界.
我的问题 :
如何在数独的正确边界上扭曲图像,即红线,或者如何消除红线和绿线之间的差异?在OpenCV中有没有这方法?
如何对此模糊图像进行阈值处理以使数字尽可能清晰?
在上一篇文章中,我尝试自适应地对模糊图像进行阈值处理(左图),这会导致数字失真和断开(右图):

从那时起,我已经使用如所描述的形态学闭运算试图此篇使图像均匀的亮度:

如果我自适应地对此图像进行阈值处理,则不会获得明显更好的结果.但是,由于亮度大致均匀,我现在可以使用普通阈值:

这比以前好多了,但我有两个问题:
我认为回到自适应阈值,但是具有非常大的块大小(图像的1/9)将解决这两个问题.相反,我最终得到一个奇怪的"光环效应",其中图像的中心更亮,但边缘与正常阈值图像大致相同:

编辑:remi 建议在形态上打开这篇文章右上角的阈值图像.这不太好用.使用椭圆内核,只有3x3足够小,以避免完全消除图像,即使这样,数字也会有明显的破损:

Edit2:mmgp 建议使用维纳滤镜来消除模糊.我将此代码用于OpenCV中的Wiener过滤到OpenCV4Android,但它使图像更加模糊!这是使用我的代码和5x5内核过滤之前(左)和之后的图像:

这是我改编的代码,它就地过滤:
private void wiener(Mat input, int nRows, int nCols) { // I tried nRows=5 and nCols=5
Mat localMean = new Mat(input.rows(), input.cols(), input.type());
Mat temp = new Mat(input.rows(), input.cols(), input.type());
Mat temp2 = new Mat(input.rows(), input.cols(), input.type());
// Create the kernel for convolution: a constant matrix with nRows rows
// and nCols cols, normalized so that the sum of the …Run Code Online (Sandbox Code Playgroud)