图像处理之卷积操作(C++)

图像处理之卷积操作(C++)



前言

卷积是图像处理中最基本且重要的概念,使用C++实现图像的卷积运算。


一、原理

步骤:
1.翻转卷积核;
2.对图像边缘进行填充;
3.对卷积核和图像执行相关性计算。(注意:相关和卷积的关系)
相关性计算公式

二、代码实现

#include <iostream>
#include <opencv.hpp>
using namespace std;

/*基于opencv实现的卷积运算*/
void test()
{
	cv::Mat kernel = (cv::Mat_<float>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);

	cv::Mat src = (cv::Mat_<uchar>(4, 4) << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
	cv::Mat dst;
	cv::filter2D(src, dst, CV_32F, kernel);
	
	for (int i = 0; i < dst.rows; i++)
		for (int j = 0; j < dst.cols; j++)
			cout << dst.at<float>(i, j) << endl;
}

/*
* @param cv::Mat src	输入图像
* @param cv::Mat dst	输出图像
* @param cv::Mat kernel	卷积核
* @param int stride		步长
* @breif	自己实现的卷积运算
*/
void myConv(cv::Mat& src, cv::Mat& dst,cv::Mat& kernel,int stride)
{
	//1.翻转卷积核180°(OpenCV中卷积核没有翻转)
	cv::flip(kernel, kernel, 0);

	//2.复制边界填充(OpenCV中采用是 CV_HAL_BORDER_REFLECT_101)
	int top, bottom ,right, left;
	top = bottom = ((src.rows - 1) * stride + kernel.rows - src.rows)/2;	//计算需要padding的值
	right=left= ((src.cols - 1) * stride + kernel.cols - src.cols) / 2;
	cv::copyMakeBorder(src, src, top, bottom, left, right, CV_HAL_BORDER_REFLECT_101);

	//3.执行卷积计算
	dst.convertTo(dst, CV_32F);
	for(int i=0;i<src.rows-kernel.rows+1;i++)
		for (int j = 0; j < src.cols-kernel.cols+1; j++)
		{
			int sum = 0;
			for(int m=0;m<kernel.rows;m++)
				for (int n = 0; n < kernel.cols; n++)
				{
					sum += kernel.at<float>(m, n) * src.at<uchar>(i+m, j+n);
				}
			cout << sum << endl;
			dst.at<float>(i, j) = sum;
		}
}


int main()
{
	//opencv卷积测试
	test();

	//自定义卷积测试
	cv::Mat kernel = (cv::Mat_<float>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);

	cv::Mat src = (cv::Mat_<uchar>(4, 4) << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
	cv::Mat dst(src.size(),CV_8U);
	myConv(src, dst, kernel, 1);

	cv::waitKey(0);
	return 0;
}

总结

自己手动C++实现了图像卷积的计算,明确了卷积和相关性的关系,探析了opencv内部卷积的实现实际上是相关性计算,没有对卷积核进行翻转,采用的图像填充的方式是CV_HAL_BORDER_REFLECT_101。欢迎大家验证。
因为笔者水平有限,有错误欢迎指出,代码本人均在本地运行实验正确,大家放心使用。

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值