山东大学数字图像处理实验(三) 计算机学院

本实验为计算机科学与技术学院计算机专业大四上限选课,2023-2024-1年度课程实验,较以往实验内容发生较大变化
本实验使用vs2019,c++语言,需要提前安装opencv,具体方法请自行搜索。

实验三:图像滤波

实现高斯滤波,基于行列可分离性进行加速,并与没有加速的情况进行速度和效果的对比。
OpenCV GaussianBlur 函数比较计算速度,并分析导致速度差异的原因。

 

#include <opencv2/opencv.hpp>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/imgproc.hpp>  
#include <iostream>  
#include <vector>
#include <time.h>
using namespace std;
using namespace cv;

int ksize = 1; //声明并初始化ksize变量,用于控制高斯核的大小  
Mat src, dst, blurred, kernel;  
clock_t startTime, endTime;

//高斯滤波函数,参数包括ksize和void指针(此处未使用)  
void Gaussian(int, void*) {  
	int GaussianKernel = 6 * ksize - 1; //计算高斯核的大小
	cout << "高斯核大小为:   " << GaussianKernel <<  endl;
	startTime = clock();
	// 使用库文件自带的高斯滤波函数
	GaussianBlur(src, blurred, Size(GaussianKernel, GaussianKernel), 0, 0);
	imshow("Blurred Image", blurred);
	endTime = clock();
	cout << "使用库函数GaussianBlur的时间为   " << endTime - startTime << "   " << endl;
	startTime = clock();
	kernel = getGaussianKernel(GaussianKernel, ksize).t(); //生成一维高斯核并转置  
	double* matrix = kernel.ptr<double>(0); //获取一维高斯核的数据指针  

	int GaussianKernel_2 = GaussianKernel / 2; //计算高斯核半径  
	Mat src_Extended;
	//对源图像进行边界扩展,扩展方式为复制  
	copyMakeBorder(src, src_Extended, GaussianKernel_2, GaussianKernel_2, GaussianKernel_2, GaussianKernel_2, BORDER_REPLICATE);

	const int row = src_Extended.rows; //获取扩展后图像的行列数
	const int col = src_Extended.cols;
	Mat dst_tmp = src_Extended.clone(); //复制扩展后的图像到临时目标图像  
	//除以255进行归一化  
	dst_tmp.convertTo(dst_tmp, CV_64FC3, 1 / 255.0);

	//水平方向的高斯滤波  
	for (int i = GaussianKernel_2; i < row - GaussianKernel_2; i++) { //行循环
		for (int j = GaussianKernel_2; j < col - GaussianKernel_2; j++) { 
			for (int k = 0; k < 3; ++k) { //通道循环
				double sum = 0.0; 
				//计算每一个像素点周围矩形区域内所有像素点的累加和  
				for (int x = 0; x < GaussianKernel; x++) {
					sum += src_Extended.at<Vec3b>(i, j - GaussianKernel_2 + x)[k] / 255.0 * matrix[x];
				}
				dst_tmp.at<Vec3d>(i, j)[k] = sum; //将累加和保存到临时目标图像中  
			}
		}
	}

	//竖直方向的高斯滤波  
	dst = Mat(src.size(), src.type()); 
	for (int i = GaussianKernel_2; i < row - GaussianKernel_2; i++) { 
		for (int j = GaussianKernel_2; j < col - GaussianKernel_2; j++) {
			for (int k = 0; k < 3; ++k) {
				double sum = 0.0; 
				// 计算每一个像素点周围矩形区域内所有像素点的累加和  
				for (int y = 0; y < GaussianKernel; y++) {
					sum += dst_tmp.at<Vec3d>(i - GaussianKernel_2 + y, j)[k] * matrix[y];
				}
				dst.at<Vec3b>(i - GaussianKernel_2, j - GaussianKernel_2)[k] = (uchar)(sum * 255.0 + 0.5); // 将累加和乘以255并四舍五入
			}
		}
	}
	imshow("Dst_img", dst); // 显示目标图像 
	endTime = clock();
	cout << "使用自己实现的高斯滤波的时间为   " << endTime - startTime << "   " << endl << endl;
}



int main()
{
	src = imread("C:/Users/13441/Desktop/数字图像/a.png");
	namedWindow("Dst_img", WINDOW_AUTOSIZE);
	createTrackbar("Sigma:", "Dst_img", &ksize, 20, Gaussian);
	//Mat blurred;
	// 使用库文件自带的高斯滤波函数
	//GaussianBlur(src, blurred, cv::Size(29, 29), 0, 0);
	//imshow("Blurred Image", blurred);
	waitKey(0);
	return 0;
}

自己实现和自带的对比:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值