What I want to do is adjust the transparency of every pixel in a picture according to its ink ratio. I will take an example:
A node-link graph
In this picture, I want to calculate every pixel's ink ratio(That is, the ratio of the part covered by the line in each pixel to the size of the entire pixel).
Then assign a transparency value to each pixel according to this ratio, the higher the ratio is, the lower the transparency.
Finally,rendering the picture.
But now I don't know how to achieve it. Can someone help me or give me some advice to solve it? I will be very grateful!
I have very limited experience with any kind of image processing so these ideas may be far too simplistic to help.
In the simplest case if you are working on some kind of raw data AND with a single colour background (e.g. black line on white background) then any pixel values diverging from the background pixel value represent one or more lines passing through the pixel.
If this is not the case I think it's down to lots of calculations.
I suggest that first you have to calculate which pixels are covered in part or whole by one or more lines which depends on the line width and direction. I assume that the length and direction of each line is known so you can calculate one or more lines that
represent the boundaries of the line and use those to give the affected pixels.
Now it's necessary to calculate the proportion of the pixel that is covered by the total line i.e. the part of the pixel that lies between the calculated line boundaries. At this point I leave it to you - but I visualise a pixel as a square of known position and dimensions with a boundary line passing through it at known points to cut off a triangle or, for a horizontal or vertical line, a rectangle either within the line boundary or outside it.
Again - this assumes that the line width is greater than the diagonal of the pixel - if that is not so the calculation has to be done for both boundary lines.
That deals with one line passing through the pixel but of course multiple lines may have to be considered and the resultant value calculated.
If this is too simplistic and I have not understood the problem correctly I apologise.
Related
I have a binary which has some text on different parts of the image like at the bottom, top, center, right middle center, etc.
Original Image
The areas I would like to focus on are the manually drawn regions shown in red.
I calculated the horizontal and vertical summations of the image and plotted them:
plot(sum(edgedImage1,1))
plot(sum(edgedImage1,2))
Can somebody give me explanation of what these plots are telling me about the original image with regards to the structure of which I explained above?
Moreover, how could these plots help me extracting those regions I just manually drew in red?
There's nothing sophisticated about the sum operation. Simply put, sum(edgedImage1,1) computes the sum of all rows for each column in the image and that is what you are plotting. Effectively, you are computing the sum of all non-zero values (i.e. white pixels) over all rows for each column. The horizontal axis in the plot denotes what row's sum you are observing. Similarly, sum(edgedImage,2) computes the sum of all columns for each row of the image and that is what you are plotting.
Because your text is displayed in a horizontal fashion, sum(edgeImage,1) won't be particularly useful. What is very useful is the sum(edgedImage,2) operation. For lines in your image that are blank, the horizontal sum of columns for each row of your image should be a very small value whereas for lines in your image that contain text or strokes, the sum should be quite large. A good example of what I'm talking about is seen towards the bottom of your image. If you consult between rows 600 and 700, you see a huge spike in your plot as there is a lot of text that is surrounded between those rows.
Using this result, a crude way to determine what areas in your image that contain text or strokes in your case would be to find all rows that surpass some threshold. Combined with finding modes or peaks from the sum operation that was just performed, you can very easily localize and separate out each region of text.
You may want to smooth the curve provided by sum(edgedImage,2) if you decide to determine how many blobs of text there are. Once you smooth out this signal, you will clearly see that there are 5 modes corresponding to 5 lines of text.
The second plot that shows the sum of each row. This can tell you in which rows you have a lot of information and in which you have none.
You can use this plot to find the rectangles by looking for a sharp incline in the value for a start of a rectangle and sharp decline in the value for the end of the rectangle. Before you do it i would low pass filter the data and then look at the derivative of this and look for a big derivative.
You can do the same the first plot but it is more sensitive.
The minimums in your last plot are the gaps between lines of text ...
You just take the graph and align its y axis to y axis of image and then Threshold areas with too small amount of pixels per column. These areas (Red) are the gaps between lines of Text or whatever you got on the image:
Now you should de-skew the image if needed. If the skew is too big you need to apply the de-skew even before the y axis summation.
De-skew operation characters in binary image (matlab)
After this you make the x axis summation plot for each non red region separately and in the same manner detect gaps between characters/words to get the area of each character for OCR. This time you align to x axis
These plots can be also used to OCR if taken on character region instead see
OCR and character similarity
If you do a statistical analysis of the gap/non gap sizes then the most recurrent one is usually the Font spacing/size for regular text.
My requirement is to find the inclination of the lines (all 8 lines) surrounding the data matrix, as shown in the edge detected image:
The two main restrictions:
The inclination detected should have precision of at least 0.1 deg (the best achievable in this image)
Time taken should be less than 30 ms
I am implementing the algo on a Blackfin DSP, and have used Blackfin image processing toolbox.
I tried using Hough transform and Contour detection to find out the lines and thus their inclinations however the time limit exceeds. Any suggestions to use a different algorithm or optimize this one would help.
[for my use case the higher the angle precision the better, I am targeting at least 0.02 - 0.05 with a higher resolution image]
find bounding box
scan all points and found xmin,ymin,xmax,ymax of set pixels
find the gaps
cast scan lines through half of bounding box remembering/measure the gap sizes. To avoid line miss (due to holes) you can cast more scan lines or scan with wider ray.
If you need some examples for ray cast/scanning see:
How to find horizon line efficiently in a high-altitude photo?
segmentate the image into regions
just shrink bounding box by some fraction (50%) of a gap ... something like this:
forming 8 rectangular regions each one with single line without noise from the edges.
regress/fit lines
The idea is to make a list of all set pixels for each region separately and fit a line that has smallest distance to all of them.
I would try to use this:
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line
Or use approximation search and fit something like
Curve fitting with y points on repeated x positions
just ignore the curvature and fit line equation parameters directly instead cubics.
After the lines are fitted you can compute their slope directly by atan2(dy,dx)
A fast and easy approch would be to scan every line and column for the first and second white pixel starting from left, right, top and bottom. Then simply use some robust line fit algorithm to get the lines.
Unless you did not already try to do that you can reduce the data for Hough transform or other algorithms by cropping the image down to DMC size.
The required angle accuracy cannot be achieved as you don't have enough resultion. And even if you had your results would suffer from any noise and outliers.
Im a novice when it comes to computer graphics.Im trying to learn Bresenham's Scanline algorithm.
It says Pixels positions along a Line are determined by sampling at unit X intervals What exactly does this sampling mean,in layman's terms.
Then it says Plot the pixel whose scan line value is closest to the line path
What exactly is this scanline value? How is this computed ,again in layman's terms please.
Look at the wiki picture for Bresenham algo.
Every horizontal row of pixels is scanline (term from old time raster printers and tube monitors). Sampling denotes using individual pixels' coordinates of every (scan)line. For example, if target graphic context has dimensions 1920x1080, there are 1920 pixels in scanline with X-coordinates 0..1919, and we do sampling (choose coloured pixels) for these integer coordinates.
Note - line is contiguous math concept, but pixels are discrete.
Colored pixels are closer to the line than pixels with the same Y but from other scanlines
Sampling: Mathematically, a line is a continous (smooth) function. In raster graphics you have just a few pixels. So you need to represent (draw) such a line using a few pixels only. Sampling means to use the functions value at a few distinct points (instead of infinite many points).
Scanline: In this case the y value of the pixel. The term comes from the old CRT monitors where pictures are build from electron beams which followed a line pattern from left to right, one line after the next. The beam "scanned" these lines.
i'm searching for the fastest way to find one or more reference points, (could be +, or a rectangle).
My first idea is, to go from the mid point of the image and look iterative in all 4 directions for the coloured pixels. But in this case it is not clear for me how to handle a symbol like + .
Hopefully my description is clear.
Greetings
UPDATE
Like in this image, the rectangle should normally in the mid. For the detection it would be ok, if the initial finding of the positions would take longer and a "check" must be really fast.:
I don't know the relative performance of all the aspects of the OpenCV code, but I assume it is pretty good at vector type operations across whole rows of an image rather than scalar operations such as you suggest when you propose doing ever increasing circles radiating from the centre to find the cross. Here is one approach that may work.
First, squidge (TM) all the pixels together to make a column as tall as the original image but just a single pixel wide. I have coloured this in red in the diagram. The darkest pixel in this column gives you the y-coordinate of your reference points.
Then, squidge (TM) all the pixels together to make a row as wide as the original image but just a single pixel high. I have coloured this in blue in the diagram. The darkest of the middle black bar then gives you the x-coordinate of your central reference point.
This will also handle small rotations as well as translations - and if the rotations are larger, you will get 3 black bars on the right.
You may also decide that, in general, and to save time, you only need process the image from the 1/3 to the 2/3 point in the vertical direction and the 1/4 to the 3/4 point in the horizontal direction since that is most likely to include the reference points.
I have an image like this (thresholding, noise removal, etc. completed):
My final output should be an image without any of the jagged edges, and smaller than the given image. By this, I mean to say that the only difference between the 2 images must be that in the new one, the jagged edges must be removed, and not the jagged edges filled in. Like so (the final image must be the region within the red border, the red border is shown only for explanation):
I was thinking of something along the lines of using Hough transforms, or of using dilations and then erosions, but nothing seems to be working (probably my fault, because I have not worked in too much detail with them before).
Note that the language I'd like t do this in is MATLAB.
There are 2 primary aims to this:
To get the edges themselves, using Hough transforms
So that the 'Extrema' property returns the desired pints when using regionprops, like so:
The question, in a more concise form:
How would I go about extracting this T in MATLAB, such that it does not have rugged edges, but the overall figure is not larger than the original, as shown in the second figure above? In other words, what set of transformations (in MATLAB) would I use to smoothen the borders of the image with as little of the area lost as little as possible (but no area added) such that ruggedness disappears?
Is there a more efficient way of extracting the corner (extrema) points as shown in figure 2 above without requiring to go through step 1?
EDIT:
A few more sample images:
NB: All images in consideration will be composed of rectangles approximately at 90 to each other, and no other figure. So smoothening an image with a curved edge, for example, would be beyond the scope of an answer to this question (or even, for that matter, a trapezium, although I think that smoothening 2 straight edges should be the same, irrespective of whether the edge has another parallel to it or not).
Here are a few more images, for reference:
I'm not sure if my answer would satisfy your requirements. I'm putting it here because I think it's too long for a comment.
since you want the final output to be smaller than the input image, erode the input image. You can pick an appropriate kernel size.
perform a corner detection on this eroded image. This will give you all strong corners, but without any order
trace the boundaries of the eroded image. This should give you an ordered list of boundary pixels
now, with the help of these ordered boundary points you can order the corners that you found earlier
filter corner points that form approximately 90 degrees of angle. You can do this considering each 3 ordered corner points (two green points and the red point in between in the image below. It's just for illustration, not corner points that I calculated. At the end of this operation, you have all red points in the image below which are at strong corners, in addition to other yellow and green corner points)
now you can either find the equation of the line connecting 2 consecutive red points
or
fit a least-squares-line to the points between (and including) each 2 consecutive red points
since you did all this processing on a eroded image that is essentially smaller than the original image, you should get a smaller shape