我們很容易用findContours()函數(shù)將圖像中的輪廓提取出來,但是并沒有將輪廓所包圍的圖像輸出的函數(shù),以下是幾個(gè)有類似功能的函數(shù):
cvimageroi():得到包圍ROI(感興趣區(qū)域)的矩形區(qū)域,可以直接把輪廓點(diǎn)集作為參數(shù)給進(jìn)去然后返回包圍這個(gè)輪廓的最佳矩形點(diǎn)集,然后再用Mat的成員函數(shù)Mat(Rec)把這個(gè)區(qū)域提取出來。遺憾的是這樣只能提取矩形區(qū)域,無法提取不規(guī)則區(qū)域。
boundingRect():這個(gè)同上一個(gè)是一樣的功能,也是得到矩形區(qū)域。
進(jìn)入正題
首先將原圖像灰度化,二值化,然后提取輪廓,進(jìn)行排除、去噪處理之后用drawContours()函數(shù)把輪廓填充為白色。具體做法是:
Mat hole(res.size(), CV_8U, Scalar(0)); //新建一個(gè)黑色的遮罩圖層
cv::drawContours(hole, contours1, -1, Scalar(255), CV_FILLED); //在遮罩圖層上,將輪廓里面的空間用白色像素填充
之后將原圖用copyTo()函數(shù)疊加到遮罩圖層上,就大功告成了。
- #include "opencv2/imgproc.hpp"
- #include "opencv2/highgui.hpp"
- #include <iostream>
- using namespace cv;
- using namespace std;
- void main() {
- Mat original = imread("D:\\res.png");
- namedWindow("My original");
- imshow("My original", original);
- Mat gray = original;
- cv::cvtColor(gray, gray, CV_RGB2GRAY);//灰度化
-
- int thresh_size = (100 / 4) * 2 + 1; //自適應(yīng)二值化閾值
- adaptiveThreshold(gray, gray, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY_INV, thresh_size, thresh_size / 3);
- morphologyEx(gray, gray, MORPH_OPEN, Mat());//形態(tài)學(xué)開運(yùn)算去噪點(diǎn)
-
- vector<vector<Point> > contours;
- cv::findContours(gray, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); //找輪廓
- vector<vector<Point>> contours1;
- for (int i = 0; i < contours.size(); ++i)
- {
- if (contours[i].size() > 200)//將比較小的輪廓剔除掉
- {
- contours1.push_back(contours[i]);
- }
- }
- /*可以加入以下功能*/
- //vector<vector<Point>> contours2;
- //vector<Point> approx_poly;//存放頂點(diǎn)
- //for (int i = 0; i < contours1.size(); ++i)
- //{
- //double eps = contours1[i].size()*0.08;//精度
- //approxPolyDP(contours1[i], approx_poly, eps, true);//用另一條頂點(diǎn)較少的曲線來逼近一條曲線或者一個(gè)多邊形
- //if ((approx_poly.size() != 4) || (!isContourConvex(approx_poly)))//提取只有4個(gè)頂點(diǎn)的輪廓和凸多邊形
- //{
- // continue;
- //}
- //else {
- //contours2.push_back(contours1[i]);
- //}
- //}
- Mat hole(gray.size(), CV_8U, Scalar(0)); //遮罩圖層
- cv::drawContours(hole, contours1, -1, Scalar(255), CV_FILLED); //在遮罩圖層上,用白色像素填充輪廓
- namedWindow("My hole");
- imshow("My hole", hole);
- Mat crop(original.rows, original.cols, CV_8UC3);
- original.copyTo(crop, hole);//將原圖像拷貝進(jìn)遮罩圖層
- namedWindow("My warpPerspective");
- imshow("My warpPerspective", crop);
- waitKey(0);
- }
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點(diǎn)擊舉報(bào)。