contours
被定义成二维浮点型向量,这里面将来会存储找到的边界的(x,y)坐标。vector
是定义的层级。这个在找边界findcontours
的时候会自动生成,这里只是给它开辟一个空间。将来findContours( src, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
就能算出边界的坐标,存在contours
里面。
typedef Vec
Vec4i
指的是四个整形数
膨胀:高亮区域增长(取局部MAX)
腐蚀:暗部地区增长(取局部MIN)
inRange
过滤void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)
morphologyEx(mask, mask, MORPH_OPEN, kernel1, Point(-1, -1), 1); // 开操作
dilate(mask, mask, kernel2, Point(-1, -1), 4);// 膨胀
void processFrame(Mat &binary, Rect &rect) {
vector> contours;//储存轮廓点(二维向量)
vector hireachy; //轮廓层次信息
findContours(binary, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));//查找轮廓
if (contours.size() > 0) {
double maxArea = 0.0;
for (size_t t = 0; t < contours.size(); t++) { //几个轮廓遍历
double area = contourArea(contours[t]);
if (area > maxArea) {//寻找面积最大的轮廓
maxArea = area;
rect = boundingRect(contours[t]);
}
}
}
else {
rect.x = rect.y = rect.width = rect.height = 0;
}
}
#include
#include
using namespace std;
using namespace cv;
Rect roi;
void processFrame(Mat &binary, Rect &rect);
int main(int argc, char* argv) {
// load video
VideoCapture capture;
capture.open("006.mp4");
if (!capture.isOpened()) {
printf("could not find video file");
return -1;
}
Mat frame, mask;
Mat kernel1 = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
Mat kernel2 = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
namedWindow("input video", CV_WINDOW_AUTOSIZE);
namedWindow("track mask", CV_WINDOW_AUTOSIZE);
while (capture.read(frame)) {
inRange(frame, Scalar(0, 127, 0), Scalar(120, 255, 120), mask); // 过滤
morphologyEx(mask, mask, MORPH_OPEN, kernel1, Point(-1, -1), 1); // 开操作
dilate(mask, mask, kernel2, Point(-1, -1), 4);// 膨胀
imshow("track mask", mask);
// 使用经过颜色过滤后的图像来实现轮廓发现与位置标定,返回ROI矩形
processFrame(mask, roi);
//利用对角线两点来画矩形:
//void rectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness = 1, int lineType = 8, int shift = 0)
// 传入矩形参数来画矩形:
//void rectangle(Mat& img, Rect rec, const Scalar& color, int thickness = 1, int lineType = 8, int shift = 0)
//得到位置后在原图像上画出ROI
rectangle(frame, roi, Scalar(0, 0, 255), 3, 8, 0);
imshow("input video",frame);
// trigger exit
char c = waitKey(100);
if (c == 27) {
break;
}
}
capture.release();
waitKey(0);
return 0;
}
void processFrame(Mat &binary, Rect &rect) {
vector> contours;//储存轮廓点(二维向量)
vector hireachy; //轮廓层次信息
findContours(binary, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));//查找轮廓
if (contours.size() > 0) {
double maxArea = 0.0;
for (size_t t = 0; t < contours.size(); t++) { //几个轮廓遍历
//double area = contourArea(contours[static_cast(t)]);
double area = contourArea(contours[t]);
if (area > maxArea) {//寻找面积最大的轮廓
maxArea = area;
//rect = boundingRect(contours[static_cast(t)]);
rect = boundingRect(contours[t]);
}
}
}
else {
rect.x = rect.y = rect.width = rect.height = 0;
}
}