2
votes

Here is an example of binary images, i.e. as input we have an imageByteArray with 2 possible values: 0 and 255.

Example1: enter image description here

Example2: enter image description here

The image contains some document edge on a background.

The task is to remove, decrease amount of background pixels with minimal impact on edge pixels.

The question is what modern algorithms, techniques exist to do this?

What I do not expect as an answer: use Gaussian blur to get rid of background noise, use bitonal algorithm (Canny, Sobel, etc.) thresholds or use Hough (Hough linearization goes crazy on such noise no matter what options are set)

The simplest solution is to detect all contours and filter out ones with the lowest length. This works good, but sometimes depending on an image it will also erase useful edge pixels pretty much.

Update: As input I have standard RGB image with a document (driver license ID, check, bill, credit card, ...) on some background. The main task is to detect document edges. Next steps are pretty known: greyscale, blur, Sobel binarization, Hough probabilistic, find rectangle or trapezium (if trapezium shape found then go to perspective transformation). On simple contrast backgrounds it all works fine. The reason why I am asking about noise reduction is that I have to work with thousands of backgrounds and some of them give noise no matter what options used. The noise will cause additional lines no matter how Hough is configured and additional lines may fool subsequent logic and seriously affect performance. (It is implemented in java script, no OpenCV or GPU support).

5
Is this black/white image your input image? If so, it is hard to improve the quality of imagec3R1cGFy
You could look into morphological operations, though maybe there is already too much noise to do anything sensible with morphology.hbaderts
As input I have standard RGB image, images above are the result of grayscale, blur and Sobel processing.Viacheslav Fateev

5 Answers

1
votes

It's hard to know whether this approach will work with all your images since you only provided one, but a Hough Line detection with ImageMagick and these parameters in the Terminal command-line produces this:

convert card.jpg                                               \
    \( +clone -background none -fill red -stroke red           \
       -strokewidth 2 -hough-lines 49x49+100 -write lines.mvg  \
    \) -composite hough.png

enter image description here

and the file lines.mvg contains 4 lines as follows:

# Hough line transform: 49x49+100
viewbox 0 0 1024 765
line 168.14,0 141.425,765  # 215
line 0,155.493 1024,191.252  # 226
line 0,653.606 1024,671.48  # 266
line 940.741,0 927.388,765  # 158

ImageMagick is installed on most Linux distros and is available for OSX and Windows from here.

0
votes

I assume you did mean binary image instead of bitonic...

Do flood fill based segmentation

  1. scan image for set pixels (color=255)
  2. for each set pixel create a mask/map of its area

    Just flood fill set pixels with 4 or 8 neighbor connection and count how many pixels you filled.

  3. for each filled area compute its bounding box

  4. detect edge lines

    • edge lines have rectangular bounding box so test its aspect ratio if close to square then this is not edge line
    • also too small bounding box means not an edge line
    • too small filled pixels count in comparison to bounding box bigger side size then area is also not an edge line
    • You can make this more robust if you regress line for set pixels of each area and compute the average distance between regressed line and each set pixel. If too high area is not edge line ...
  5. recolor not edge lines areas to black

    so either substract the mask from image or flood fill with black again ...

[notes]

Sometimes step #5 can mess the inside of document. In that case you do not recolor anything instead you remember all the regressed lines for edge areas. Then after whole process is done join together all lines that are parallel and close to same axis (infinite line) that should reduce to 4 big lines determining document rectangle. So now fill with black all outside pixels (by geometric approach)

0
votes

For such tasks you would usually carefully examine input data and try to figure out what cues can you utilize. But unfortunately you have provided only one example, which makes this approach pretty useless. Besides, this representation is not really comfortable to work with - have you done some preprocessing, or this is what you get as input? In first case, you may get better advice if you can show us real input.

Next, if your goal is noise reduction and not document/background segmentation - you are really limited in options. Similar to what you said, I would try to detect connected components with 255 intensity (instead of detecting contours, which can be less robust) and remove ones with small area. That may fail on certain instances.

Besides, on image you have provided you can use local statistics to suppress areas of regular noise. This will reduce background clutter if you select neighborhood size appropriately.

But again, if you are doing this for document detection - there may be more robust approaches.

For example, if you know the foreground object (driver's ID) - you can try to collect a dataset of ID images, and calculate the 'typical' color histogram - it may be rather characteristic. After that, you can backproject this histogram on input image and get either rough region of interest, or maybe even precise mask. Then you may binarize it and try to detect contours. You may try different color spaces and bin sizes to see which fits best.

If you have to work in different lighting conditions you can try to equalize histogram or do some other preprocessing to reduce color variation caused by lighting.

0
votes

Strictly answering the question for the binary image (i.e. after the harm as been made):

What seems characteristic of the edge pixels as opposed to noise is that they form (relatively) long and smooth chains.

So far I see no better way than tracing all chains of 8-connected pixels, for instance with a contour following algorithm, and detect the straight sections, for example by Douglas-Peucker simplification.

As the noise is only on the outside of the card, the outline of the blobs will have at least one "clean" section. Keep the sections that are long enough.

This may destroy the curved corners as well and actually you should look for the "smooth" paths that are long enough.

Unfortunately, I cannot advise of any specific algorithm to address that. It should probably be based on graph analysis combined to geometry (enumerating long paths in a graph and checking the local/global curvature).

As far as I know (after reading thousands related articles), this is nowhere addressed in the literature.

0
votes

None of the previous answers would really work, the only thing that can work here is a blob filter, filter it so that blobs below a certain size get deleted.