OpenCV: the formation of points from the image after thinning

I ran into the problem of creating floating point coordinates from an image.

The initial problem is this: the input image is handwritten text. From this I want to create a set of points (only x, y coordinates) that make up individual characters.

At first I used findContours to create points. Since this finds edges of characters, you first need to start the decimation algorithm, since I am not interested in the shape of the characters, indicate only strings, or as in this case.

Input:

input

thinning:

thinning

So, I run my input through the thinning algorithm, and everything is fine, the output looks good. Running findContours on this, however, is not so good, it skips a lot of things, and I get something unusable.

The second idea was to create bounding fields (using findContours) using these bounding fields to capture characters from the thinning process and capture all non-white pixel indices as โ€œdotsโ€ and shift them to the bounding box position. This creates an even worse result and seems like a bad method.

Awful code for this:

Mat temp = new Mat(edges, bb); byte roi_buff[] = new byte[(int) (temp.total() * temp.channels())]; temp.get(0, 0, roi_buff); int COLS = temp.cols(); List<Point> preArrayList = new ArrayList<Point>(); for(int i = 0; i < roi_buff.length; i++) { if(roi_buff[i] != 0) { Point tempP = bb.tl(); tempP.x += i%COLS; tempP.y += i/COLS; preArrayList.add(tempP); } } 

Are there any alternatives or am I missing something?

UPDATE:

I overlooked the fact that I needed dots (pixels) to order. In the above method, I just use the scanline method to capture all the pixels. If you look, for example, at "o", he will first take a point on the left side, then one on the right side. I need neighboring pixels to order them, since I want to draw paths with dots later (outside of opencv). Is it possible?

+4
source share
1 answer

You should learn how to implement your own related components. The concept is very simple: you look at the first line and assign unique labels to each horizontally connected pixel strip. You basically check each pixel if it is connected to its left neighbor and assigns it either a neighboring label or a new label. In the second line, you do the same, but you also check the pixels above it. Sometimes you need to merge labels: two lines that were not connected in the previous line are joined in the current line. The way to handle this is to either save the list of label equivalents, or use pointers for labels (so you can easily complete a complete label change for an object).

This is basically what findContours does, but if you implement it yourself, you have the freedom to go 8-connected and even bridge a single-pixel or two-pixel gap. This way you get a โ€œcomponent-tagged component label.โ€ It looks like you need this for the "w" in your example.

Once you have an image marked this way, you can click all the pixels of the same label on the vector and order them something like this. Find the top left pixel, push it to a new vector and remove it from the original vector. Now find the pixel in the original vector closest to it, click on the new vector and remove it from the original. Continue until all pixels are migrated.

It will not be so fast, but it should be the beginning.

+1
source

Source: https://habr.com/ru/post/1491495/


All Articles