opencv中對Mat型別影象感興趣(ROI)輪廓外接矩形並擷取儲存結果

opencv中對Mat型別影象感興趣(ROI)輪廓外接矩形並擷取儲存結果

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型別影象的輪廓外接矩形並儲存結果影象的功能,要想程式碼跑起來,肯定需要加一些定義部分的程式碼。我自己也是初學者,如果你發現不對的地方,敬請指正,謝謝!

執行結果:

源影象

執行結果