OpenCV C++ Drawing and Analyzing Line - c++

I am working on a OpenCV program capable of detecting Boxers punches and categories them. At the moment my program goes through all the different image processing, finds and detects contours, draws bounding boxes on ROI's (Region Of Interest), I am also computing some properties of each bounding box such as: Area and Center Point.
Now what i want to do is to draw a line from each bounding box starting from the center point and analyze that line for its Angle and Length. Have a look at the Image that illustrates my aim:
So hopefully now you guys have a better overview........
My Question here is How do i draw such line from starting position to end position store it in a vector to analyse it...?
I did some research on various functions that draw lines but non of them seem to be appropriate for my purpose. Here are some Research links:
Opencv Draw Line & Line iterator & poly lines
Also looked at arcLength, fitLine, clipLine & Hough transform
Could some one indicate me which technique would best fit my aim...?
Some good read, examples, Or just suggest how to even start this whole thing
Regards Hopefully my problem is well understood by now

Store the centroid positions frame-by-frame of an object being tracked in an array, then feed it to the PolyLines() function.

We can use PolyLines as following:
polylines(img /*image where to plot*/, &points /*the points (centroids in your case)*/ ,&numPoint /*number of points*/,1,false /*contour is not closed shape*/, Scalar(255,255,255),3, CV_AA, 0);
-Pay attention that points must be defined as Mat

Related

Detect ball/circle in OpenCV (C++)

I am trying to detect a ball in an filtered image.
In this image I've already removed the stuff that can't be part of the object.
Of course I tried the HoughCircle function, but I did not get the expected output.
Either it didn't find the ball or there were too many circles detected.
The problem is that the ball isn't completly round.
Screenshots:
I had the idea that it could work, if I identify single objects, calculate their center and check whether the radius is about the same in different directions.
But it would be nice if it detect the ball also if he isn't completely visible.
And with that method I can't detect semi-circles or something like that.
EDIT: These images are from a video stream (real time).
What other method could I try?
Looks like you've used difference imaging or something similar to obtain the images you have..? Instead of looking for circles, look for a more generic loop. Suggestions:
Separate all connected components.
For every connected component -
Walk around the contour and collect all contour pixels in a list
Suggestion 1: Use least squares to fit an ellipse to the contour points
Suggestion 2: Study the curvature of every contour pixel and check if it fits a circle or ellipse. This check may be done by computing a histogram of edge orientations for the contour pixels, or by checking the gradients of orienations from contour pixel to contour pixel. In the second case, for a circle or ellipse, the gradients should be almost uniform (ask me if this isn't very clear).
Apply constraints on perimeter, area, lengths of major and minor axes, etc. of the ellipse or loop. Collect these properties as features.
You can either use hard-coded heuristics/thresholds to classify a set of features as ball/non-ball, or use a machine learning algorithm. I would first keep it simple and simply use thresholds obtained after studying some images.
Hope this helps.

Using Opencv how to detect a box in image while eliminating objects printed inside box?

I am trying to develop box sorting application in qt and using opencv. I want to measure width and length of box.
As shown in image above i want to detect only outermost lines (ie. box edges), which will give me width and length of box, regardless of whatever printed inside the box.
What i tried:
First i tried using Findcontours() and selected contour with max area, but the contour of outer edge is not enclosed(broken somewhere in canny output) many times and hence not get detected as a contour.
Hough line transform gives me too many lines, i dont know how to get only four lines am interested in out of that.
I tried my algorithm as,
Convert image to gray scale.
Take one column of image, compare every pixel with next successive pixel of that column, if difference in there value is greater than some threshold(say 100) that pixel belongs to edge, so store it in array. Do this for all columns and it will give upper line of box parallel to x axis.
Follow the same procedure, but from last column and last row (ie. from bottom to top), it will give lower line parallel to x axis.
Likewise find lines parallel to y axis as well. Now i have four arrays of points, one for each side.
Now this gives me good results if box is placed in such a way that its sides are exactly parallel to X and Y axis. If box is placed even slightly oriented in some direction, it gives me diagonal lines which is obvious as shown in below image.
As shown in image below i removed first 10 and last 10 points from all four arrays of points (which are responsible for drawing diagonal lines) and drew the lines, which is not going to work when box is tilted more and also measurements will go wrong.
Now my question is,
Is there any simpler way in opencv to get only outer edges(rectangle) of box and get there dimensions, ignoring anything printed on the box and oriented in whatever direction?
I am not necessarily asking to correct/improve my algorithm, but any suggestions on that also welcome. Sorry for such a big post.
I would suggest the following steps:
1: Make a mask image by using cv::inRange() (documentation) to select the background color. Then use cv::not() to invert this mask. This will give you only the box.
2: If you're not concerned about shadow, depth effects making your measurment inaccurate you can proceed right away with trying to use cv::findContours() again. You select the biggest contour and store it's cv::rotatedRect.
3: This cv::rotatedRect will give you a rotatedRect.size that defines the width en the height of your box in pixels
Since the box is placed in a contrasting background, you should be able to use Otsu thresholding.
threshold the image (use Otsu method)
filter out any stray pixels that are outside the box region (let's hope you don't get many such pixels and can easily remove them with a median or a morphological filter)
find contours
combine all contour points and get their convex hull (idea here is to find the convex region that bounds all these contours in the box region regardless of their connectivity)
apply a polygon approximation (approxPolyDP) to this convex hull and check if you get a quadrangle
if there are no perspective distortions, you should get a rectangle, otherwise you will have to correct it
if you get a rectangle, you have its dimensions. You can also find the minimum area rectangle (minAreaRect) of the convexhull, which should directly give you a RotatedRect

OpenCV C++ extract features from binary image

I have written an algorithm to process a camera capture and extract a binary image of two features I'm interested in. I'm trying to find the best (fastest) way of detecting when the two features intersect and where the lowest (y coordinate is greatest) point is (this will be the intersection).
I do not want to use a findContours() based method as this is too slow and, in my opinion, unnecessary. I also think blob detection libraries are too bloated for this.
I have two sample images (sorry for low quality):
(not touching: http://i.imgur.com/7bQ9qMo.jpg)
(touching: http://i.imgur.com/tuSmKw7.jpg)
Due to the way these images are created, there is often noise in the top right corner which looks like pixelated lines but methods such as dilation and erosion lose resolution around the features I'm trying to find.
My initial thought would be to use direct pixel access to form a width filter and a height filter. The lowest point in the image is therefore the intersection.
I have no idea how to detect when they touch... logically I can see that a triangle is formed when they intersect and otherwise there is no enclosed black area. Can I fill the image starting from the corner with say, red, and then calculate how much of the image is still black?
Does anyone have any suggestions?
Thanks
Your suggestion is a way more slow than finding contours. For binary images, finding contour is very easy and quick because you just need to find a black pixel followed by a white pixel or vice versa.
Anyway, if you don't want to use it, you can use the vertical projection or vertical profile you will see it the objects intersect or not.
For example, in the following image check the the letter "n" which is little similar to non-intersecting object, and the letter "o" which is similar to intersecting objects :
By analyzing the histograms you can recognize which one is intersecting or not.

Finding individual center points of circles in an image

I am using open CV and C++. I have a completely dark image which has 3 colored points on it. I need their center coordinates. If I have only one colored point in the dark image, it will automatically display its center coordinate. However,if I take as input the dark image with the 3 colored points,my program will make an average if those 3 coordinates and return the center of the 3 colored points together,which is my exact problem. I need their individual center coordinates.
Can anyone suggest a method to do that please. Thanks
Here is the code http://pastebin.com/RM7chqBE
Found a solution!
load original image to grayscale
convert original image to gray
set range of intensity value depending on color that needs to be detected
vector of contours and hierarchy
findContours
vector of moments and point
iterate through each contour to find coordinates
One of the ways to do this easily is to use the findContours and drawContours function.
In the documentation you have a bit of code that explains how to retrieve the connected components of an image. Which is what you are actually trying to do.
For example you could draw every connected component you will find (that means every dot) on it's own image and use the code you already have on every image.
This may not be the most efficient way to do this however but it's really simple.
Here is how I would do it
http://pastebin.com/y1Ae3e2V
I'm not sure this works however as I don't have time to test it but you can try it.

Divide Contours at overlap

I have an Image on which i have extracted several contours with 1st) cvCanny and 2nd) findContours. I'm only interested in the external Points, so I got several closed contours that i do analyse further. I'm looking for ellipses or circles and due to some overlap in the image i got some contours that are actually interesting for me but my algorithm discards them because they do not look elliptic.
Is there a way to dividide those contours, e.g. based on the small connecting "bridges" between two overlapping contours detected as one?
In this example i would want to just cut the rod on the lower right corner.
Due to performance issues, Hough circle detection is not an option.
Thanks!
Never worked with these sorts of algorithms before, but here's an idea: Define a minimum length L between points less than which you'd want to create a bridge. Then for each point on the contour, construct the tangent line segment of length L with its origin at that point. Wherever that tangent line segment intersects two points you will have a place where the contour is effectively getting 'pinched' as with the rod/ellipse junction in your figure. When this happens draw the bridge, which will be the tangent segment itself.
It might be easier to imagine or do if you take a single segment at a single point (say at the top of your curve, oriented to the left) and you move the segment around the contour, moving it along the bridges created online when the above condition is met.