初识数字图像处理:GaussianBlur与MedianBlur(小白篇)

数字图像处理第一面:高斯滤波与中值滤波

这个学期,由于脑袋抽风涉嫌装逼(不是),校选课选了四大名挂之数字图像处理- -。但在慢慢深入学习之后,却渐渐对其产生了兴趣(真香)

初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第1张图片

于是在朋友和百度的帮助下,总算是完成了最后的拙作。我选择的是数字图像处理中的高斯滤波和中值滤波的实现,话不多说,正文开始:

小小的介绍

在实现滤波操作之前,需要先介绍一下数字图像处理中图像的噪声和卷积

图像噪声是指存在于图像数据中的不必要的或多余的干扰信息。各类图像处理系统在图像的采集、获取、传送和转换(如成像、复制扫描、传输以及显示等)过程中,均处在复杂的环境中,光照、电磁多变,所有的图像均不同程度地被可见或不可见的噪声干扰,导致图像质量的下降,掩盖图片重要细节
而图像噪声的去除在数字图像处理技术中的重要性越来越明显,如高放大倍数航片的判读,X射线图像系统中的噪声去除等已经成为不可缺少的技术步骤。

卷积:其实就是一个带权值的n维矩阵(这里也叫滤波器)在图像的像素图上滚来滚去对每个像素点进行加权运算,滚完了滤波也就做完了~
初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第2张图片

总所周知,图片其实是有千万个像素组成的,而每个像素点,其实就是表示图像的二维数组中的每个房间地址,灰度值,就是每个房间中的值。在图像的生成过程中,由于不可控因素,会造成临近灰度值所形成的函数的导数过大——也就是噪声,让其与真实颜色产生误差,掩盖图片细节,之后的各种后期图像处理便会不断放大这种误差。
而滤波则是对图片预处理时消除噪音的一种重要方式。

这里再简单的介绍一下高斯滤波和中值滤波

高斯滤波的滤波器中的权值的计算公式就是他啦~也就是高斯滤波名字的由来啦!
初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第3张图片
中值滤波正如其名,它是将像素(中值计算中包括的原像素值)邻域内灰度的中值代替该像素的值,也就是我们在图像中取3*3的矩阵,里面有9个像素点,我们将9个像素进行排序,最后将这个矩阵的中心点赋值为这九个像素的中值

函数原型

介绍了这么多,其实滤波器复杂的运算并不需要我们去实现,opencv中提供了medianBlur()和GaussianBlur()函数来实现中值滤波和高斯滤波的操作。原型如下:

C++: void medianBlur(InputArray src, OutputArray dst, int ksize)

参数解释:

  • IputArray src: 输入图像,图像为1、3、4通道的图像,当模板尺寸为3或5时,图像深度只能为CV_8U、CV_16U、CV_32F中的一个,如而对于较大孔径尺寸的图片,图像深度只能是CV_8U。
  • OutputArray dst: 输出图像,尺寸和类型与输入图像一致,可以使用Mat::Clone以原图像为模板来初始化输出图像dst
  • int ksize: 滤波器模板的尺寸大小,必须是大于1的奇数,如3、5、7…
C++:void GaussianBlur( InputArray src, OutputArray dst, Size ksize,
                                double sigmaX, double sigmaY = 0,
                                int borderType = BORDER_DEFAULT );

参数解释:

  • InputArray src:输入图像,通道不限,各通道单独处理;深度应当是CV_8U,CV_16U,CV_16S,CV_32F或CV_64F
  • OutputArray dst:输出图像,尺寸和类型与输入图像一致
  • Size ksize:高斯滤波器模板的大小,也是要大于1的奇数
  • double sigmaX, double sigmaY = 0:高斯滤波器在X方向上的标准差,而sigmaY=0时,其值自动由sigmaX确定。
  • borderType为边缘点插值类型。(4,5点稍显晦涩,感兴趣的可以百度了解一下)

实现过程

QSecond.h

#pragma once
#ifndef QSecond_H
#define QSecond_H

#include 
#include "ui_QSecond.h"
#include 
#include 
#include 
#include 

namespace Ui {//namespace:命名空间Ui:区分不同代码作者的相同函数名,相当于不同文件夹下的相同文件名得以区分
	class MainWindow;//空间成员
}

class QSecond : public QMainWindow
{
	Q_OBJECT

public:
	explicit QSecond(QWidget *parent = nullptr);//使用explcit防止Qsecond被自动地隐式类型转换
	~QSecond();//析构函数

private slots://private:只能在定义它的类QSecond中使用
	void on_inputPushButton_pressed();
	void on_outputPushButton_pressed();
	void on_savePushButton_pressed();
	void on_showPushButton_pressed();

private://只能在定义它的类中使用
	Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

QSecond.cpp:

初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第4张图片

#include "QSecond.h"
#include "ui_QSecond.h"
#include 
#include 
#include 


QSecond::QSecond(QWidget *parent) ://QWidget:所有用户界面对象的基类。
	QMainWindow(parent),//创建主界面
	ui(new Ui::MainWindow)
{
	ui->setupUi(this);
}

QSecond::~QSecond()//析构函数:在QSecond类使用完后自动删除(抛弃)
{
	delete ui;
}

void QSecond::on_inputPushButton_pressed()//Input键功能实现
{
	QString fileName = QFileDialog::getOpenFileName(this,//Q:FileDialogL-文件选择窗口。
		"Open Input Image",
		QDir::currentPath(),//获取当前工作目录
		"Images (*.jpg *.png *.bmp)");
	if (QFile::exists(fileName)) {
		ui->inputLineEdit->setText(fileName);
	}
}
void QSecond::on_outputPushButton_pressed()//Output键功能实现
{
	QString fileName = QFileDialog::getSaveFileName(this,
		"Select Output Image",
		QDir::currentPath(),
		"*.jpg;;*.png;;*.bmp");
	if (!fileName.isEmpty())
		ui->outputLineEdit->setText(fileName);
}

void QSecond::on_savePushButton_pressed()//Save键功能实现
{
	if (!ui->outputLineEdit->text().isEmpty()) {
		cv::Mat inImg, outImg;
		inImg = cv::imread(ui->inputLineEdit->text().toStdString());
		if (ui->medianBlurRadioButton->isChecked())
			cv::medianBlur(inImg, outImg, 5);
		else if (ui->gaussianBlurRadioButton->isChecked())
			cv::GaussianBlur(inImg, outImg, cv::Size(5, 5), 1.25);
		if (ui->displayImageCheckBox->isChecked())//dispaly键功能实现
			cv::imshow("Output Img", outImg);
	}
}

void QSecond::on_showPushButton_pressed()//Show键功能实现
{
	if (ui->gaussianBlurRadioButton->isChecked() | ui->medianBlurRadioButton->isChecked())//ischecked:该键是否被选中
		if (!ui->inputLineEdit->text().isEmpty()) {
			cv::Mat inImg, outImg;//初始化定义两个图像:输入输出图
			inImg = cv::imread(ui->inputLineEdit->text().toStdString());//imread读取图像
			if (ui->medianBlurRadioButton->isChecked())
				cv::medianBlur(inImg, outImg, 5);//5:滤波模板尺寸大小
			else if (ui->gaussianBlurRadioButton->isChecked())
				cv::GaussianBlur(inImg, outImg, cv::Size(5, 5), 1.25);//5.5为高斯滤波模板器尺寸,1.25为边缘点插值类型大小
			cv::namedWindow("Input Img",cv::WINDOW_NORMAL);//窗口命名。NORMAL:窗口可以通过拖动改变大小
			cv::namedWindow("Output Img",cv::WINDOW_NORMAL);//AUTOSIZE:窗口大小等于图片大小
			cv::imshow("Input Img", inImg);//imshow:输出图像
			cv::imshow("Output Img", outImg);
			if (cv::waitKey(200) == 27)//waitKey:不断刷新图像,刷新率为200ms.当输入键值为27(ESC)时,停止刷新,关闭窗口
				cv::destroyAllWindows();
		}
}	


main.cpp

#include "QSecond.h"
#include 

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);//创建对象
	QSecond w;
	w.show();//显示无模式对话框。(无模式:即可以切换焦点程序)
	return a.exec();//程序进程开始
}

  • 详细解释都在注释中~

测试数据

初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第5张图片
高斯:
初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第6张图片
中值:
初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第7张图片


高斯:
初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第8张图片

初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第9张图片

初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第10张图片
高斯:
初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第11张图片
中值:
初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第12张图片

初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第13张图片
高斯:
初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第14张图片

中值:
初识数字图像处理:GaussianBlur与MedianBlur(小白篇)_第15张图片

  • 因为滤波操作只是图片的预处理,简单的进行去噪,所以不会有太大的变化,不然就是本末倒置了。
  • 当然,可以通过修改滤波器模板的尺寸大小和边缘点插值大小来使效果更加明显。
  • 安装了OpenCV与QT creator

结语

因为我也是初学,所以大多还只是略懂皮毛,但这次的实验也让我打开了一扇新的大门,后面等待的是更多未知的有趣的代码与知识。希望在未来,还能在这里与大家分享自己摸爬滚打的学习经验~

最后的彩蛋

#include 
#include 
#include 
#include 


int main(int argc, char* argv[])
{
	using namespace cv;
	using namespace std;
	Mat img;
	VideoCapture cap;
	cap.open(0);
	if (!cap.isOpened())
		return 0;
	namedWindow("JT", WINDOW_NORMAL);
	while (1)
	{
		cap >> img;
		if (img.empty())
			break;
		imshow("JT", img);
		if (waitKey(30) == 27)
			break;
	}
	destroyAllWindows();
	return 0;
}

别问运行后是什么,问就是蔡徐坤/滑稽脸

下次再见~

你可能感兴趣的:(数字图像处理)