Text boxes and lines layouting in document - c++

My program is supposed to position a set of text boxes with lines in a proper manner in documents. You can find an example below:
Here's the information my program has available:
Sizes of the text boxes
Target area to which their arrow is supposed to point to.
To which point exactly in that area the arrow is pointing is not critical (center, closest border)
Now I'm looking for a layouting algorithm providing me the following information:
Where to place the text boxes
Where to attach the lines on the text boxes
Optional: Where to attach the lines on the target boxes (i.e. which exact point to point to)
Optional: Where to bend the lines
In addition to that, the following conditions should be adhered to:
Text boxes should not overlap each other or target boxes
Text boxes may overlap any other document content
Optional: minimum line length
Optional: lines should not intersect
Is there a suitable layouting algorithm for this kind of problem that I could use as a starting point?
Thanks in advance for your ideas here!

Related

Image bounding boxes from sprite sheet

I've a sprite sheet containing a set of icons as shown here:
I'd like to get the bounding box (at pixel precision) of all icons inside it, some cases like list, grid have to be considered as only one icons. Any ideas are more than welcome.
I think the main issue in your problem is that some icons contain disjoint parts.
If all the icons were in only one part, you could just find the "connected components" (groups of white pixels) in your image and isolate them.
I don't know your level in image processing but to connect the parts of one icons, I would probably use dilation, which is a morphological method to expand (under constraints) the areas of maximum intensity in an image.
If you need any clarification, please let me know !
In general, it is not possible: only the humans have enough context to determine which of the disjoint parts belong together. You can approximate it using various ways, but it's a lost cause - and IMHO completely unnecessary. Imagine writing a test for this functionality - it's impossible, it requires a human in the loop, since the results for any particular icon sheet don't generalize. Knowing that the algorithm works for some sheet tells you nothing about whether it will work for some other sheet that you know nothing about a-priori.
It'd be simpler to manually colorize each sprite to have a color different than that of its neighbors. Then a greedy algorithm could find the bounding boxes easily without having to approximate anything.

OpenCV: Ignore text-like contours

Background
I want to detect all contours in an image that contains 2D geometric shapes, but strip away anything that looks like text.
Example input:
I tried to detect text areas via Tesseract and remove those text areas subsequently. For some images where the OCR recognition is good this works fine, thus text areas are recognized with quite good rate and contours of recognized text can then be removed. But for most images the text is not recognized well and thus I cannot remove irrelevant text contours from the image.
Therefore my question is: How can I distinguish text-like contours from my 2D "geometric" contours?
If you don't care about the text and just want to get rid of it, then you can just detect outer contours by passing RETR_EXTERNAL as the mode parameter to the findCountours() function. That will give you the outermost contours and ignore anything contained inside of the geometric shapes.
Or if you want more control, you can pass the mode parameter as RETR_TREE and then walk the tree, keeping only the top-level contours and ignoring anything below that level in the hierarchy. That way you'll get everything and you can decide later what you want to keep and what you want to ignore.
Read this page of the OpenCV documentation for information on how findCountours() represents the hierarchy (that page is from a python tutorial, but it's generic enough to follow along).
Of course that will only work if the images always look similar to the example you gave in your question - i.e. the text is always inside of the geometric shapes. If you have text outside of the shapes, then maybe you could look at the size of the contours (bounding rectangles) and ignore anything that falls below a certain threshhold (assuming text contours will be much smaller than your geometric shapes).
Contours that belong to text, also represent a region according to your example. So that you can try to use the properties of regions to eliminate some unneeded regions (text contours!) I can suggest that you can use some properties like eccentricity, solidity or compactness (you can find code example here: https://github.com/mribrahim/Blob-Detection
)
For ex: Regular shapes and the others can be distinguished by using compactness value, or you can combine any other properties

Minimum distance between markers

Each red circle in this map is a point but due to the density of them, there isn't enough space to show the text labels for all of them. So I want to filter them down to just show those which can show a text label.
How can I do this? marker-spacing seemed to be promising but makes no difference. I see no "marker-min-distance" as there is with "text-min-distance".
Basically there's no point in showing a marker at all if it can't be identified with text. This is for a non-interactive offline map.
There is marker-spacing.
If you want to draw only labelled markers, use shields instead (answered here).

I have a large list of bounding boxes, how can I calculate duplicates?

I have a list of bounding boxes, I was wondering how I could calculate which ones were redundant / duplicates.
The reason being is I have 2 million of these I send to a API and I want to know which are overlapping others so I can reduce them down so each box only covers a unique area of land, so no two bounding boxes cover the same piece of geo space.
How would I calculate it so that these bounding boxes were each covering their own unique space of geo land ?
I am writing this program in C++ btw.
I think that this task is more complex then you think.
You would have to split existing boxes, untill no overlapping exists, and then remove the boxes totally contained in another.
Instead giving you a solution to that, I recomend to check if you can live with:
1) remove the boxes that are totally contained in another box.
2) leave (partly-)overlapping boxes as they are.
For 2 millions you need a spatial index (QuadTree), to get a list of all boxes nearby one box.
If you have to avoid any overlappings, then you must continue to think what should be the result?
A) A union of overlapping rectangles that therfore is not an rectangle anymore, but a polygon.
or B) The result should be rectangles.
You could check if X% of a box's vertices are inside another box to find if it's overlapped but I suppose this isn't the optimal solution.

Counting objects on a grid with OpenCV

I'm relatively new to OpenCV, and I'm working on a project where I need to count the number of objects on a grid. the grid is the background of the image, and there's either an object in each space or there isn't; I need to count the number present, and I don't really know where to start. I've searched here and other places, but can't seem to find what I'm looking for. I will need to be tracking the space numbers of the grid in the future, so I will also eventually need to know whether each grid space is occupied or empty. I'm not going so far as to ask for a coded example, but does anybody know of any source or tutorials to accomplish this task or one similar to it? Thanks for your help!
Further Details: images will come from a stable-mounted camera, objects are of relatively uniform shape, but varying size and color.
I would first answer a few questions:
Will an object be completely enclosed in a grid cell? Or can it be placed on top of a grid line? (In other words, will the object hide a line from the camera?)
Will more than one object be in one cell?
Can an object occupy more than one cell? (closely related to question 1)
Given reasonable answers to those questions, I believe the problem can be broken into two parts: first, identify the centers of each grid space. To count objects, you can then sample that region to see if anything "not background" is there.
You can then assume that a grid space is defined by four strong, regularly-placed, corner features. (For the sake of discussion, I'll assume you've performed the initial image preparation as needed: histogram equalization, gaussian blur for noise reduction, etc.) From there, you might try some of OpenCV's methods for finding corners (Harris corner detector, cvGoodFeaturesToTrack, etc). It's likely that you can borrow some of the techniques found in OpenCV's square finding example (samples/c/square.c). For this task, it's probably sufficient to assume that the grid center is just the centroid of each set of "adjacent" (or sufficiently near) corners.
Alternatively, you might use the Hough transform to identify the principal horizontal and vertical lines in the image. You can then determine the intersection points to identify the extents of each grid cell. This implementation might be more challenging since inferring structure (or adjacency) from "nearby" vertices in order to find a grid center seems more difficult.