Threshold to amplify black lines

2020-07-27 03:51发布

Given an image (Like the one given below) I need to convert it into a binary image (black and white pixels only). This sounds easy enough, and I have tried with two thresholding functions. The problem is I cant get the perfect edges using either of these functions. Any help would be greatly appreciated.

The filters I have tried are, the Euclidean distance in the RGB and HSV spaces.

Sample image:

enter image description here

Here it is after running an RGB threshold filter. (40% it more artefects after this)

enter image description here

Here it is after running an HSV threshold filter. (at 30% the paths become barely visible but clearly unusable because of the noise)

enter image description here

The code I am using is pretty straightforward. Change the input image to appropriate color spaces and check the Euclidean distance with the the black color.

sqrt(R*R + G*G + B*B)

since I am comparing with black (0, 0, 0)

5条回答
▲ chillily
2楼-- · 2020-07-27 04:12

Running an adaptive threshold over the V channel in the HSV color space should produce brilliant results. Best results would come with higher than 11x11 size window, don't forget to choose a negative value for the threshold.

Adaptive thresholding basically is:

if (Pixel value + constant > Average pixel value in the window around the pixel )
    Pixel_Binary = 1;
else
    Pixel_Binary = 0;
查看更多
霸刀☆藐视天下
3楼-- · 2020-07-27 04:17

Your problem appears to be the variation in lighting over the scanned image which suggests that a locally adaptive thresholding method would give you better results.

The Sauvola method calculates the value of a binarized pixel based on the mean and standard deviation of pixels in a window of the original image. This means that if an area of the image is generally darker (or lighter) the threshold will be adjusted for that area and (likely) give you fewer dark splotches or washed-out lines in the binarized image.

http://www.mediateam.oulu.fi/publications/pdf/24.p

I also found a method by Shafait et al. that implements the Sauvola method with greater time efficiency. The drawback is that you have to compute two integral images of the original, one at 8 bits per pixel and the other potentially at 64 bits per pixel, which might present a problem with memory constraints.

http://www.dfki.uni-kl.de/~shafait/papers/Shafait-efficient-binarization-SPIE08.pdf

I haven't tried either of these methods, but they do look promising. I found Java implementations of both with a cursory Google search.

查看更多
兄弟一词,经得起流年.
4楼-- · 2020-07-27 04:17

Due to the noise and the illumination variation you may need an adaptive local thresholding, thanks to Beaker for his answer too.

Therefore, I tried the following steps:

  • Convert it to grayscale.

  • Do the mean or the median local thresholding, I used 10 for the window size and 10 for the intercept constant and got this image (smaller values might also work): image

    Please refer to : http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm if you need more information on this techniques.

  • To make sure the thresholding was working fine, I skeletonized it to see if there is a line break. This skeleton may be the one needed for further processing.

image

  • To get ride of the remaining noise you can just find the longest connected component in the skeletonized image.

Thank you.

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2020-07-27 04:23

You could try a black top-hat transform. This involves substracting the Image from the closing of the Image. I used a structural element window size of 11 and a constant threshold of 0.1 (25.5 on for a 255 scale)

You should get something like:

enter image description here

Which you can then easily threshold:

enter image description here

Best of luck.

查看更多
霸刀☆藐视天下
6楼-- · 2020-07-27 04:28

You probably want to do this as a three-step operation.

  1. use leveling, not just thresholding: Take the input and scale the intensities (gamma correct) with parameters that simply dull the mid tones, without removing the darks or the lights (your rgb threshold is too strong, for instance. you lost some of your lines).

  2. edge-detect the resulting image using a small kernel convolution (5x5 for binary images should be more than enough). Use a simple [1 2 3 2 1 ; 2 3 4 3 2 ; 3 4 5 4 3 ; 2 3 4 3 2 ; 1 2 3 2 1] kernel (normalised)

  3. threshold the resulting image. You should now have a much better binary image.

查看更多
登录 后发表回答