OpenCV3图像处理——查找两张图像差异的地方并标记

版权声明:转载请注明出版 https://blog.csdn.net/matt45m/article/details/89294950

前言

1.有一个小游戏,就给出两张内容几乎差不多全部相同的图像,让大家在最快的时间内找出两个图像中有几处不同地方,我这里试着用OpenCV实现这个功能。
2.我的编程环境是Windows 7 64位,IDE是VS2015,配置了OpenCV3.3与OpenCV_Contrib,实现语言是C++。是于如果配置以上的环境,可以看我之前写的博文。

一、资源准备

可以在网上搜《图片大找茬》,然后下载两张相似的图像,但图像的大小必须一样。下面是我指用的两张图像。如果不一样,就用resize()这个函数去调整两张图像的尺寸。

在这里插入图片描述
在这里插入图片描述

二、代码演示

1.这里用到的是OpenCV图像基本运算,两图相减。使用的API是subtract()。
代码是传入两张图像的绝对路径

void imageSubtract(string image1_path, string image2_path)
{
	Mat image1_gary;
	Mat image2_gary;
	Mat image1 = imread(image1_path);
	if (image1.empty())
	{
		return;
	}
	imshow("原图1", image1);
	Mat image2 = imread(image2_path);
	if (image2.empty())
	{
		return;
	}
	if ((image1.rows != image2.rows) || (image1.cols != image2.cols))
	{
		if (image1.rows > image2.rows)
		{
			resize(image1, image1, image2.size(), 0, 0, INTER_LINEAR);
		}
		else if (image1.rows < image2.rows)
		{
			resize(image2, image2, image1.size(), 0, 0, INTER_LINEAR);
		}
	}

	cvtColor(image1, image1_gary, COLOR_BGR2GRAY);

	cvtColor(image2, image2_gary, COLOR_BGR2GRAY);

	Mat frameDifference, absFrameDifferece;
	Mat previousGrayFrame = image2_gary.clone();
	//图1减图2
	subtract(image1_gary, image2_gary, frameDifference, Mat(), CV_16SC1);

	//取绝对值
	absFrameDifferece = abs(frameDifference);

	//位深的改变
	absFrameDifferece.convertTo(absFrameDifferece, CV_8UC1, 1, 0);
	Mat segmentation;
	//阈值处理
	threshold(absFrameDifferece, segmentation, 112, 255, THRESH_BINARY);

	//中值滤波
	medianBlur(segmentation, segmentation, 3);

	//形态学处理(开闭运算)
	//形态学处理用到的算子
	Mat morphologyKernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
	morphologyEx(segmentation, segmentation, MORPH_CLOSE, morphologyKernel, Point(-1, -1), 2, BORDER_REPLICATE);

	//显示二值化图片
	imshow("segmentation", segmentation);

	//找边界
	vector< vector<Point> > contours;
	vector<Vec4i> hierarchy;
	findContours(segmentation, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));//CV_RETR_TREE
	vector< vector<Point> > contours_poly(contours.size());

	vector<Rect> boundRect;
	boundRect.clear();

	for (int index = 0; index < contours.size(); index++)
	{
		approxPolyDP(Mat(contours[index]), contours_poly[index], 3, true);
		Rect rect = boundingRect(Mat(contours_poly[index]));
		rectangle(image2, rect, Scalar(0, 255, 0), 2);
	}

	imshow("效果图", image2);
}

2.运行效果
在这里插入图片描述

结语

1.例子很简单,但是这个方法用到移动目标追踪的上去,就是两帧差。
2.关于工程的源码,运行程序时的bug,都可以加这个群(487350510)互相讨论学习。

猜你喜欢

转载自blog.csdn.net/matt45m/article/details/89294950