Wanted to achieve something like this: http://www.leptonica.com/binarization.html
While searching for solutions, most of the answers were general instructions such as advise to look at adaptive filter, gaussian blur, dilation and erosion but none of them provide any sample code to start with (so can play around with the values)..
I know different image require different methods and values to achieve optimum clarity, but I just need some general filter so that the image at least slightly sharper and less noisy compare to the original, before doing any OCR on it.
this is what I've tried so far..
Mat imageMat = new Mat();
Utils.bitmapToMat(photo, imageMat);
Imgproc.cvtColor(imageMat, imageMat, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(imageMat, imageMat, new Size(3, 3), 0);
Imgproc.adaptiveThreshold(imageMat, imageMat, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 5, 4);
but being an image processing newb, obviously I don't know what I'm doing XD
original image:
after applying the above:
How to do it correctly?
UPDATE: got it much closer thanks to metsburg, berak and Aurelius
Using the medianBlur method since cvSmooth with CV_MEDIAN is deprecated and replaced with medianBlur:
Imgproc.medianBlur(imageMat, imageMat, 3);
Imgproc.threshold(imageMat, imageMat, 0, 255, Imgproc.THRESH_OTSU);
Result:
Using back the GaussianBlur method, the result actually is slightly better:
Imgproc.GaussianBlur(imageMat, imageMat, new Size(3, 3), 0);
Imgproc.threshold(imageMat, imageMat, 0, 255, Imgproc.THRESH_OTSU);
Result:
For this image the difference is not noticable, so I tried another image which is a photo taken off the computer screen. Computer screen gives a lot of noises (wavy lines) so it is very hard to remove the noise.
Example original image:
Directly applying otsu:
using medianBlur before otsu:
using GaussianBlur before otsu:
Seems like gaussian blur is slightly better, however I'm still playing with the settings.. If anyone can advise on how to improve the computer screen photo further, please, let us know :) One more thing.. using this method on the image inside the top link yields horrible results :( see it here: http://imgur.com/vOZAaE0
You use a Gaussian smoothing filter and subtract the smoothed version from the original image (in a weighted way so the values of a constant area remain constant). cv::GaussianBlur(frame, image, cv::Size(0, 0), 3); cv::addWeighted(frame, 1.5, image, -0.5, 0, image);
You can also sharpen an image with a 2D-convolution kernel. First define a custom 2D kernel, and then use the filter2D() function to apply the convolution operation to the image. In the code below, the 3×3 kernel defines a sharpening kernel. Check out this resource to learn more about commonly used kernels.
Try first using cv2. resize and standard interpolation algorithms (and time how long the resizing takes). Then, run the same operation, but instead swap in OpenCV's super resolution module (and again, time how long the resizing takes).
To sharpen an image in Python, we are required to make use of the filter2D() method. This method takes in several arguments, 3 of which are very important. The arguments to be passed in are as follows: src: This is the source image, i.e., the image that will undergo sharpening.
Well, you're almost there. Just try these modifications:
Instead of
Imgproc.GaussianBlur(imageMat, imageMat, new Size(3, 3), 0);
try:
cvSmooth(imageMat, imageMat, CV_MEDIAN, new Size(3, 3), 0);
check the syntax, may not exactly match
The link you posted uses thresholding of Otsu, so try this:
Imgproc.threshold(imageMat, imageMat, 0, 255, Imgproc.THRESH_OTSU);
for thresholding.
Try tweaking the parameters here and there, you should get something pretty close to your desired outcome.
Instead of using Imgproc.THRESH_BINARY_INV
use Imgproc.THRESH_BINARY
only as _INV is inverting your image after binarisations and resulted is the said output shown above in your example.
correct code:
Imgproc.adaptiveThreshold(imageMat, imageMat, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 5, 4);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With