opencv中对Mat类型图像感兴趣(ROI)轮廓外接矩形并截取保存结果
最近自己在用opencv做图像实验时,要对轮廓外接矩形,网上大多是对IplImage类型图像做处理,而现在opencv中Mat取代了IplImage类型的图像,IplImage类型存储比Mat类型复杂,而且不如Mat类型图像访问方便,比如IplImage类型图像访问每个点的像素时,要计算步长如srcimage->imageData[i+j*srcimage->widthStep],看起来就很是繁琐,Mat类型图像srcimage.at<uchar>(i,j)即可,很方便。
话不多说,进入正题。
IplImage类型的图像用cvSetImageRIO()函数即可,具体使用代码如下:
cvSetImageROI(frame,((CvContour*)c)->rect);//frame为源图像,((CvContour*)c)->rect就是CvSeq *c;
Mat类型图像处理如下:
大致步骤:
1、用findContours()检测轮廓,具体参数可以上百度或借阅资料参考;
2、用approxPolyDP()求出多边形近似,参数如下的代码;
3、利用boundingRect()得到每个轮廓外接矩形的数据结构信息,存在boundRect[i]中;
4、image(boundRect[i])得到每个轮廓外接矩形的结果图像,可以存储到指定文件夹。
具体看代码(一些主要语句):
//轮廓检测
cv::vector<vector<Point>> contours;//定义轮廓集合
cv::vector<Vec4i> hierarchy;
cv::findContours(thinDoublexy,contours,hierarchy,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,Point(0,0));//thinDoublexy为需要查找轮廓的图像,其他参数借阅资料。
Mat drawing=Mat::zeros(thinDoublexy.size(),CV_8UC3);
cv::vector<vector<Point>> conpoint(contours.size());
cv::vector<Rect> boundRect(contours.size());
for(int i=0;i<contours.size();i++)
{
approxPolyDP(Mat(contours[i]),conpoint[i],3,true);//多边形近似
boundRect[i]=boundingRect(Mat(conpoint[i]));//得到轮廓外接矩形数据结构
cv::drawContours(drawing,contours,i,255,2,8,hierarchy,0,Point());//画出轮廓得到图像drawing
if(boundRect[i].area()>4) //有些轮廓就是一个点,要舍去
{
cv::Mat imageROI=image(boundRect[i]);//根据轮廓外接矩形信息进行截取RIO感兴趣部分图像
std::stringstream ss;//int转换为string
std::string str;
ss<<i;
ss>>str;
string tempname = pathWrite+"\\" + str + "result.jpg";<span style="font-family: Arial, Helvetica, sans-serif;">//pathWrite变量是文件夹路径
imwrite(tempname.c_str(),imageROI);//存储图像至指定文件夹
//cout<<tempname<<endl;
//imshow(tempname,imageROI);
}
}
上述代码亲测有效,运行结果如下,只是我做一下说明:代码是部分代码,只是实现Mat类型图像的轮廓外接矩形并保存结果图像的功能,要想代码跑起来,肯定需要加一些定义部分的代码。我自己也是初学者,如果你发现不对的地方,敬请指正,谢谢!
运行结果:
源图像
运行结果