具体问题交流请联系:clr_mv@163.com
更多文章请关注微信公众号:机器视觉专业论坛
本例中采用halcon的图像序列来简单分析车辆的流动,分析方法较为简单,通过
前后两幅图像的对比来进行,因此鲁棒性不强。
本例中学习到的知识主要有:
1.Videocapture类读入图像序列时对于PNG格式的图像无效。
2.在进行图像复制时不可以简单的使用“=”,需要copyto或者clone。
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
string file ;
RNG rng(12345);
Mat intimage, image, diff, offset, imagecolor, intimagecolor,tim;
file = "G:\\OpencvStudy\\Test3\\data\\xing\\init.png";
intimagecolor = cv::imread(file);
if (intimagecolor.empty())
return -1;
cvtColor(intimagecolor, intimage, CV_RGB2GRAY);
for (int i = 0; i < 586; i++)
{
string s;
char t[256];
sprintf_s(t, "%03d", i);
s = t;//int 转化为String
file = "G:\\OpencvStudy\\Test3\\data\\xing\\xing" + s + ".png";
imagecolor = cv::imread(file);
if (imagecolor.empty())
break;
cvtColor(imagecolor, image, CV_RGB2GRAY);//转化为灰度图,便于后续分析
GaussianBlur(image, image, Size(3, 3), 0.4, 0.4);
GaussianBlur(intimage, intimage, Size(3, 3), 0.4, 0.4);//对前后两幅图滤波
absdiff(image, intimage, diff);//求取前后两幅图不同的区域
intimage = image.clone();//保留初始图像,为下一帧图像分析准备
addWeighted(diff, 0.5, diff, 0.5, -35,diff);//参见halcon 的函数dyn_threshold
imshow("track", diff);
Mat threshold_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// 使用Threshold对图像二值化
threshold(diff, threshold_output, 10, 255, THRESH_BINARY);
cv::Mat element5(2, 2, CV_8U, cv::Scalar(1));
cv::Mat open;
cv::morphologyEx(diff, open, cv::MORPH_OPEN, element5);
cv::Mat element15(8, 8, CV_8U, cv::Scalar(1));
cv::Mat close;
cv::morphologyEx(open, close, cv::MORPH_CLOSE, element15);
/// 找到轮廓
findContours(close, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
/// 多边形逼近轮廓 + 获取矩形和圆形边界框
vector<vector<Point> > contours_poly(contours.size());
vector<Rect> boundRect(contours.size());
vector<Point2f>center(contours.size());
vector<float>radius(contours.size());
for (int i = 0; i < contours.size(); i++)
{
approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);
boundRect[i] = boundingRect(Mat(contours_poly[i]));
minEnclosingCircle(contours_poly[i], center[i], radius[i]);
}
/// 画多边形轮廓 + 包围的矩形框 + 圆形框
Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)
{
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
//drawContours(drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point());
rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);
//circle(drawing, center[i], (int)radius[i], color, 2, 8, 0);
}
imshow("Drawing", drawing);
add(imagecolor, drawing, imagecolor);
imshow("Image sequence", imagecolor);
waitKey(5);//每隔5毫秒再读下一幅图像
}
return 0;
}
本文分析思路较为简单,主要是为了熟悉Opencv相应算法。