基于opencv的c++图像处理(图像滤波)

前言

基于opencv的c++接口,实现常用的图像滤波方法,包括了均值滤波、中值滤波、高斯滤波、双边滤波、高通滤波以及低通滤波。

相关的opencv接口解析

CV_EXPORTS_W void blur( InputArray src, OutputArray dst,
                        Size ksize, Point anchor = Point(-1,-1),
                        int borderType = BORDER_DEFAULT );

该函数使用内核平滑图像。
@param src 输入图像; 它可以有任意数量的通道,这些通道是独立处理的,但是深度应为 CV_8U、CV_16U、CV_16S、CV_32F 或 CV_64F。
@param dst 输出与 src 大小和类型相同的图像。
@param ksize 模糊内核大小。
@param anchor 锚点; 默认值 Point(-1,-1) 表示锚点在内核中央。
@param borderType 用于外推图像外像素的边框模式,请参阅#BorderTypes。 不支持#BORDER_WRAP。

enum BorderTypes {
    BORDER_CONSTANT    = 0, //!< `iiiiii|abcdefgh|iiiiiii`  with some specified `i`
    BORDER_REPLICATE   = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
    BORDER_REFLECT     = 2, //!< `fedcba|abcdefgh|hgfedcb`
    BORDER_WRAP        = 3, //!< `cdefgh|abcdefgh|abcdefg`
    BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
    BORDER_TRANSPARENT = 5, //!< `uvwxyz|abcdefgh|ijklmno`

    BORDER_REFLECT101  = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
    BORDER_DEFAULT     = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
    BORDER_ISOLATED    = 16 //!< do not look outside of ROI
};
CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize,
                                double sigmaX, double sigmaY = 0,
                                int borderType = BORDER_DEFAULT );

该函数将源图像与指定的高斯核进行卷积。支持就地过滤。
@param src 输入图像;图像可以有任意数量的通道,它们是独立处理的,但深度应该是 CV_8U、CV_16U、CV_16S、CV_32F 或 CV_64F。
@param dst 输出与 src 大小和类型相同的图像。
@param ksize 高斯内核大小。 ksize.width 和 ksize.height 可以不同,但​​它们都必须是正数和奇数。或者,它们可以是零,然后根据 sigma 计算它们。
@param sigmaX X 方向的高斯核标准差。
@param sigmaY Y 方向的高斯核标准差;如果 sigmaY 为零,则设置为等于 sigmaX,如果两个 sigma 均为零,则分别从 ksize.width 和 ksize.height 计算;为了完全控制结果,无论将来可能修改所有这些语义,建议指定所有 ksize、sigmaX 和 sigmaY。
@param borderType 像素外推方法,参见#BorderTypes。不支持#BORDER_WRAP。

CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );

该函数使用具有孔径的中值滤波器来平滑图像。 多通道图像的每个通道都是独立处理的。 支持就地操作。
@param src 输入 1、3 或 4 通道图像; ksize 为 3 或 5 时,图像深度应为 CV_8U、CV_16U 或 CV_32F,对于较大的光圈尺寸,只能为 CV_8U。
@param dst 与 src 大小和类型相同的目标数组。
@param ksize 孔径线性大小; 它必须是奇数且大于 1,例如:3、5、7 …

CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d,
                                   double sigmaColor, double sigmaSpace,
                                   int borderType = BORDER_DEFAULT );

该函数对输入图像应用双边过滤,如 http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html 中所述
双边滤波器可以很好地减少不需要的噪声,同时保持边缘相当清晰。但是,与大多数过滤器相比,它非常慢。
@param src 源 8 位或浮点、1 通道或 3 通道图像。
@param dst 与 src 大小和类型相同的目标图像。
@param d 过滤期间使用的每个像素邻域的直径。如果它是非正数,则从 sigmaSpace 计算。
@param sigmaColor 在颜色空间中过滤 sigma。较大的参数值意味着像素邻域内更远的颜色(参见 sigmaSpace)将混合在一起,导致在较大的半等色区域。
@param sigmaSpace 在坐标空间中过滤 sigma。较大的参数值意味着更远的像素会相互影响,只要它们的颜色足够接近(参见 sigmaColor)。当 d>0 时,它指定邻域大小,而不考虑 sigmaSpace。否则,d 与 sigmaSpace 成正比。
@param borderType 用于外推图像外像素的边框模式,请参阅#BorderTypes

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

该函数将任意线性滤波器应用于图像。支持就地操作。当光圈部分位于图像之外时,该函数会根据指定的边框模式对异常像素值进行插值。
@param src 输入图像。
@param dst 输出与 src 大小和通道数相同的图像。
@param ddepth 目标图像的所需深度,请参阅 @ref filter_depths “combinations”
@param kernel 卷积核(或者说是相关核),一个单通道浮点矩阵;如果要将不同的内核应用于不同的通道,请使用 split 将图像拆分为单独的颜色平面并单独处理它们。
@param anchor 内核的锚点,表示内核中过滤点的相对位置;锚点应位于内核中;默认值 (-1,-1) 表示锚点位于内核中心。
@param delta 在将过滤像素存储到 dst 之前添加到它们的可选值。
@param borderType 像素外推方法,参见#BorderTypes。不支持#BORDER_WRAP。

示例代码

filter.h

#pragma once
#include <iostream>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>

using namespace std;
using namespace cv;
#define PROCESS_IMG_SUCESS 0
#define PROCESS_IMG_FAIL 1


namespace ImgEnhance
{
	//滤波
	class Filter
	{
	public:
		Filter() { cout << "Filter is being created" << endl; } // 这是构造函数声明
		~Filter() { cout << "Filter is being deleted" << endl; } // 这是析构函数声明
		int MeanFilter(cv::Mat srcImage, cv::Mat &dstImage, int areaSize);//均值滤波
		int GaussFilter(cv::Mat srcImage, cv::Mat &dstImage, int areaSize, int xValue, int yValue);//高斯滤波
		int MedianFilter(cv::Mat srcImage, cv::Mat &dstImage, int areaSize);//中值滤波
		int BilateralFilter(cv::Mat srcImage, cv::Mat &dstImage, int areaRadio, int limitValue, int unuseValue);//双边滤波
																												//高通滤波:边缘提取与增强//低通滤波:边缘平滑
		int HighPassFilter(cv::Mat srcImage, cv::Mat &dstImage);//高通滤波
		int LowPassFilter(cv::Mat srcImage, cv::Mat &dstImage);//低通滤波
	};

}

filter.cpp

#include"filter.h"

int ImgEnhance::Filter::MeanFilter(cv::Mat srcImage, cv::Mat &dstImage, int areaSize)
{
	if (srcImage.empty())
	{
		printf("cannot load!!\n");
		return 1;
	}
	blur(srcImage, dstImage, Size(areaSize, areaSize), Point(-1, -1));
	return 0;
}

int ImgEnhance::Filter::GaussFilter(cv::Mat srcImage, cv::Mat &dstImage, int areaSize, int xValue, int yValue)
{
	if (srcImage.empty())
	{
		printf("cannot load!!\n");
		return 1;
	}
	GaussianBlur(srcImage, dstImage, Size(areaSize, areaSize), xValue, yValue);
	return 0;
}

int ImgEnhance::Filter::MedianFilter(cv::Mat srcImage, cv::Mat &dstImage, int areaSize)
{
	if (srcImage.empty())
	{
		printf("cannot load!!\n");
		return 1;
	}
	medianBlur(srcImage, dstImage, areaSize);
	return 0;
}

int ImgEnhance::Filter::BilateralFilter(cv::Mat srcImage, cv::Mat &dstImage, int areaRadio, int limitValue, int unuseValue)
{
	if (srcImage.empty())
	{
		printf("cannot load!!\n");
		return 1;
	}
	bilateralFilter(srcImage, dstImage, areaRadio, limitValue, unuseValue);
	return 0;
}

int ImgEnhance::Filter::HighPassFilter(cv::Mat srcImage, cv::Mat &dstImage)
{
	if (srcImage.empty())
	{
		printf("cannot load!!\n");
		return 1;
	}
	Mat highKernel;
	highKernel = (Mat_<double>(3, 3) << -1, -1, -1, -1, 9, -1, -1, -1, -1);//高通滤波核

	Mat grad;

	filter2D(srcImage, grad, CV_16S, highKernel, Point(-1, -1));
	convertScaleAbs(grad, dstImage);

	return 0;
}

int ImgEnhance::Filter::LowPassFilter(cv::Mat srcImage, cv::Mat &dstImage)
{
	if (srcImage.empty())
	{
		printf("cannot load!!\n");
		return 1;
	}
	Mat lowKernel;
	lowKernel = (Mat_<double>(3, 3) << 1.0 / 16, 2.0 / 16, 1.0 / 16, 2.0 / 16, 4.0 / 16, 2.0 / 16, 1.0 / 16, 2.0 / 16, 1.0 / 16);//低通滤波核

	Mat grad;

	filter2D(srcImage, grad, CV_16S, lowKernel, Point(-1, -1));
	convertScaleAbs(grad, dstImage);

	return 0;
}

test.cpp

#include"filter.h"
ImgEnhance::Filter ImgF;//滤波

int main()
{
	// 读取源图像及判断
	cv::Mat srcImage = cv::imread("flower.jpg");
	if (!srcImage.data)
	{
		return 1;
	}
	/*cv::namedWindow("原始图", 0);
	cv::imshow("原始图", srcImage);*/
	// 转化为灰度图像
	cv::Mat srcGray;
	if (srcImage.channels() == 3)
	{
		cv::cvtColor(srcImage, srcGray, COLOR_RGB2GRAY);
	}
	else
	{
		srcGray = srcImage.clone();
	}
	cv::namedWindow("灰度图", 0);
	cv::imshow("灰度图", srcGray);


	//均值滤波
	Mat meanImage;
	int areaSizeMean=5;
	ImgF.MeanFilter(srcGray, meanImage, areaSizeMean);
	cv::namedWindow("均值滤波图", 0);
	cv::imshow("均值滤波图", meanImage);
	//高斯滤波
	Mat gaussImage;
	int areaSizeGauss = 5;
	int xValue = 1;
	int yValue = 1;
	ImgF.GaussFilter(srcGray, gaussImage, areaSizeGauss, xValue, yValue);
	cv::namedWindow("高斯滤波图", 0);
	cv::imshow("高斯滤波图", gaussImage);
	//中值滤波
	Mat medianImage;
	int areaSizeMedian = 5;
	ImgF.MedianFilter(srcGray, medianImage, areaSizeMedian);
	cv::namedWindow("中值滤波图", 0);
	cv::imshow("中值滤波图", gaussImage);
	
	//双边滤波
	Mat bilateralImage;
	int areaRadio = 1; 
	int limitValue = 1;
	int unuseValue = 5;
	ImgF.BilateralFilter(srcGray, bilateralImage,  areaRadio,  limitValue,  unuseValue);
	cv::namedWindow("双边滤波图", 0);
	cv::imshow("双边滤波图", bilateralImage);

	//高通滤波:边缘提取与增强//低通滤波:边缘平滑
	Mat highpassImage;
	ImgF.HighPassFilter(srcGray, highpassImage);//高通滤波
	cv::namedWindow("高通滤波图", 0);
	cv::imshow("高通滤波图", highpassImage);
	//低通滤波
	Mat lowpassImage;
	ImgF.LowPassFilter(srcGray, lowpassImage);
	cv::namedWindow("低通滤波图", 0);
	cv::imshow("低通滤波图", lowpassImage);

	cv::waitKey(0);

	return 0;

}

结果展示

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值