最近为了实现运动物体的检测这一功能,在网络上找了许多材料,但是大都不容易实现或者晦涩难懂,于是决定从基础入手,先对两张大小相同但略有差异的两张图片进行操作,基本步骤是首先对两张图片进行相减操作,把差值图放在另外一张大小相同的图上,之后对这张图进行阙值化操作,然后再寻找轮廓,用矩形圈去轮廓。
在创建差图时找到了两种方法,一种是 //Mat dif=src1.clone();利用clone()函数来创建,一种是Mat dif; dif.create(src1.size(), src1.type());;利用creat()函数创建,这两种方法都是创建跟原始图一样的图,但是区别在于clone(),是复制,新建的图含有元素,create创建的新图是空的。这里推荐使用第二种。
在做两图相减时也找到两种方法addWeighted(src1, 1, src2, 1, 0., dif);利用两图相加,但第二个图片的权重为-1进行相减,和absdiff(gray1, gray2, dif);两个图片的相减。两种方法都能实现图片相减的功能,这里主要理解到加减的内在联系,推荐使用第二种方法。
具体代码如下
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
Mat src1 = imread("1.jpg");
Mat src2 = imread("2.jpg");
//创建相同大小和类型的图
Mat dif;
//Mat dif=src1.clone();
dif.create(src1.size(), src1.type());
//创建窗口
namedWindow("图1", WINDOW_NORMAL);
namedWindow("图2", WINDOW_NORMAL);
namedWindow("差图", WINDOW_NORMAL);
//使窗口有序排列
cvMoveWindow("图1", 30, 0);
cvMoveWindow("图2", 360, 0);
cvMoveWindow("差图", 690, 0);
//转化为灰度值图片
Mat gray1, gray2;
//cvtColor(src1, gray1, CV_BGR2GRAY);
//cvtColor(src2, gray2, CV_BGR2GRAY);
//两图相减
absdiff(src1, src2, dif);
//addWeighted(src1, 1, src2, -1, 0., dif);
//对差值图dif_thresh进行阈值化处理
Mat dif_thresh = dif.clone();
cvtColor(dif, dif, CV_BGR2GRAY);
threshold(dif, dif, 50, 255, CV_THRESH_BINARY);
// 查找轮廓并绘制轮廓
vector<vector<Point>> contours;//contours被定义成二维浮点型向量,用来存储找到的边界的(x,y)坐标。
vector<Vec4i> hierarchy;
findContours(dif, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
drawContours(dif_thresh, contours, -1, Scalar(0, 255, 0), 1, 8);//在dif_thresh上绘制轮廓
//7.查找正外接矩形
int width = 0;
int height = 0;
int x = 0;
int y = 0;
vector<Rect> boundRect(contours.size());
for (int i = 0; i < contours.size(); i++)
{
boundRect[i] = boundingRect(Mat(contours[i]));
//2获得正外接矩形的左上角坐标及宽高
width = boundRect[i].width;
height = boundRect[i].height;
x = boundRect[i].x;
y = boundRect[i].y;
rectangle(dif_thresh, boundRect[i], Scalar(0, 255, 0), 2);//在dif_thresh上绘制正外接矩形
}
//显示图片
imshow("图1", src1);
imshow("图2", src2);
imshow("差图", dif_thresh);
waitKey(0);
}