/*OpenCV23在一个物体上绘制椭圆与矩形_轮廓周围绘制矩形 by txwtech
轮廓周围绘制矩形 -APIapproxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)
基于RDP算法实现,目的是减少多边形轮廓点数
cv::boundingRect(InputArray points)
得到轮廓周围最小矩形左上交点坐标和右下角点坐标,绘制一个矩形
cv::minAreaRect(InputArray points)
得到一个旋转的矩形,返回旋转矩形
轮廓周围绘制圆和椭圆-API cv::minEnclosingCircle(InputArray points, //得到最小区域圆形 Point2f& center, // 圆心位置 float& radius)// 圆的半径 cv::fitEllipse(InputArray points)得到最小椭圆
实现过程:
1.将图像变为二值图像 2.发现轮廓,找到图像轮廓 3.通过相关API在轮廓点上找到最小包含矩形和圆,旋转矩形与椭圆。 4.绘制出来
--------------------------- Microsoft Visual C++ Runtime Library --------------------------- Debug Assertion Failed!
Program: C:\windows\SYSTEM32\MSVCP140D.dll File: c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector Line: 1234
Expression: vector subscript out of range
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
--------------------------- 中止(A) 重试(R) 忽略(I) --------------------------- vector contours_ploy();//这样就是没有赋初值,报错
vector contours_ploy(contours.size());//这样就Ok
*/
#include
#include
using namespace std;
using namespace cv;
Mat src;
Mat src_gray;
Mat draw_image;
int threshold_min = 90;
int threshold_max = 255;
const char* out_window = "矩形输出结果";
RNG rng(12345);
void Contours_Func(int, void*);
int main(int argc, char *argv[])
{
src = imread("e:\\pictures\\热气球.jpg",CV_LOAD_IMAGE_COLOR);
if (!src.data)
{
printf("failed to load image");
return -1;
}
//namedWindow("原图",CV_WINDOW_AUTOSIZE);
//imshow("原图",src);
//转灰度图像
cvtColor(src, src_gray, CV_BGR2GRAY);
//模糊
blur(src_gray,src_gray,Size(3,3),Point(-1,-1));
const char* src_window = "原图";
namedWindow(src_window,CV_WINDOW_AUTOSIZE);
namedWindow(out_window,CV_WINDOW_AUTOSIZE);
imshow(src_window,src);
createTrackbar("threshold:",out_window,&threshold_min,threshold_max,Contours_Func);
Contours_Func(0,0);
waitKey(0);
return 0;
}
void Contours_Func(int, void*)
{
Mat binary_output;//二值图像
vector contours;
vector hierachy;
//阈值处理
threshold(src_gray,binary_output,threshold_min,threshold_max,THRESH_BINARY);
//发现轮廓
findContours(binary_output,contours,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(-1,-1));
vector contours_ploy(contours.size());//外接多边形
//找出最小矩形
vector ploy_rects(contours.size());;
vector ccs(contours.size());//圆心
vector radius(contours.size());//半径
vector minRect(contours.size());
vector myellipse(contours.size());
for (size_t i = 0; i < contours.size(); i++)
{
//true就是绘制封闭矩形
approxPolyDP(Mat(contours[i]),contours_ploy[i],3,true);
ploy_rects[i] = boundingRect(contours_ploy[i]);
minEnclosingCircle(contours_ploy[i],ccs[i],radius[i]);
if (contours_ploy[i].size() > 5)
{
myellipse[i] = fitEllipse(contours_ploy[i]);
minRect[i] = minAreaRect(contours_ploy[i]);
}
}
//src.copyTo(draw_image);//原图上画椭圆与矩形
draw_image = Mat::zeros(src.size(),src.type());//此句为在空白模板画
Point2f pts[4];
for (size_t t = 0; t < contours.size(); t++)
{
Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0, 255), rng.uniform(0, 255));
//rectangle(draw_image,ploy_rects[t],color,2,8);
//circle(draw_image,ccs[t],radius[t],color,2,8);
if (contours_ploy[t].size() > 5)
{
//画椭圆
ellipse(draw_image,myellipse[t],color,1,8);
minRect[t].points(pts);
//画4条线就是矩形
for (int r = 0; r < 4; r++)
{
line(draw_image,pts[r],pts[(r+1)%4],color,1,8);
}
}
}
//imshow(out_window, draw_image);//正常显示
imshow(out_window,~draw_image);//反色显示
}