使用自定义内核给图像做卷积操作

使用C++、opencv创建自定义内核(卷积核),使用内核给图像做卷积操作

关于图像卷积的原理及知识可参考博客https://www.cnblogs.com/bithuaning/p/6924978.html,说的非常详细。

opencv中的相关API:

void filter2D( InputArray src, OutputArray dst, int ddepth,
                            InputArray kernel, Point anchor=Point(-1,-1),
                            double delta=0, int borderType=BORDER_DEFAULT );

InputArray src: 输入图像

OutputArray dst: 输出图像,和输入图像具有相同的尺寸和通道数量

int ddepth: 目标图像深度,如果没写将生成与原图像深度相同的图像。原图像和目标图像支持的图像深度如下:

    src.depth() = CV_8U, ddepth = -1/CV_16S/CV_32F/CV_64F
    src.depth() = CV_16U/CV_16S, ddepth = -1/CV_32F/CV_64F
    src.depth() = CV_32F, ddepth = -1/CV_32F/CV_64F
    src.depth() = CV_64F, ddepth = -1/CV_64F
当ddepth输入值为-1时,目标图像和原图像深度保持一致。

InputArray kernel: 卷积核(或者是相关核),一个单通道浮点型矩阵。如果想在图像不同的通道使用不同的kernel,可以先使用split()函数将图像通道事先分开。

Point anchor: 内核的基准点(anchor),其默认值为(-1,-1)说明位于kernel的中心位置。基准点即kernel中与进行处理的像素点重合的点。

double delta: 在储存目标图像前可选的添加到像素的值,默认值为0

int borderType: 像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。

以上参考:http://www.javashuo.com/article/p-pzwehvet-kg.html

------------------------------------------------------------------

代码实现:

#include "stdafx.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

int main()
{
	system("color 02");
	//读取原图
	cv::Mat src = cv::imread("D:\\哀.jpg");
	//自定义内核
	cv::Mat kernel = (cv::Mat_<float>(3, 3) << 1, 1, 1,
				                1, -7.5, 1,	
				                1, 1, 1);
	cv::Mat dst;
	//卷积操作
	cv::filter2D(src, dst, src.depth(), kernel);

	cv::namedWindow("dst", CV_WINDOW_NORMAL);
	cv::imshow("dst", dst);
	cv::waitKey();

    return 0;
}

源图像:

 结果图: