获取轮廓的最小外接矩形
2017-08-27 16:16
344 查看
本文主要实现了轮廓的最小面积外接矩形:
(1)对获取的凸包点,计算凸包线的角度;
(2)将凸包点按照计算的凸包线角度进行旋转;
(3)获取旋转后的点在x、y两方向上各自的最大最小值;
(4)利用获取的最大最小值计算此时最小外接矩形的面积。
typedef struct min_area_rect
{
point_t* pt;
int width;
int height;
float angle;
}min_area_rect_t;
min_area_rect_t* get_rotate_rect(IplImage* img, point_t *p, const int num);
实现效果:
(1)对获取的凸包点,计算凸包线的角度;
(2)将凸包点按照计算的凸包线角度进行旋转;
(3)获取旋转后的点在x、y两方向上各自的最大最小值;
(4)利用获取的最大最小值计算此时最小外接矩形的面积。
typedef struct min_area_rect
{
point_t* pt;
int width;
int height;
float angle;
}min_area_rect_t;
min_area_rect_t* get_rotate_rect(IplImage* img, point_t *p, const int num);
#include "min_area_rect.h" //计算凸包线角度 float* get_angle(point_t *p,const int num) { float* angle = (float*)malloc(num * sizeof(float)); float temp = 0; for (int i = 0; i < num - 1; i++) { temp = atan2(p[i + 1].y - p[i].y,p[i + 1].x - p[i].x); if (temp < 0) temp += PI / 2; angle[i] = -temp; } return angle; } //剔除冗余角度 unsigned int* angle_unique(float* angle,const int num) { unsigned int* state = (int*)malloc(num * sizeof(unsigned int)); for (int i = 0; i < num; i++) state[i] = 1; for (int i = 0; i < num; i++) { for (int j = i + 1; j < num; j++) { if (angle[i] == angle[j]) state[j] = 0; } } return state; } //计算旋转凸包点坐标 point_t* get_rotate_point(point_t* p,float theta, const int num) { point_t* r_p = (point_t*)malloc(num * sizeof(point_t)); for (int i = 0; i < num; i++) { r_p[i].x = p[i].x * cos(theta) - p[i].y * sin(theta); r_p[i].y = p[i].x * sin(theta) + p[i].y * cos(theta); } return r_p; } //计算旋转后凸包点的坐标对应的原始坐标 point_t* get_remap_point(point_t* p, float theta) { point_t* r = (point_t*)malloc(4 * sizeof(point_t)); for (int i = 0; i < 4; i++) { r[i].x = p[i].x * cos(theta) + p[i].y * sin(theta); r[i].y = -p[i].x * sin(theta) + p[i].y * cos(theta); } return r; } float get_distance(const point_t p1, const point_t p2) { return sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y)); } min_area_rect_t* get_rotate_rect(IplImage* img, point_t *p, const int num) { float* angle; unsigned int* state; point_t* r_p = NULL; point_t* rect_p = (point_t*)malloc(4 * sizeof(point_t)); angle = get_angle(p, num); state = angle_unique(angle, num); float min_area = 100000.; float min_angle = 0.; for (int i = 0; i < num; i++) { float area = 0.0; float max_x = -1000; float min_x = 1000; float max_y = -1000; float min_y = 1000; if (state[i] == 1) { r_p = get_rotate_point(p, angle[i], num); for (int j = 0; j < num; j++) { if (r_p[j].x > max_x) max_x = r_p[j].x; if (r_p[j].x < min_x) min_x = r_p[j].x; if (r_p[j].y > max_y) max_y = r_p[j].y; if (r_p[j].y < min_y) min_y = r_p[j].y; } area = ((max_x - min_x) * (max_y - min_y)); if (area < min_area) { min_area = area; min_angle = angle[i]; rect_p[0].x = min_x; rect_p[0].y = min_y; rect_p[1].x = min_x; rect_p[1].y = max_y; rect_p[2].x = max_x; rect_p[2].y = min_y; rect_p[3].x = max_x; rect_p[3].y = max_y; } } } min_area_rect_t* _minAreaRect = (min_area_rect_t*)malloc(sizeof(min_area_rect_t)); _minAreaRect -> pt = get_remap_point(rect_p, min_angle); _minAreaRect->width = get_distance(rect_p[0],rect_p[1]); _minAreaRect->height = get_distance(rect_p[0],rect_p[2]); _minAreaRect->angle = min_area; free(angle); free(state); free(r_p); free(rect_p); return _minAreaRect; }
实现效果:
相关文章推荐
- Opencv寻找轮廓的最小外接矩形,并获取矩形的中心点,旋转角度
- 使用OpenCv的cvMinAreaRect2函数获取轮廓的可倾斜最小矩形区域
- 利用cvMinAreaRect2求取轮廓最小外接矩形
- opencv(23)---轮廓特征属性及应用之最小外接矩形
- 获取shapefile文件最小包围矩形的c++程序
- 利用cvMinAreaRect2求取轮廓最小外接矩形
- 【opencv学习之三十四】轮廓特征应用:最小外接矩形和圆
- opencv之轮廓最小外接矩形和最小外接圆
- OpenCV环境下绘制轮廓的外接多边形、最小立式矩形、最小外接圆
- opencv 轮廓的长度,面积,外接矩形(平行坐标轴),处接最小矩形,处接圆 , 椭圆
- 获取限制x值范围内轮廓的y值最小的点
- cvMinAreaRect2和CvBox2D求取轮廓最小外接矩形中遇到的问题!
- 利用cvMinAreaRect2求取轮廓最小外接矩形
- OpenCV轮廓、边界框、最小矩形、最小闭圆检测
- 利用minAreaRect求轮廓最小外接矩形
- C/C++ 图像处理(16)------图像轮廓の最小外接矩形
- 利用cvMinAreaRect2求取轮廓最小外接矩形
- opencv 轮廓的长度,面积,外接矩形(平行坐标轴),处接最小矩形,处接圆 , 椭圆
- Opencv 轮廓 逼近多边形曲线 正外接矩形 外接最小矩形
- 获取轮廓中心点,并且判断是否在一个矩形区域内