热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

结构分析与形状识别(外接矩形旋转角度)

classCV_EXPORTSRotatedRect{public:!variousconstructorsRotatedRect();Rotate
class CV_EXPORTS RotatedRect  
{
public:  
    //! various constructors  
    RotatedRect();  
    RotatedRect(const Point2f& center, const Size2f& size, float angle);  
    RotatedRect(const CvBox2D& box);  
  
    //! returns 4 vertices of the rectangle  
    void points(Point2f pts[]) const;  
    //! returns the minimal up-right rectangle containing the rotated rectangle  
    Rect boundingRect() const;  
    //! conversion to the old-style CvBox2D structure  
    operator CvBox2D() const;  
  
    Point2f center; //< the rectangle mass center  
    Size2f size;    //< width and height of the rectangle  
    float angle;    //< the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.  
};
RotatedRect::points(Point2f pt[]) const  
{  
    double _angle = angle*CV_PI/180.;  
    float b = (float)cos(_angle)*0.5f;  
    float a = (float)sin(_angle)*0.5f;  
  
    pt[0].x = center.x - a*size.height - b*size.width;  
    pt[0].y = center.y + b*size.height - a*size.width;  
    pt[1].x = center.x + a*size.height - b*size.width;  
    pt[1].y = center.y - b*size.height - a*size.width;  
    pt[2].x = 2*center.x - pt[0].x;  
    pt[2].y = 2*center.y - pt[0].y;  
    pt[3].x = 2*center.x - pt[1].x;  
    pt[3].y = 2*center.y - pt[1].y;  
}                      
#include"iostream"  #include"opencv2/opencv.hpp"    using namespace std;  using namespace cv;    int main()  {      Mat image(200, 200, CV_8UC3, Scalar(0));      RotatedRect rRect(Point2f(100, 100), Size2f(100, 50), 30);        Point2f vertices[4];      //定义矩形的4个顶点      rRect.points(vertices);   //计算矩形的4个顶点      for (int i = 0; i < 4; i++)          line(image, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0));        Rect brect = rRect.boundingRect(); //返回包含旋转矩形的最小矩形      rectangle(image, brect, Scalar(255, 0, 0));      imshow("rectangles", image);      waitKey(0);  }  
RotatedRect是一个存储旋转矩形的类,通常用来存储最小外包矩形函数minAreaRect( )和椭圆拟合函数fitEllipse( )返回的结果。存储的值,完全取决在于函数的返回

            

之前用到OpenCV最小外接矩形去表示一个类椭圆形的高度,特此记录备查。
对给定的 2D 点集,寻找最小面积的包围矩形,使用函数:
CvBox2D  cvMinAreaRect2( const CvArr* points, CvMemStorage* storage=NULL );

   points
   点序列或点集数组
   storage
   可选的临时存储仓
  函数 cvMinAreaRect2 通过建立凸外形并且旋转外形以寻找给定 2D 点集的最小面积的包围矩形。
其中返回的2D盒子定义如下:
1 typedef struct CvBox2D
2 {
3     CvPoint2D32f center; /* 盒子的中心 */
4     CvSize2D32f size; /* 盒子的长和宽 */
5     float angle; /* 水平轴与第一个边的夹角,用弧度表示*/
6 }CvBox2D;

注意夹角 angle 是水平轴逆时针旋转,与碰到的第一个边(不管是高还是宽)的夹角。如下图
                                 
  可用函数 cvBoxPoints(box[count], point); 寻找盒子的顶点
1  void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] )
2  {
3      double angle = box.angle*CV_PI/180.
4      float a = (float)cos(angle)*0.5f;
5      float b = (float)sin(angle)*0.5f;

7      pt[0].x = box.center.x - a*box.size.height - b*box.size.width;
8      pt[0].y = box.center.y + b*box.size.height - a*box.size.width;
9      pt[1].x = box.center.x + a*box.size.height - b*box.size.width;
10     pt[1].y = box.center.y - b*box.size.height - a*box.size.width;
11     pt[2].x = 2*box.center.x - pt[0].x;
12     pt[2].y = 2*box.center.y - pt[0].y;
13     pt[3].x = 2*box.center.x - pt[1].x;
14     pt[3].y = 2*box.center.y - pt[1].y;
15 }
简单证明此函数的计算公式:
 
   计算x,由图可得到三个方程式: pt[1].x - pt[0].x = width*sin(angle)
                             pt[2].x - pt[1].x = height*cos(angle)
                             pt[2].x - pt[0].x = 2(box.center.x - pt[0].x)
   联立方程可解得函数里的计算式,算 y 略。
写了个函数绘制CvBox2D
1  void DrawBox(CvBox2D box,IplImage* img)
2  {
3      CvPoint2D32f point[4];
4      int i;
5      for ( i=0; i<4; i++)
6      {
7          point[i].x = 0;
8          point[i].y = 0;
9      }
10     cvBoxPoints(box, point); //计算二维盒子顶点
11     CvPoint pt[4];
12     for ( i=0; i<4; i++)
13     {
14         pt[i].x = (int)point[i].x;
15         pt[i].y = (int)point[i].y;
16     }
17     cvLine( img, pt[0], pt[1],CV_RGB(255,0,0), 2, 8, 0 );
18     cvLine( img, pt[1], pt[2],CV_RGB(255,0,0), 2, 8, 0 );
19     cvLine( img, pt[2], pt[3],CV_RGB(255,0,0), 2, 8, 0 );
20     cvLine( img, pt[3], pt[0],CV_RGB(255,0,0), 2, 8, 0 );



                        
                        
                         
推荐阅读
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 判断数组是否全为0_连续子数组的最大和的解题思路及代码方法一_动态规划
    本文介绍了判断数组是否全为0以及求解连续子数组的最大和的解题思路及代码方法一,即动态规划。通过动态规划的方法,可以找出连续子数组的最大和,具体思路是尽量选择正数的部分,遇到负数则不选择进去,遇到正数则保留并继续考察。本文给出了状态定义和状态转移方程,并提供了具体的代码实现。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
author-avatar
林校帅哥美女排行榜_511
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有