C++OpenCV图像处理(九)图像形态学及模板匹配

这段代码展示了如何使用OpenCV进行形态学操作,包括开操作、闭操作、梯度、顶帽和黑帽操作,以及模板匹配。在形态学操作中,通过调整结构元素大小改变处理效果。模板匹配部分则计算了图像与模板之间的相似度,并将最佳匹配区域复制到目标图像上。
摘要由CSDN通过智能技术生成

void QuickDemo::elementsizechange_open_demo(Mat& image) {
	//开操作
	Mat dst;
	int elementsize = 3;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(elementsize * 2 + 1, elementsize * 2 + 1));//保证是奇数
	morphologyEx(image, dst, MORPH_OPEN, kernel);
	imshow("OPEN", dst);
}

void QuickDemo::elementsizechange_close_demo(Mat& image) {
	//闭操作
	Mat dst;
	int elementsize = 3;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(elementsize * 2 + 1, elementsize * 2 + 1));
	morphologyEx(image, dst, MORPH_CLOSE, kernel);
	imshow("CLOSE", dst);
}

void QuickDemo::elementsizechange_gradient_demo(Mat& image) {
	//形态学梯度
	Mat dst;
	int elementsize = 3;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(elementsize * 2 + 1, elementsize * 2 + 1));
	morphologyEx(image, dst, MORPH_GRADIENT, kernel);
	imshow("GRADIENT", dst);
}

void QuickDemo::elementsizechange_tophat_demo(Mat& image) {
	//顶帽操作
	Mat dst;
	int elementsize = 3;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(elementsize * 2 + 1, elementsize * 2 + 1));
	morphologyEx(image, dst, MORPH_TOPHAT, kernel);
	imshow("TOPHAT", dst);

}
void QuickDemo::elementsizechange_blackhat_demo(Mat& image) {
	Mat dst;
	int elementsize = 3;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(elementsize * 2 + 1, elementsize * 2 + 1));
	morphologyEx(image, dst, MORPH_BLACKHAT, kernel);
	imshow("BLACKHAT", dst);
}

模板匹配如下所示:


void QuickDemo::template_match_demo(Mat* pTo, Mat* pTemplate, Mat* src) {
	//模板匹配
	int i, j, m, n;
	double dSumT;//模板元素的平均和
	double dSumS;//图像子区域元素的平均和
	double dSumST;//图像子区域和模板的点积
	double R;//响应值
	double MaxR;//记录当前的最大响应
	//最大响应出现的位置
	int nMaxX;
	int nMaxY;
	int nHeight = src->rows;
	int nwidth = src->cols;
	//模板的高和宽
	int nTplHeight = pTemplate->rows;
	int nTplwidth = pTemplate->cols;
	//计算dSumT
	dSumT = 0;
	for (m = 0; m < nTplHeight; m++) {
		for (n = 0; n < nTplwidth; n++) {
			//模板图像第m行,第n个像素的灰度值
			int nGray = *pTemplate->ptr(m, n);
			dSumT += (double)nGray * nGray;
		}
	}
	//找到图像中最大响应的出现位置
	MaxR = 0;
	for (i = 0; i < nHeight - nTplHeight + 1; i++) {
		for (j = 0; j < nwidth - nTplwidth + 1; j++) {
			dSumST = 0;
			dSumS = 0;
			for (m = 0; m < nTplHeight; m++) {
				for (n = 0; n < nTplwidth; n++) {
					// 原图像第i+m行,第j+n列象素的灰度值
					int nGraySrc = *src->ptr(i + m, j + n);
					//模板图像第m行,第n个像素的灰度值
					int nGrayTp1 = *pTemplate->ptr(m, n);
					dSumS += (double)nGraySrc * nGraySrc;
					dSumST += (double)nGraySrc * nGrayTp1;
				}
			}
			R = dSumS / (sqrt(dSumS) * sqrt(dSumT));//计算相应响应
			//与最大相似性比较
			if (R > MaxR) {
				MaxR = R;
				nMaxX = j;
				nMaxY = i;
			}
		}
		//将找到的最佳匹配区域复制到模板图像
		for (int m=0; m < nTplHeight; m++) {
			for (n = 0; n < nTplwidth; n++) {
				int nGray = *src->ptr(nMaxY + m, nMaxX + n);
				//pTo->setTo(nMaxX + n, nMaxY + m, RGB(nGray, nGray, nGray));
				pTo->at<BYTE>(nMaxY + m, nMaxX + n) = nGray;
			}
		}
	}
}

main文件如下所示:

#include<opencv2/opencv.hpp>
#include<iostream>
#include<quickopencv.h>
using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	Mat src = imread("D:\\testImage\\1.jpg",0);
	Mat template_image = imread("D:\\testImage\\12.jpg", 0);
	Mat pt = src;
	if (src.empty()) {
		printf("could not load image...");
		return -1;
	}
	//如果图像过于大,不能完全显示整张图像可以使用namedWindow()可以实现对图像的自由缩放
	pt.data = new BYTE[src.cols * src.rows];
	memset(pt.data, 255, src.cols * src.rows);
	QuickDemo qd;
	qd.template_match_demo(&pt, &template_image, &src);

	imshow("S", src);
	imshow("T", template_image);
	imshow("P", pt);
	
	imwrite("S.jpg", src);
	imwrite("T.jpg", template_image);
	imwrite("P.jpg", pt);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI炮灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值