Python uses OpenCV to handle Sudoku problems

Source: Internet
Author: User

Original link: http://codewenda.com/python%E4%BD%BF%E7%94%A8opencv%E5%A4%84%E7%90%86sudoku%E9%97%AE%E9%A2%98/

I'm doing an interesting project: use OpenCV to resolve Sudoku from the input image (e.g., Google Goggles, etc.). I have finished the task, but in the end I found a little problem with my coming here.
I use the Python API of OpenCV 2.3.1 to program.
Here's what I did:

    1. Read the picture
    2. Find Outlines
    3. Select the area of maximum area (also a bit equal to square).
    4. Find Corner points
      For example, the following:

      Note that the Green Line is correctly aligned with the true boundaries of the Sudoku, so the Sudoku can be correctly distorted. Check the next picture)
    5. Transform an image into a perfect square
      Example Image:
    6. Perform OCR (I use the method I gave in the simple Digit recognition OCR in Opencv-python)

And this method works well.
Problem:
Check out this image.
The following results are given in step 4 of the execution of this image:

The red Line drawn is the original contour and is the true contour of the Sudoku boundary.
The Green Line drawn is an approximate contour, which will distort the image's outline.
Of course, there is a difference between a green line and a red line on the top of Sudoku. So at the moment of bending, I didn't get the primitive boundaries of Sudoku.
My question:
How do you distort the image on the correct boundary of Sudoku, the red line, or how to eliminate the difference between the red and green lines? Is there such a way in OpenCV?

Reply:

I have a solution, but you have to convert it to opencv yourself. It is written in mathematics.
The first step is to adjust the brightness in the image by dividing each pixel by the result of the close operation:

123 src =ColorConvert[Import["http://davemark.com/images/sudoku.jpg"], "Grayscale"];white = Closing[src, DiskMatrix[5]];srcAdjusted =Image[ImageData[src]/ImageData[white]]


The next step is to find the Sudoku area, so I can ignore (cloak) the background. To do this, I use the Join component analysis and select the component with the largest convex area:

12345 components =  ComponentMeasurements[    [email protected][srcAdjusted], {"ConvexArea", "Mask"}][[All,     2]];largestComponent = Image[SortBy[components, First][[-1, 2]]]


By filling in this image, I get the mask of the Sudoku grid:

1 mask =FillingTransform[largestComponent]


Now, I can use the second derivative filter to find vertical and horizontal lines in two different images:

12 lY = ImageMultiply[MorphologicalBinarize[GaussianFilter[srcAdjusted, 3, {2, 0}], {0.02, 0.05}], mask];lX = ImageMultiply[MorphologicalBinarize[GaussianFilter[srcAdjusted, 3, {0, 2}], {0.02, 0.05}], mask];


I use connection component analysis again to extract gridlines from these images. The grid line is much longer than the number, so I can use the caliper length to select the components that are only connected by the grid line. Sort by location, I get 2x10 masks for each vertical/horizontal gridline in the image:

12345678 verticalGridLineMasks =  SortBy[ComponentMeasurements[      lX, {"CaliperLength", "Centroid", "Mask"}, # > 100 &][[All,       2]], #[[2, 1]] &][[All, 3]];horizontalGridLineMasks =  SortBy[ComponentMeasurements[      lY, {"CaliperLength", "Centroid", "Mask"}, # > 100 &][[All,       2]], #[[2, 2]] &][[All, 3]];


Next, I take each pair of vertical/horizontal gridlines, enlarge them, calculate the pixel-by-node intersection, and calculate the center of the result. These points are the intersection of gridlines:

1234567 centerOfGravity[l_] := ComponentMeasurements[Image[l], "Centroid"][[1, 2]]gridCenters =  Table[centerOfGravity[    ImageData[Dilation[Image[h], DiskMatrix[2]]]*     ImageData[Dilation[Image[v], DiskMatrix[2]]]], {h,     horizontalGridLineMasks}, {v, verticalGridLineMasks}];


The final step is to define the two interpolation functions for the X/Y mapping through these points and convert the images using these features:

123456 fnX = ListInterpolation[gridCenters[[All, All, 1]]];fnY = ListInterpolation[gridCenters[[All, All, 2]]];transformed = ImageTransformation[  srcAdjusted, {fnX @@ Reverse[#], fnY @@ Reverse[#]} &, {9*50, 9*50},   PlotRange -> {{1, 10}, {1, 10}}, DataRange -> Full]


All operations are basic image processing functions, so it is also possible in OPENCV. Image transformations based on splines may be more difficult, but I don't think you really need it. It is possible to use the perspective transforms that are now used on each individual cell to give good enough results.

Code question: http://codewenda.com/topics/python/
Stackoverflow:how to remove convexity defects in a Sudoku square?

* Reprint please indicate the link of this article and the English link of StackOverflow

Python uses OpenCV to handle Sudoku problems

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.