Find slope (angle) of each line of the image - image-processing

I have to calculate a slope (or an angle) of every single detectable line of the image. And even to detect the changes of the slope of the line, if it is possible.
I've performed 2D Fourier and I know a neighborhood averege angle at every area (sets of 64x64px). I even try a Hough transform, but neither sobel nor prewitt edge detection seems to detect these lines appropriately.
Please note that some of the lines are crossing each other, and some aren't straight.
Is there a method to detect the slope of each line? Or to detect these lines in order to perform an usefull Hough transform?
If you need the full image I can upload it somewhere.
Image

Greets Adamek,
I hope it is not too late. Here some quick ideas:
1) Using Hough trafo to detect lines is a good idea as a first step
2) Second step would be some kind of labeling to really know what lines there are. The most difficult problem to address is probably how to determine start and end of lines and seperate potentially connected ones. Search for the labeling keyword in this context, that should give some results.
3) Afterwards, having end and startpoint, I would
a) calculate for each line a regression line if you need more exact data in further analysis
b) just compute slope and intercept via f(x)=mx+n, where m is the slope and n the intercept. Given two points in 2D this is easily done as follows:
slope = (yRight - yLeft)/(xRight - xLeft);
m_oIntercept = ((yLeft - slope*xLeft) + (yRight - slope*xRight))*0.5;
and don't forget to test for (xRight-xLeft) < eps before to avoid zero division.
Hope that helps,
G.

Related

OpenCV parallel lines cull

I have an algorithm that simply goes through a number of corners and finds those which are parallel. My problem is, as shown below, that I sometimes get false positive results.
To eliminate this I was going to check if both points fell onto a single hough line but this would be quite computationally intensive and I was wondering if anyone had any simpler ideas.
Thanks.
Ok based on the comments, this should be fix-able. When you detect a pair of parallel lines, get the equation of the line using the two corners that you've used to construct it. This line may be of the form y = mx + c. Then for every y coordinate between the two points, compute the x coordinate. This gives you a set of all the pixels that the line segment covers. Go through these pixels, and check if the intensity at every pixel is closer to black than white. If a majority of the pixels in the set are black-ish, then it's a line. If not, it's probably a non-line.

Image processing: drawing a line though the axis of a bone

I hope someone can point me, to how I can solve my issue. . I have 6000 X-rays where I have to measure the angle between bones.
My strategy is the following: If I can somehow draw a line1 though the long axis of bone1, and line2 though the long axis of bone2, then I can simply measure the angle between the 2 lines.
So how can I find the axis in the first place? Is it possible to do it this way? :
(It is an x-ray picture) Lets say 1 cm from the top of the picture, we scan that row for the first pixel that turns white (the first edge of the bone), here we have a dot A1, the we continue scanning until we find the first pixel that turns black (the second edge of bone ), this is dot A2, we draw a line between Y1(A1,A2).
We do the same procedure, we go just further down lets say 10 cm from the top, we then have another line Y2(B1,B2). A line that goes from the middle of Y1 to the middle of Y2, will be the axis of the bone
I already managed to play with the threshold, and making and edge. to make it easy to draw the lines ?
Does it make sense?
Please, can it be done? Any idea how?
Any help will be appreciated, thank you!
Here's an idea:
Maybe if you downsample the images to get less artifacts and/or apply some mathematical morphology (http://en.wikipedia.org/wiki/Mathematical_morphology) to reduce the noise you can convert the bones into more line-shaped separated figures.
Apply some threshold so you can have black/white binary pictures. Use math to find a point in each of the 2 shapes and then try to match them to a rectangle or an oval. These will give you the axis you are looking for and then you can measure the angle.
This is too general a question. Images would always be appreciated! I guess you have 6000 xrays producing a grayscale image of the bones. In this case the general idea would be to:
1. Find a good binary segmentation of the bones in 3d
2. Find a good skeletonization of the 2 bones, also look at this
3. Replace the main skeletons of the two bones by line segments that best approximate it and measure the two angles (in 3d) between them
4. If this is two bones in the body - there is usually a limit to the degrees of freedom of two connected bones. It would be good to validate it wrt to this reference.
Tracing the line in realtime might not be the best in terms of accuracy. I guess this is obvious.
This could give an idea for the full human pose.

How to detect 45 degree edges in an image

If instead of getting all edges, I only want edges that make 45 degree angles. What is a method to detect these?
Would it be possible to detect all edges, then somehow run a constrained hough transform to detect which edges form 45 degrees?
What is wrong with using an diagonal structure element and simply convolve the image??
Details
Please read here and it should become clear how to build the structuring element. If you are familiar with convolution than you can build a simple structure matrix which amplifies diagonals without theory
{ 0, 1, 2},
{-1, 0, 1},
{-2, -1, 0}
The idea is: You want to amplify pixel in the image, where 45deg below it is something different than 45deg above it. Thats the case when you are at a 45deg edge.
Taking an example. Following picture
convolved by the above matrix gives a graylevel image where the highest pixel values have those lines which are exactly 45deg.
Now the approach is to simply binarize the image. Et voila
First of all, it is possible to do this as post processing.
The result of Hough is in the parameter space of (angle,radius).
So you can simply take a slice in say angle=(45-5,45+5) and all radiuses.
An alternative method is that the output of edge detection will contain only 45/135 angle edges.
If you use a kernel but want line equations, then you'll still have to perform a line fit after the edge pixels are found. If you're certain the lines are exactly 45 degrees, then knowing the (x,y) point on any discovered line or line segment is sufficient to find the line equation.
Hough (rho, theta) parameter space can use whatever ranges of rho and theta that you'd like. You might preprocess the image to favor neighbor pixels at the proper angle. For example, give a "bonus point" to an edge pixel if it has 8-neighbors at the appropriate angle. You can certainly mix a kernel-based method (such as halirutan suggested) with a parametric or parameterless Hough algorithm.
A recent implementation of Hough runs at blazing fast speeds, so if you're looking for a quick solution you might download the open source code and then simply filter the output.
"Real-time line detection through an improved Hough transform voting scheme"
by Fernandes and Oliveira
http://www.ic.uff.br/~laffernandes/projects/kht/index.html

How to dertmine the DirectionVector of a Line?

I have a programming problem , in the context of a geometric shape recognition(Rectangles, ovals etc).
In this context, if I have a a simple line, from say (x1,y1) to (x2,y2) - made up of a series of points(x-y pairs) -
How would I calculate the DIRECTION VECTOR for this line? I understand the math behind it, but I'm finding the algorithm provided by my client a bit vague. I'm stuck at step 3) of this algorithm.
The following is the algorithm(in English as opposed ot psedocode), exactly as provided by my client.
1) Brake the points that make up a "stroke" or "line" up in to sets of X(where by default X= 20 - we will adjust) points = a PointSet
2) For Each PointSet, find the EndPouint(average of the points at the ends) for the first and last Y points(where by default Y= X/5).
3) Find the DirectionVector of the PointSet= Subtract the CentrePoints
4) For each pair of PointSets, find the AngleChange = the angle between the DirectionVectors of the PointSets.
and so on.......
I am trying to figure out what point (3) means......
Any help would be DEEPLy appreciated folks! THANKS in advance.
If the segment from (x1,y1) to (x2,y2) is short, then you can approximate its direction vector simply by: (x2-x1)*i + (y2-y1)*j.
Otherwise, you could use PCA to estimate the direction vector as the principal axis of individual points forming the segment,

How to test proximity of lines (Hough transform) in OpenCV

(This is a follow-up from this previous question).
I was able to successfully use OpenCV / Hough transforms to detect lines in pictures (scanned text); at first it would detect many many lines (at least one line per line of text), but by adjusting the 'threshold' parameter via trial-and-error, it now only detects "real" lines.
(The 'threshold' parameter is dependant on image size, which is a bit of a problem if one has to deal with images of different resolutions, but that's another story).
My problem is that the Hough transform sometimes detects two lines where there is only one; those two lines are very near one another and (apparently) parallel.
=> How can I identify that two lines are almost parallel and very near one another? (so that I can keep only one).
If you use the standard or multiscale hough, you will end up with the rho and theta coordinates of the lines in polar coordinates. Rho is the distance to the origin, and theta is normally the angle between the detected line and the Y axis. Without looking into the details of the hough transform in opencv, this is a general rule in those coordinates: two lines will be almost parallel and very near one another when:
- their thetas are nearly identical AND their rhos are nearly identical
OR
- their thetas are near 180 degrees apart AND their rhos are near each other's negative
I hope that makes sense.
That's interesting about the theta being the angle between the line and the y-axis.
Generally, the rho and theta values are visualized as being the angle from the x-axis to the line perpendicular to the line in question. The rho is then the length of this perpendicular line. Thus, a theta = 90 and rho = 20 would mean a horizontal line 20 pixels up from the origin.
A nice image is shown on Hough Transform question

Resources