高斯滤波 c++实现

高斯滤波

To smooth the image, a Gaussian filter kernel is convolved with the image.

高斯滤波的实质就是用高斯核对图片进行卷积操作

算法较为简单,在复杂度运行效率方面还有很多需要改进的

从RGB色转为灰度色算法(转) - carekee - 博客园 (cnblogs.com)

彩图转灰度图


Mat gray(Mat& image) {
	Mat dst = Mat::zeros(image.size(), CV_8UC1);
	for (int i = 0; i < image.rows; i++) {
		for (int j = 0; j < image.cols; j++)
		{
			dst.at<uchar>(i, j) = 0.114*image.at<Vec3b>(i, j)[0] + 0.587*image.at<Vec3b>(i, j)[1] + 0.299*image.at<Vec3b>(i, j)[2];
			//将彩色图像的三个通道的值,每个乘以对应的比例,进行相加,opencv B G R
		}
	}
	return dst;
}

 填充 padding

padding 的选择,5乘5(padding = 2),3乘3(padding = 1)

 如上图,要是右上角的小正方形位于卷积核的中心正方形处,就需要填充一层空的矩形

因此可以推至5乘5的卷积核

我选用的是3*3 的卷积,故填充为1

Mat Padding(Mat& image,int padNum = 1) {
	Mat dst = Mat::zeros(image.size[0]+2*padNum, image.size[1] + 2*padNum, CV_8UC1);
	cout << "dst size" << dst.size << endl;
	for (int i = 0; i < image.rows; i++) {
		for (int j = 0; j < image.cols; j++)
		{
			dst.at<uchar>(i + 1, j + 1) = image.at<uchar>(i, j);
		}
	}

	return  dst;

}

卷积

同样 3*3 的卷积核在主函数里

Mat  convolution(Mat &image, Mat &kernal) {

	Mat dst = Mat ::zeros(image.size(),image.type());
	// padding 填充
	Mat test = Padding(image);// 6*6 填充一层 变 8*8
	
	//cout << "conv test" << endl;
	for (int i = 0; i < image.rows; i++) {
		for (int j = 0; j < image.cols; j++)
		{
			double pixSum = 0;
		
			//这个像素就在卷积核的中心处
			for (int k = 0; k < kernal.rows; k++) {
				for (int l = 0; l < kernal.cols; l++) {
					//cout << kernal.at<double>(k, l) << endl;
					//cout << double(test.at<uchar>(k + i, l + j)) << endl;
					pixSum += kernal.at<double>(k, l) * double(test.at<uchar>(k + i, l + j));
				}
			}
			dst.at<uchar>(i, j) = uchar(pixSum);


		}
	}


	return dst;


}

因为使用的是3X3 的卷积核,所以模糊的不明显

 

代码

#include<opencv2/opencv.hpp>
#include<iostream>


using namespace cv;
using namespace std;


Mat gray(Mat& image) {
	Mat dst = Mat::zeros(image.size(), CV_8UC1);
	for (int i = 0; i < image.rows; i++) {
		for (int j = 0; j < image.cols; j++)
		{
			dst.at<uchar>(i, j) = 0.114*image.at<Vec3b>(i, j)[0] + 0.587*image.at<Vec3b>(i, j)[1] + 0.299*image.at<Vec3b>(i, j)[2];
			//将彩色图像的三个通道的值,每个乘以对应的比例,进行相加,opencv B G R
		}
	}
	return dst;
}

Mat Padding(Mat& image,int padNum = 1) {
	Mat dst = Mat::zeros(image.size[0]+2*padNum, image.size[1] + 2*padNum, CV_8UC1);
	cout << "dst size" << dst.size << endl;
	for (int i = 0; i < image.rows; i++) {
		for (int j = 0; j < image.cols; j++)
		{
			dst.at<uchar>(i + 1, j + 1) = image.at<uchar>(i, j);
		}
	}

	return  dst;

}

Mat  convolution(Mat &image, Mat &kernal) {

	Mat dst = Mat ::zeros(image.size(),image.type());
	// padding 填充
	Mat test = Padding(image);// 6*6 填充一层 变 8*8
	
	//cout << "conv test" << endl;
	for (int i = 0; i < image.rows; i++) {
		for (int j = 0; j < image.cols; j++)
		{
			double pixSum = 0;
		
			//这个像素就在卷积核的中心处
			for (int k = 0; k < kernal.rows; k++) {
				for (int l = 0; l < kernal.cols; l++) {
					//cout << kernal.at<double>(k, l) << endl;
					//cout << double(test.at<uchar>(k + i, l + j)) << endl;
					pixSum += kernal.at<double>(k, l) * double(test.at<uchar>(k + i, l + j));
				}
			}
			dst.at<uchar>(i, j) = uchar(pixSum);


		}
	}


	return dst;


}


/*
Mat GaussianBlur(Mat& image){
	//实质就是用高斯核实现一个卷积操作






}
*/

int main(int argc, char* argv[])
{
	//load pics

	string imgPath = "E:\\研究生\\数字图像处理\\c++\\字符识别\\Project1\\beauty.jpg";
	Mat srcImg = imread(imgPath);//RGB,JPG,PNG,TIFF格式

	if (srcImg.empty()) {
		cout << "can't load pic" << endl;
		exit(-1);
	}
	//show pics
	//imshow("air plane",srcImg);
	
	//转灰度化
	Mat image_gray = gray(srcImg);
	imshow("gray img", image_gray);

	//3*3 的卷积核 , padding = 1
	Mat kernal = (Mat_<double>(3, 3) << 1, 2, 1,2, 4, 2,1,2, 1);
	
	kernal = kernal / 16;

	//卷积实现高斯滤波
	Mat imgconv = convolution(image_gray, kernal);
	imshow("img conv", imgconv);
	waitKey(0);//wait function


	return 0;
}

 与opencv对比

模糊效果好像差不多

int main(int argc, char* argv[])
{
	//load pics

	string imgPath = "E:\\研究生\\数字图像处理\\c++\\字符识别\\Project1\\beauty.jpg";
	Mat srcImg = imread(imgPath,0);//RGB,JPG,PNG,TIFF格式

	if (srcImg.empty()) {
		cout << "can't load pic" << endl;
		exit(-1);
	}
	//show pics
	imshow("src",srcImg);
	Mat  dst;
	GaussianBlur(srcImg,dst,Size(3,3),0,0);
	imshow("opencv gsblur", dst);
	
	waitKey(0);//wait function


	return 0;
}

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值