mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 01:13:28 +08:00
fix choose minimum angle in rotatingCalipers
This commit is contained in:
parent
992b47b991
commit
8199967b31
@ -88,6 +88,32 @@ enum { CALIPERS_MAXHEIGHT=0, CALIPERS_MINAREARECT=1, CALIPERS_MAXDIST=2 };
|
||||
// Notes:
|
||||
//F*/
|
||||
|
||||
static void rotate90CCW(const cv::Point2f& in, cv::Point2f &out)
|
||||
{
|
||||
out.x = -in.y;
|
||||
out.y = in.x;
|
||||
}
|
||||
|
||||
static void rotate90CW(const cv::Point2f& in, cv::Point2f &out)
|
||||
{
|
||||
out.x = in.y;
|
||||
out.y = -in.x;
|
||||
}
|
||||
|
||||
static void rotate180(const cv::Point2f& in, cv::Point2f &out)
|
||||
{
|
||||
out.x = -in.x;
|
||||
out.y = -in.y;
|
||||
}
|
||||
|
||||
/* return true if first vector is to the right (clockwise) of the second */
|
||||
static bool firstVecIsRight(const cv::Point2f& vec1, const cv::Point2f &vec2)
|
||||
{
|
||||
cv::Point2f tmp;
|
||||
rotate90CW(vec1, tmp);
|
||||
return tmp.x * vec2.x + tmp.y * vec2.y < 0;
|
||||
}
|
||||
|
||||
/* we will use usual cartesian coordinates */
|
||||
static void rotatingCalipers( const Point2f* points, int n, int mode, float* out )
|
||||
{
|
||||
@ -100,6 +126,7 @@ static void rotatingCalipers( const Point2f* points, int n, int mode, float* out
|
||||
Point2f* vect = (Point2f*)(inv_vect_length + n);
|
||||
int left = 0, bottom = 0, right = 0, top = 0;
|
||||
int seq[4] = { -1, -1, -1, -1 };
|
||||
Point2f rot_vect[4];
|
||||
|
||||
/* rotating calipers sides will always have coordinates
|
||||
(a,b) (-b,a) (-a,-b) (b, -a)
|
||||
@ -179,32 +206,18 @@ static void rotatingCalipers( const Point2f* points, int n, int mode, float* out
|
||||
/* all of edges will be checked while rotating calipers by 90 degrees */
|
||||
for( k = 0; k < n; k++ )
|
||||
{
|
||||
/* sinus of minimal angle */
|
||||
/*float sinus;*/
|
||||
|
||||
/* compute cosine of angle between calipers side and polygon edge */
|
||||
/* dp - dot product */
|
||||
float dp[4] = {
|
||||
+base_a * vect[seq[0]].x + base_b * vect[seq[0]].y,
|
||||
-base_b * vect[seq[1]].x + base_a * vect[seq[1]].y,
|
||||
-base_a * vect[seq[2]].x - base_b * vect[seq[2]].y,
|
||||
+base_b * vect[seq[3]].x - base_a * vect[seq[3]].y,
|
||||
};
|
||||
|
||||
float maxcos = dp[0] * inv_vect_length[seq[0]];
|
||||
|
||||
/* number of calipers edges, that has minimal angle with edge */
|
||||
int main_element = 0;
|
||||
|
||||
/* choose minimal angle */
|
||||
for ( i = 1; i < 4; ++i )
|
||||
/* choose minimum angle between calipers side and polygon edge by dot product sign */
|
||||
rot_vect[0] = vect[seq[0]];
|
||||
rotate90CW(vect[seq[1]], rot_vect[1]);
|
||||
rotate180(vect[seq[2]], rot_vect[2]);
|
||||
rotate90CCW(vect[seq[3]], rot_vect[3]);
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
float cosalpha = dp[i] * inv_vect_length[seq[i]];
|
||||
if (cosalpha > maxcos)
|
||||
{
|
||||
if (firstVecIsRight(rot_vect[i], rot_vect[main_element]))
|
||||
main_element = i;
|
||||
maxcos = cosalpha;
|
||||
}
|
||||
}
|
||||
|
||||
/*rotate calipers*/
|
||||
|
Loading…
Reference in New Issue
Block a user