In fact, I am not very good at the algorithm, but the project is useful to some kind of algorithm to achieve a certain function, but also have to bite the bullet to achieve.
This is a very early project, to calculate the minimum bounding rectangle of a convex hull polygon. There must be no end to this situation. After having turned over some information. It's finally done.
Let's talk about what the project will do:
There is a desktop app that connects to an external camera, captures graphics through the camera, and calculates a function
For example, when we do the app, we can use the camera to identify the bank card, and then through the OCR to identify the card number, to quickly fill the bank card number purposes.
For example, the bank needs a copy of the customer ID card, only need to put your ID card under the camera under the mouse, you can complete the copy of the electronic file, and discard the scanner.
For example, when you go to the parking lot, the LED display can quickly display your license plate number. These are captured with an HD camera, followed by a series of calculations, and then by OCR recognition.
For example, remove the Green Circle section from the picture.
First we get the picture, after the image to grayscale---> two value---> Find the edge---> get the largest blob, by the coordinates of the calculation, the final can be cut out of the circle part.
So the object is more complex graphics, such as triangles, pentagram, irregular polygon change how to deal with it.
Any picture his final shape is a rectangle, then we can get the desired shape by calculating the minimum bounding rectangle of the irregular polygon and then tilting 90° through the angle.
The smallest bounding rectangle of a convex polygon has at least one edge collinear with one edge of the polygon.
Brute Force algorithm
Traverse each edge to construct a bounding rectangle to compare the area size. is to construct the bounding rectangle, take the projection point to the edge and the vertical edge to take the distance up to two points away
/* min value */#define FLT_MIN 1.175494351e-38f/* max value */#define FLT_MAX 3.402823466e+38f struct OBB { Point U[2]; X, y-axis point C; Center point float e[2]; Half-length, half-width}; Float Minarearec (point *pts, int ptsnum, OBB &obb) {float Minarea = Flt_max; for (int i = 0, j = ptsNum-1; i < ptsnum; j = i, i++) {//traverse edge point u0 = pts[i]-pts[j];//construction Edge u0 = u 0/length (u0); Point u1 = Point (0-u0.y, u0.x);//u0 vertical float Min0 = 0.0f, max0 = 0.0f, min1 = 0.0f, max1 = 0.0f; for (int k = 0; k < ptsnum; k++) {//traverse point d = pts[k]-pts[j]; Projection in u0 float dot = dot (d, u0); if (dot < min0) Min0 = dot; if (dot > max0) max0 = dot; Projection in u1 dot = dot (d,u1); if (dot < min1) min1 = dot; if (dot > max1) max1 = dot; } Float area = (max0-min0) * (max1-min1); if (area < Minarea) {Minarea = area; OBB.C = Pts[j] + (u0 * (max0 + min0) + u1 * (Max1 + min1)) *0.5f; Obb.u[0] = u0; OBB.U[1] = u1; Obb.e[0] = (max0-min0) *0.5f; OBB.E[1] = (max1-min1) *0.5f; }} return Minarea; } point * getobbpoints (OBB OBB) {//Get OBB four vertex coordinates point *pts = new Point [4]; Pts[0] = OBB.C + (obb.u[0] * obb.e[0] + obb.u[1] * obb.e[1]); PTS[1] = OBB.C + (obb.u[0] * obb.e[0]-obb.u[1] * obb.e[1]); PTS[2] = OBB.C-(obb.u[0] * obb.e[0] + obb.u[1] * obb.e[1]); PTS[3] = OBB.C + (obb.u[1] * obb.e[1]-obb.u[0] * obb.e[0]); return pts; }
Rotating caliper (rotating jam) algorithm
Using the rotary caliper algorithm can reduce the time consumption of calculating the minimum bounding rectangle of a convex polygon.
Take the coordinates of the two points to form a parallel line, rotating two lines, when the line and polygon one edge coincident, the calculation of the rectangular area.
Continue to rotate until the rotation angle exceeds 90 degrees. The minimum area to be taken.
The algorithm is effective only for convex bodies (the force method is effective for convex concave bodies), so it is necessary to calculate the convex body first, and the time complexity of the algorithm is limited by the calculation process of the convex body.
Float Cos (Point V, point p1) {Float dot = dot (v,p1); float cos = dot/(Length (v) *length (p1)); return cos; } void Setu0u1 (point e, point &u0, point &u1) {//x-axis direction in e direction, set xy axis u0 = E/length (e); u1 = Point (0-u0.y, u0.x); } int Getminangleindex (int imin1, int imax0, int imax1, int imin0, point* E, point u0, point U1) {//returns the subscript int imin_angle_index = 0 for the point with the smallest rotation angle (the Cos value is the largest); float cos = 0, maxcos = flt_min; cos = cos (e[imin1], u0); if (Cos > maxcos) {maxcos = cos; imin_angle_index = imin1;} cos = cos (e[imax0], U1); if (Cos > maxcos) {maxcos = cos; imin_angle_index = imax0;} cos = cos (e[imax1], point (0-U0.X,0-U0.Y)); if (Cos > maxcos) {maxcos = cos; imin_angle_index = imax1;} cos = cos (e[imin0], point (0-U1.X,0-U1.Y)); if (Cos > maxcos) {maxcos = cos; imin_angle_index = imin0;} return imin_angle_index; } void Setminmax (point*pts, int i, int iu, point u0, point U1, float &max0, float &min0, float &max1, int & new_imax0, int & amp;new_imin0, int &new_imax1) {//Find x-axis projection maximum minimum, y-axis projection maximum length (y-axis is the smallest coincident edge, length 0)//And the extremum point is subscript in pts in point d = Pts[i]-PTS[IU]; float dist0 = Dot (d, u0); if (Dist0 > max0) {max0 = dist0; new_imax0 = i;} if (Dist0 < min0) {min0 = dist0; new_imin0 = i;} float Dist1 = Dot (d, U1); if (Dist1 > Max1) {max1 = Dist1; new_imax1 = i;} } float MINAREAREC2 (point *pts, int ptsnum, OBB &obb) {//Rotation jam algorithm//must be convex package float Minarea = Flt_max; Initialize Edge e Point *e = new point[ptsnum]; for (int i = 0; i < Ptsnum; i++) {E[i] = pts[(i+1)%ptsnum]-pts[i]; } int iu = 0;//with e[0] for coincident edges//initialization u0 U1 point u0,u1; SETU0U1 (E[iu], u0, U1); int imax0 = 0, imax1 = 0, Imin0 = 0, imin1 = 0; float Min0 = Flt_max, max0 = flt_min, max1 = flt_min, min1 = 0;//min1 can actually not be set, always 0 Just for the sake of understanding convenience plus//To remove the min1 you need to change the below to 0 Ask for three extremum coordinates for (int i = 0; i < Ptsnum; i++) {Setminmax (pts, I, IU, u0 , U1, Max0, Min0, Max1, imax0, Imin0, IMAX1); } for (int i = 0; i < Ptsnum; i++) {int iminangle = 0; Iminangle = Getminangleindex ((iu+1)%ptsnum, imax0, Imax1, Imin0, E, u0, U1); if (Iminangle = = 0) break;//rotated back to the initial point no need to continue if (Iminangle = = imax0) {imax0 = (IU + 1)%ptsnum;iu = Iminangle;} else if (Iminangle = = imax1) {imax1 = (IU + 1)%ptsnum;iu = Iminangle;} else if (Iminangle = = imin0) {Imin0 = (IU + 1)%ptsnum;iu = Iminangle;} else if (Iminangle = = (iu+1)%ptsnum) {IU = (iu+1)%ptsnum;} SETU0U1 (E[iu], u0, U1);//reset U0U1//maintain three extreme points int new_imax0 = imax0, new_imax1 = imax1, new_imin0 = Imin0; Min0 =flt_max, max0 =Flt_min, max1 = flt_min; Determine what extreme values of the original imax0 in the new coordinate system Setminmax (pts, imax0, IU, u0, U1, max0, Min0, Max1, New_im Ax0, New_imin0, NEW_IMAX1); Determine what extreme values of the original IMAX1 in the new coordinate system Setminmax (pts, Imax1, IU, u0, U1, max0, Min0, Max1, New_im Ax0, New_imin0, NEW_IMAX1); Determine what extreme values of the original imin0 in the new coordinate system Setminmax (pts, Imin0, IU, u0, U1, max0, Min0, Max1, New_im Ax0, New_imin0, NEW_IMAX1); imax0 = new_imax0; Imax1 = New_imax1; Imin0 = New_imin0; Maintenance completed//For area setting OBB float areas = (max0-min0) * (max1-min1); if (area < Minarea) {Minarea = area; Obb.e[0] = (max0-min0) *0.5f; OBB.E[1] = (max1-min1) *0.5f; Obb.u[0] = u0; OBB.U[1] = u1; OBB.C = Pts[iu] + (u0 * (max0 + min0) + u1 * (Max1 + min1)) *0.5f; } }return minarea; }
Got four points, the other is to say, from the main cut out of the rectangle, and then parallel to 90° is OK.
Finish
The minimum bounding rectangle algorithm for convex hull polygon