• 『OpenCV3』滤波器实现及使用滤波器降噪


    一、滤波器实现

    我们实现这样一个基于拉普拉斯算子的滤波器核心,并使用它进行滤波,这可以做到锐化图像的效果,

    0 -1 0
    -1 5 -1
    0 -1 0

    首先我们完全手动的进行滤波,依赖指针操作,

    void sharpen(const cv::Mat &image, cv::Mat &result) {
    	result.create(image.size(), image.type());
    	std::cout << image.size() << std::endl;
    	int col = image.cols;
    	int row = image.rows;
    	int channels = image.channels();
    	
    	for (int i = 1; i < row - 1; i++ ) {
    		// 必须添加const,因为image是const的
    		const uchar* previous_row = image.ptr<uchar>(i - 1);
    		const uchar* current_row = image.ptr<uchar>(i);
    		const uchar* next_row = image.ptr<uchar>(i + 1);
    
    		uchar* out_line = result.ptr<uchar>(i);
    		for (int j = channels; j < (col - 1)*channels; j++) {
    			// cv::saturate_cast<uchar>将输入截断在0到255
    			*out_line++ = cv::saturate_cast<uchar>(
    				5 * current_row[j] - current_row[j - channels] - current_row[j + channels]
    				- previous_row[j] - next_row[j]);
    		}
    	}
    	result.row(0).setTo(cv::Scalar(0,0,0));
    	result.row(row - 1).setTo(cv::Scalar(0, 0, 0));
    	result.col(0).setTo(cv::Scalar(0, 0, 0));
    	result.col(col - 1).setTo(cv::Scalar(0,0,0));
    }
    

    OpenCV提供了cv::filter2D函数,当我们指定滤波核(一个Mat格式数据)可以自动代我们完成循环过程,依赖API实现本函数如下:

    void sharpen2D(const cv::Mat image, cv::Mat &result) {
    	cv::Mat kernel(3, 3, CV_32F, cv::Scalar(0));
    	kernel.at<float>(1, 1) = 5;
    	kernel.at<float>(0, 1) = -1;
    	kernel.at<float>(1, 0) = -1;
    	kernel.at<float>(2, 1) = -1;
    	kernel.at<float>(1, 2) = -1;
    	cv::filter2D(image, result, image.depth(), kernel);
    }
    

    对两个版本函数都进行调用,

    	cv::Mat image = cv::imread("test.jpg");
    	std::cout << (int)image.data << std::endl;
    
    	// 自行锐化滤波
    	cv::Mat image1;
    	sharpen(image, image1);
    	show(image1, "锐化");
    	cv::Mat image2;
    	sharpen2D(image, image2);
    	show(image2, "API锐化");
    

    查看输出(可右键查看大图),

    原图如下:

    二、高斯滤波

    OpenCV将大部分常用滤波函数进行封装,资料很多,自行查阅。其中高斯核函数多提一句,它是可拆分核函数,一个二维核可以拆解为两个一维核,我们既可以这样调用:

    cv::GaussianBlur(
    	image,
    	result,
    	cv::Size(5, 5),  // 窗口大小
    	1.5  // sigma
    );
    

    也可以这样调用,

    cv::Mat gauss = cv::getGaussianKernel(5, 1.5, CV_32F);
    cv::sepFilter2D(image, result, -1, gauss, gauss);  // -1代表输入图深度
    cv::imshow("双一维高斯滤波", result);
    

    结果一样,

  • 相关阅读:
    mysql_fetch_row()获取显示数据
    数组上下移动
    croppie 在Angular8 中使用
    关于 element 的 backToTop
    苹果手机new Date()问题
    js精简代码集合
    vue 中使用高德地图, 地图选点
    代替if else 的表单验证方法!
    记一次webpack打包样式加载问题
    echarts 饼图的指示线(labelline) 问题
  • 原文地址:https://www.cnblogs.com/hellcat/p/9890048.html
Copyright © 2020-2023  润新知