Search code examples
opencvimage-processingsudokuthresholdsobel

Otsu Thresholding on a Sobel Filtered Image gives different Results


I'm creating a Sudoku solving application on an Android platform and I've run into an issue when processing the image. I'm trying to find the horizontal lines of the puzzle using OpenCV using a Sobel filter and then thresholding with the Otsu algorithm:

Mat kernaly = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,2));
Mat dy = new Mat();
Mat close = new Mat();
Imgproc.Sobel(img, dy, CvType.CV_16S, 0, 2);
Core.convertScaleAbs(dy, dy);
Core.normalize(dy,dy,0,255,Core.NORM_MINMAX);
Imgproc.threshold(dy, close, 0, 255, Imgproc.THRESH_BINARY|Imgproc.THRESH_OTSU);
Imgproc.morphologyEx(close, close, Imgproc.MORPH_DILATE, kernaly);

This method actually works well for most images, for example:

enter image description here

However, it fails for the following image:

enter image description here

Can someone explain why the results are so vastly different and the second image above returns only one line? Also, should I just use another methodology instead, such as Canny or Hough lines?

Thanks in advance!


Edit: Using marol's advice, I tried removing as much of the black border as possible without having to warp the image. This is the result when applying the same process above to these reworked images.

Image 1:

Image 1

Image 2:

Image 2

As you can see, the results are better as most lines have been detected. However, it's still not good enough. It can be improved by adding in a fixed threshold but that has to be different for each image.

I'll probably just use a new approach as this method does not seem to be robust enough. Any tips will be greatly appreciated.


Solution

  • I found a quick fix that improves the results quite significantly by doing some image processing before running the code above:

    1. I just did as marol suggested above and cut as much of the black border out as possible.
    2. Resized the images, using warpPerspective, so that it became a square of a standard size.
    3. Ran the code above and then dilated the result.

    Its not the most robust solution but it works for all 10 of my test image samples.