How can I find center of object? - c++

I have black and white image after binarization. After that I get one object with irregular shape. Link to this image is below.
How can I inscribe this object to circle?? or How can I find "center" of this object??

You can find the center of gravity of the pixels using a simple formula which is the sum of the x coordinates divided by the number of points and the sum of the y coordinates divided by the number of points (I mean white points).
Then you can draw a circle centered in the center of gravity with radious half of the maximum distance between points.
Here you have a graphic explanation for this.

This sounds like a smallest circle problem on the set of white pixels. It can be found in linear time in the number of pixels. This is the best you will ever get it your input is just an array of binary pixels.

well, you could scan from top down for the top-most white pixel, then from the bottom up for the bottom-most white pixel, same for left and right. that gives you a rectangle. finding the center of the rectangle is easy (e.g. left + ( right - left ) / 2), and that's your circle center. then find the distance to a corner (any will do), and that's your circle radius.

I think, that center of the object can be easily found as an arithmetic mean of x and y coordinate. I you want to replace it by a circle, I'd say that the diameter is a double of the mean distance of all points to the center.

Related

Calculate positions occupied by a polygon after rotation in a grid

I looked for some similar questions, but I think that no one of them are related to my problem.
I am coding in C++ the translation and rotation of a simple polygon (i.e a rectangle, a polygon like a L shape, ...) in a grid cell of 10x10.
Let's say that I have a rectangle of width = 1 cell and height = 3 cells. Translate it in the 8 directions is easy. But if I want to rotate this polygon 45º, I can get it, but I want to calculate which are the cells that are now occupied or partially occupied by the rectangle.
I have the center of mass of the rectangle, that is a cell of it. I can calculate the positions occupied by the rectangle before the rotation depending on the size. But, after the rotation, I cannot find the way to calculate the cell positions occupied by the rectangle.
Thank you very much!
You can definitely treat this like a bounding box problem -
Take the four corners of your rectangle with x,y coordinate of these corners being the cell numbers they occupy - for e.g. for the rectangle of width = 1 cell and height = 3 cells centered at o(2,2) these 4 corners represented in corner(x,y) format would be - a(1.5,3.5) b(2.5,3.5) c(2.5,0.5) d(1.5,0.5).
Once this is clear, i think the remaining procedure you might have already understood as it has been explained before a number of times like here -
Calculate Bounding box coordinates from a rotated rectangle
To summarize, apply the standard matrix for 2D rotation to these 4 corners and get the new corners for e.g.
a'.x = o.x + (a.x - o.x) * cos(t) + (a.y - o.y) * sin(t)
a'.y = o.y - (a.x - o.x) * sin(t) + (a.y - o.y) * cos(t)
and similarly for the other points. Then find the max and min x and y and they will represent the cells occupied by your rectangle. Similar stuff can be done for other convex polygon.
UPDATE:
As commented by Fang, to get the accurate number of cells occupied by the rotated polygon you would still need to do the square to polygon intersection check for all the square cells within the bounding box- you can take a look at this -
How to check intersection between 2 rotated rectangles?
Here is what I would do:
1) Get the vertices of the original polygon. Since your polygon is composed of connected grid cells, I supposed the coordinates of these vertices will all be integers.
2) Rotate the polygon vertices. I supposed you know how to do this as you know how to rotate the polygon.
3) To detect if a given cell is still occupied by the rotated polygon, check if the cell has any intersection with the rotated polygon. So, this is basically a square-to-polygon intersection check. When there is no intersection at all or the intersection is an edge or a vertex, you can conclude that this cell is not occupied by the rotated polygon.
4) Do step 3 for all the cells.
In step 4, instead of looping thru all cells, you can actually use the bounding box of the rotated polygon to easily exclude some cells from the square-to-polygon intersection check. But if you only have 10x10 cells, you probably can get away without it without seeing any performance difference.

Circle that moves on the edge of a circle

As the title describes, I want to make a tiny circle that circulates on the edge of the sector of the another big circle. I have implemented sector of the circle, now only issue here is how to make small circle circulate on the edge of this sector. I have tried various ways, however, none of them was proved to be successful, therefore I plead you to give me some tips of how to implement it.
Thanks in advance.
You just have to consider that, for a circle of radius 1 centered on the origin, every point on the circle can be described as:
P = [sin(alpha); cos(alpha)]
With 0<=alpha<2*pi
Now, if you change the radius and the center you will have:
P = [(radius * sin(alpha))+x_center; (radius*cos(alpha))+y_center]
So, just have a loop for alpha going from 0 to 2*pi (or whatever section of circle you need) and use the above equation to calculate the position of the center of the small circle.
I presume you have a a function that can draw a circle at a given position in cartesian co-ordinates and radius.
Use polar co-ordinates (angle / radius), set the radius to the radius of the big circle minus the small circle. Set the angle to wherever you want to start the circle. Then set a loop up to increment the angle by a given amount. After each increment, clear the screen, draw the big circle. Then convert the polar co-orindates into cartesian, add on the centre of the big circle and draw the small circle. Hold for as long as you want.

Get rectangle vertices by center, normal, length and height

I am looking for a way to get all the vertices of a rectangle whose center, normal, length and height I know. I am a little weak in maths so please help me.
Edit : the plane is in 3D space.
You can easily calculate the x and y coordinates of the vertices of a rectangle in 2D space given the center, width and height by subtracting/adding half the width/height from the x/y position of the center point.
If you need this in 3D space, this becomes a little more tricky and relies on a bit of trigonometry, but still follows the same principle. You'll need one extra piece of information. You need some way of fixing the orientation of the square in some direction; ie, which direction is the rectangle 'facing'. The normal will allow you to work out what plane the rectangle is on, but without some orientation on that plane, the best you can do is work out a set of possible values in a circle around the center for each of the vertices.

Problem with Multigradient brush implementation from scatch in C++ and GDI

I am trying to implement a gradient brush from scratch in C++ with GDI. I don't want to use GDI+ or any other graphics framework. I want the gradient to be of any direction (arbitrary angle).
My algorithm in pseudocode:
For each pixel in x dirrection
For each pixel in the y direction
current position = current pixel - centre //translate origin
rotate this pixel according to the given angle
scalingFactor =( rotated pixel + centre ) / extentDistance //translate origin back
rgbColor = startColor + scalingFactor(endColor - startColor)
extentDistance is the length of the line passing from the centre of the rectangle and has gradient equal to the angle of the gradient
Ok so far so good. I can draw this and it looks nice. BUT unfortunately because of the rotation bit the rectangle corners have the wrong color. The result is perfect only for angle which are multiples of 90 degrees. The problem appears to be that the scaling factor doesn't scale over the entire size of the rectangle.
I am not sure if you got my point cz it's really hard to explain my problem without a visualisation of it.
If anyone can help or redirect me to some helpful material I'd be grateful.
Ok guys fixed it. Apparently the problem was that when I was rotating the gradient fill (not the rectangle) I wasn't calculating the scaling factor correctly. The distance over which the gradient is scaled changes according to the gradient direction. What must be done is to find where the edge points of the rect end up after the rotation and based on that you can find the distance over which the gradient should be scaled. So basically what needs to be corrected in my algorithm is the extentDistance.
How to do it:
•Transform the coordinates of all four corners
•Find the smallest of all four x's as minX
•Find the largest of all four x's and call it maxX
•Do the same for y's.
•The distance between these two point (max and min) is the extentDistance

Calculate minimum area rectangle for a polygon

I have a need to calculate the minimum area rectangle (smallest possible rectangle) around the polygon.
The only input i have is the number of points in polygon.
I have the co-ordinates of the points also.
This is called Minimum Bounding Box, it's most basic algorithm used in OCR packages. You can find an implementation using Rotating Calipers from the OpenCV package. Once you get the source code, check out this file,
cv/src/cvrotcalipers.cpp
The method you need is cvMinAreaRect2().
Use the rotating calipers algorithm for a convex polygon, or the convex hull otherwise. You will of course need the coordinates of the points in the polygon, not just the number of points.
First do a grahm-scan and get the convex hull of the set of points. Then you can use something like minimum rectangle discussed here
Follow the following algorithm
Rotate the polygon onto the XY plane
Pick 1 edge and align this edge with the X axis(use arctan). Use the min/max x,y to find the bounding rectangle. Compute Area and store in list
Do the same for remaining edges in clipped polygon.
Pick the rectangle with the minimum Area.
Rotate Bounding Rectangle back for Coplanar reverse rotation of Step 1 and step 2
for more detail check link Minimum-Area-Rectangle
Obviously, you'll need the coordinates of the points to get the answer. If the rectangle is aligned to the X and Y aces, then the solution is trivial. If you want the smallest possible rectangle, at any angle, then you'll need to do some sort of optimization process.