How would it be possible to identify rotated squares in an image?
I have some ideas how to identify them normally, but I'm confused with the "pixel" representation of rotated square. If it is rotated by the angle of 90 degrees it seems that it would be represented by edges that will follow (starting from left point) x+1,y+1 then x+1,y-1 then x-1,y+1 and x-1,y-1. But what happens if angle is different then 90 degrees? How would it be represented in pixels?
And how to detect such square?
If your square edges are well-defined, you can try Hough transform to determine lines on the image and find whether they form a square. Another option - using OpenCV library to find shape contours.
(OpenCV contains Hough transform too)
[Edit]
If edge lines are ideal (without gaps and artifacts), then you can try point-by-point traversal:
Scan an image, find any active (non-background) point. It is corner or point on the edge. Check neighbour pixels, find active one. Check next pixel in the same direction and in two adjacent directions (from 8 possible ways). Continue moving until corner is met. Remember corner position. Check for perpendicular direction for the next edge.
Related
I have a situation where I have a set of pixels that make up the border of a quadrilateral (very close to square). I'm trying to determine the location of the corners as best as possible and have been struggling for a while now. My first thought was to determine the straight lines of the border and then calculate the corner points, but I don't have access to OpenCV or other image processing libraries, unfortunately.
Below are three cases where the black outline is the image boundary and the red outline is the quadrilateral boundary. I have a list of all of the pixels that make up the red boundary and the red boundary thickness may vary.
My initial thought was that I could just find the pixel that is closest to each of the four image boundaries, however this won't quite work for the first case where the inner quadrilateral isn't tilted.
Any thoughts on how to tackle this problem would be great. I'm coding in dart, but am looking for a psuedocode answer that I can implement myself.
(I have seen this post, which is similar to my problem, but I think there should be a simpler solution for my problem since I have access to all of the boundary points of the quadrilateral)
Having a list of all rectangle boundary pixels, you can use simple methods like this:
Calculate gravity center of rectangle (just sum X- and Y- coordinates of pixels and divide by their number) - it is diagonal intersection.
Find the farthest pixels - they are corners.
In case of bad quality of data set (empty places, excessive pixels) center calculation might be inexact. So you can apply Hough transform to extract sides (as lines) and calculate their intersections.
I have a set of arbitrary rotated filled rectangles plotted on a Cartesian grid (2D integer array, each cell is either 0 - empty space or 1 - rectangle pixel) and would like to test whether a particular rectangle has any obstacles around it given that the center of rectangle is known along with the coordinates of its four edges.
For example, let's say we want to test if rectangle is obstacle free 5 units from either of its edges.
Rectangles marked with green dot are ok, while the unmarked are clearly collide.
It seems trivial for non rotated rectangles however, I am having a hard time coming up with algorithm which can handle rotated rectangles.
Simply looping starting from the center till we hit empty space and then checking for obstacles in the empty space doesn't seem to work if rectangles are touching each other.
Since you seem to be operating with an image-oriented mindset, you can use image processing.
Apply a radius-2.5 dilation filter to your image.
Treat the image as a graph where there is an edge between two pixels if they both have a red value above some threshold.
Any rectangles that have a path between them are at most 5 apart. (Although, note that this will give you the transitive closure of the "too close" relationship.)
I have a shape (in black below) and a point inside the shape (red below). What's the algorithm to find the closest distance between my red point and the border of the shape (which is the green point on the graph) ?
The shape border is not a series of lines but a randomly drawn shape.
Thanks.
So your shape is defined as bitmap and you can access the pixels.
You could scan ever growing squares around your point for border pixels. First, check the pixel itself. Then check a square of width 2 that covers the point's eight adjacent pixels. Next, width 4 for the next 16 pixels and so on. When you find a border pixel, record its distance and check against the minimum distance found. You can stop searching when half the width of the square is greater than the current minimum distance.
An alternative is to draw Bresenham circles of growing radius around the point. The method is similar to the square method, but you can stop immediately when you have a hit, because all points are supposed to have the same distance to your point. The drawback is that this method is somewhat inaccurate, because the circle is only an approximation. You will also miss some pixels along the disgonals, because Bresenham circles have artefacts.
(Both methods are still quite brute-force and in the worst case of a fully black bitmap will visit every node.)
You need a criterion for a pixel on the border. Your shape is antialiassed, so that pixels on the border are smoothed by making them a shade of grey. If your criterion is a pixel that isn't black, you will chose a point a bit inside the shape. If you cose pure white, you'll land a bit outside. Perhaps it's best to chose a pixel with a grey value greater than 0.5 as border.
If you have to find the closest border point to many points for the same shape, you can preprocess the data and use other methods of [nearest-neighbour serach].
As always, it depends on the data, in this case, what your shapes are like and any useful information about your starting point (will it often be close to a border, will it often be near the center of mass, etc).
If they are similar to what you show, I'd probably test the border points individually against the start. Now the problem is how you find the border without having to edge detect the entire shape.
The problem is it appears you can have sharply concave borders (think of a circle with a tiny spike-like sliver jutting into it). In this case you just need to edge detect the shape and test every point.
I think these will work, but don't hold me to it. Computational geometry seems to be very well understood, so you can probably find a pro at this somewhere:
Method One
If the shape is well behaved or you don't mind being wrong try this:
1- Draw 4 lines (diving the shape into four quandrants). And check the distance to each border. What i mean by draw is keep going north until you hit a white pixel, then go south, west, and east.
2- Take the two lines you have drawn so far that have the closest intersection points, bisect the angle they create and add the new line to your set.
3- keep repeating step two until are you to a tolerance you can be happy with.
Actually you can stop before this and on a small enough interval just trace the border between two close points checking each point between them to refine the final answer.
Method Two (this wil work with the poorly behaved shapes and plays well with anti-aliasing):
1- draw a line in any direction until he hit the border (black to white). This will be your starting distance.
2- draw a circle at this distance noting everytime you go from black to white or white to black. These are your intersection points.
As long as you have more than two points, divide the radius in half and try again.
If you have no points increase your radius by 50% and try again (basically binary search until you get to two points - if you get one, you got lucky and found your answer).
3- your closet point lies in the region between your two points. Run along the border checking each one.
If you want to, to reduce the cost of step 3 you can keep doing step 2 until you get a small enough range to brute force in step 3.
Also to prevent a very unlucky start, draw four initial lines (also east, south, and west) and start with the smallest distance. Those are easy to draw and greatly reduce your chance of picking the exact longest distance and accidentally thinking that single pixel is the answer.
Edit: one last optimization: because of the symmetry, you only need to calculate the circle points (those points that make up the border of the circle) for the first quadrant, then mirror them. Should greatly cut down on computation time.
If you define the distance in terms of 'the minimum number of steps that need to be taken to reach from the start pixel to any pixel on the margin', then this problem can be solved using any shortest path search algorithm like bread first search or even better if you use A* search algorithm.
Suppose I have an image of a scene as depicted above. A sort of a pole with a blob on it next to possibly similar objects with no blobs.
How can I find the blob marked by the red circle (a binary image indicating which pixels belong to the blob).
Note that the pole together with the blob may be rotated arbitrarily and also size may vary.
Can you try to do it in below 4 steps?
Circle detection like: writing robust (color and size invariant) circle detection with opencv (based on Hough transform or other features)
Line detection, like: Finding location of rectangles in an image with OpenCV
Identify rectangle position by combining neighboring lines (For each line segment you have the start and end point position, you also know the direction of each line segment. So that you can figure out if two connecting line segments (whose endpoints are close) are orthogonal. Your goal is to find 3 such segments for each rectangle.)
Check the relative position of each circle and rectangle to see if any pair can form the knob shape.
One approach could be using Viola-Jones object detection framework.
Though the framework is mostly used for face detection - it is actually designed for generic objects you feed to the algorithm.
The algorithm basic idea is to feed samples of "good object" (what you are looking for) and "bad objects" to a machine learning algorithm - which generates patterns from the images as its features.
During Classification - using a sliding window the algorithm will search for a "match" to the object (the classifier returned a positive answer).
The algorithm uses supervised learning and thus requires a labeled set of examples (both positive and negative ones)
I'm sure there is some boundary-map algorithm in image processing to do this.
Otherwise, here is a quick fix: pick a pixel at the center of the
"undiscovered zone", which initially is the whole image.
trace the horizantal and vertical lines at 4 directions each ending at the
borders of the zone and find the value changes from 0 to 1 or the vice verse.
Trace each such value switch and complete the boundary of each figure (Step-A).
Do the same for the zones
that still are undiscovered: start at some center
point and skim thru the lines connecting the center to the image border or to a
pixel at the boundary of a known zone.
In Step-A, you can also check to see whether the boundary you traced is
a line or a curve. Whenever it is a curve, you need only two points on it--
points at some distance from one another for the accuracy of the calculation.
The lines perpendicular each to these two points of tangency
intersect at the center of the circle red in your figure.
You can segment the image. Then use only the pixels in the segments to contribute to a Hough-transform to find the circles.
Then you will only have segments with circle in them. You can use a modified hough transform to find rectangles. The 'best' rectangle and square combination will then be your match. This is very computationally intentsive.
Another approach, if you already have these binary pictures, is to transform to a (for example 256 bin) sample by taking the distance to the centroid compared to the distance travelled along the edge. If you start at the point furthest away from the centroid you have a fairly rotational robust featurevector.
I am writing a program in Matlab to detect a circle.
I've already managed to detect shapes such as the square, rectangle and the triangle, basically by searching for corners, and determining what shape it is based on the distance between them. The images are black and white, with black being the background and white the shape, so for me to find the corners I just have to search each pixel in the image until I find a white pixel.
However I just can't figure out how I can identify the circle.
Here it the an example of how a circle input would look like:
It is difficult to say what the best method is without more information: for example, whether more than one circle may be present, whether it is always centred in the image, and how resilient the algorithm needs to be to distortions. Also whether you need to determine the location and dimensions of the shape or simply a 'yes'/'no' output.
However a really simple approach, assuming only one circle is present, is as follows:
Scan the image from top to bottom until you find the first white pixel at (x1,y1)
Scan the image from bottom to top until you find the last white pixel at (x2,y2)
Derive the diameter of the suspected circle as y2 - y1
Derive the centre of the suspected circle as ((x1+x2)/2, y1+(y2-y1)/2)
Now you are able to score each pixel in the image as to whether it matches this hypothetical circle or not. For example, if a pixel is inside the suspected circle, score 0 if it is white and 1 if it black, and vice-versa if it is outside the suspected circle.
Sum the pixel scores. If the result is zero then the image contains a perfect circle. A higher score indicates an increasing level of distortion.
I think you may read about this two topics:
Theoretical:
Binary images
Hough transform
Matlab:
Circle Detection via Standard Hough Transform
Hough native in matlab
Binary images