数字图像处理基础实验(四):图像去噪

数字图像处理基础实验(四):图像去噪
⼀、实验内容及原理
具体内容:利⽤ OpenCV 对灰度图像像素进⾏操作,分别利⽤算术均值滤波器、⼏何均值滤波器、谐波和逆谐波均值滤波器进⾏图像去噪。模板⼤⼩为 5*5。 (注:请分别为图像添加⾼斯噪声、胡椒噪声、盐噪声和椒盐噪声,并观察 滤波效果)
(1)算术均值滤波器
(2)⼏何均值滤波器
注:这个累乘很容易会超过int或者long的表⽰范围,建议每n个灰度⼀起乘,再开根号
(3)谐波均值滤波器
(4)逆谐波均值滤波器
2、中值滤波
具体内容:利⽤ OpenCV 对灰度图像像素进⾏操作,分别利⽤和  尺⼨的模板对图像进⾏中值滤波。(注:请分别为图像添加胡椒噪声、盐噪声和 椒盐噪声,并观察滤波效果)
3、⾃适应均值滤波。
具体内容:利⽤ OpenCV 对灰度图像像素进⾏操作,设计⾃适应局部降 低噪声滤波器去噪算法。模板⼤⼩ 7*7(对⽐该算法的效果和均值滤波器的效果)
4、⾃适应中值滤波(x ,y )=f ^g (s ,t )
mn 1∑(x ,y )=f ^[g (s ,t )]∏mn
1(x ,y )=f ^g (s ,t )
∑1mn (x ,y )=f ^g (s ,t )∑Q
g (s ,t )∑Q +1
5∗59∗9(x ,y )=f ^g (s ,t )−
[g (s ,t )−σL 2ση2
m ]
L
具体内容:利⽤ OpenCV 对灰度图像像素进⾏操作,设计⾃适应中值滤波算 法对椒盐图像进⾏去噪。模板⼤⼩ 7*7(对⽐中值滤波器的效果)
5、彩⾊图像均值滤波
具体内容:利⽤ OpenCV 对彩⾊图像 RGB 三个通道的像素进⾏操作,利⽤算 术均值滤波器和⼏何均值滤波器进⾏彩⾊图像去噪。模板⼤⼩为 5*5
⼆、实验代码
实验环境:
(1)OpenCV3.4.3
(2)Ubuntu16.04
(3)VS Code
(4)C++
#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
#include <vector>
#include <math.h>
#include <cmath>
#include <algorithm>
class Exp4{
public:
// 1 初始化:彩⾊图⽚、灰度图⽚、加噪图⽚
Exp4(std::vector<std::string> path){
noise_name.push_back("⾼斯噪声");
noise_name.push_back("胡椒噪声");
noise_name.push_back("盐噪声");
noise_name.push_back("椒盐噪声");
filter_name.push_back("算术均值滤波");
filter_name.push_back("⼏何均值滤波");
filter_name.push_back("谐波均值滤波");
filter_name.push_back("逆谐波均值滤波");
filter_name.push_back("中值滤波");
filter_name.push_back("⾃适应均值滤波");
filter_name.push_back("⾃适应中值滤波");
pic_color.push_back("灰度");
pic_color.push_back("彩⾊");
for(int i = 0; i < path.size(); i++){
// 读取彩⾊图⽚、灰度图⽚
original_color_image.push_back(cv::imread(path[i]));
original_gray_image.push_back(color2Gray(original_color_image[i]));
// 彩⾊图⽚加噪
noise_color_image.push_back(addNoise(original_color_image[i], 0, 0));
noise_color_image.push_back(addNoise(original_color_image[i], 1, 0));
noise_color_image.push_back(addNoise(original_color_image[i], 2, 0));
noise_color_image.push_back(addNoise(original_color_image[i], 3, 0));
/
/ 灰度图⽚加噪
noise_gray_image.push_back(addNoise(original_gray_image[i], 0));
noise_gray_image.push_back(addNoise(original_gray_image[i], 1));
noise_gray_image.push_back(addNoise(original_gray_image[i], 2));
noise_gray_image.push_back(addNoise(original_gray_image[i], 3));
}
}
// 1.1 彩⾊图像转灰度图像
cv::Mat color2Gray(cv::Mat src_image){
//创建与原图同类型和同⼤⼩的矩阵
cv::Mat gray_image(ws, ls, CV_8UC1);
if(src_image.channels()!=1){
for(int i = 0; i < ws; i++)
for(int j = 0; j < ls; j++)
gray_image.at<uchar>(i, j) = (src_image.at<cv::Vec3b>(i, j)[0] + src_image.at<cv::Vec3b>(i, j)[1] + src_image.at<cv::Vec3b>(i, j)[2]) / 3;        }
else
gray_image = src_image.clone();
return gray_image;
}
// 2 灰度图像滤波
void grayFiltering(int id, int select, int filter_size=5, double Q=1){
int size = filter_size;
if(select == 6 || select == 5)
size = 7;
int m = size/2;
int n=size*size;
cv::Mat image = cv::Mat::zeros(noise_gray_image[id].size(), noise_gray_image[id].type());
for(int i=m; i < noise_gray_image[id].rows - m; i++)
for(int j=m; j < noise_gray_image[id].cols - m; j++){
cv::Mat sub_matrix = noise_gray_image[id](cv::Rect(j - m, i - m, size, size));
if(select == 0)
image.at<uchar>(i,j) = arithmeticMeanValueConvolution(sub_matrix);
else if(select == 1)
image.at<uchar>(i,j) = geometryMeanValueConvolution(sub_matrix);
else if(select == 2)
image.at<uchar>(i,j) = harmonicMeanValueConvolution(sub_matrix);
else if(select == 3)
image.at<uchar>(i,j) = inverseHarmonicMeanValueConvolution(sub_matrix);
else if(select == 4)
image.at<uchar>(i,j) = middleValueConvolution(sub_matrix);
else if(select == 5)
image.at<uchar>(i,j) = selfAdaptionMeanValueConvolution(sub_matrix, image.at<uchar>(i,j));
else if(select == 6)
image.at<uchar>(i,j) = selfAdaptionMiddleValueConvolution(sub_matrix);
}
noise_gray_image_process.push_back(image);
}
// 2.1 算术均值
int arithmeticMeanValueConvolution(cv::Mat& image_block, int size=5){
cv::Mat c_template(size, size, CV_8UC1, 1);
int n=size*size;
return c_template.dot(image_block) / n + 0.5;
}
// 2.2 ⼏何平均
int geometryMeanValueConvolution(cv::Mat& image_block, int size=5){
std::vector<double> product(5,1);
double n = 1.0 / double(size * size);
for(int k1 = 0; k1 < size; k1++){
double temp=1;
for(int k2 = 0; k2 < size; k2++){
temp = temp * ((image_block.at<uchar>(k1,k2) > 0) ? double(image_block.at<uchar>(k1,k2)) : 1.0);                product[k1] = pow(temp, n);
}
椒盐噪声}
return int(product[0] * product[1] * product[2] * product[3] * product[4]);
}
// 2.3 谐波均值
int harmonicMeanValueConvolution(cv::Mat& image_block, int size=5){
std::vector<double> product(5,1);
double sum=0;
double n = double(size * size);
for(int k1 = 0; k1 < size; k1++){
for(int k2 = 0; k2 < size; k2++){
double temp;
if(image_block.at<uchar>(k1,k2))
temp = 1.0 / double(image_block.at<uchar>(k1,k2));
else
temp=0;
sum += temp;
}
}
return int(n / sum);
}
// 2.4 逆谐波均值
int inverseHarmonicMeanValueConvolution(cv::Mat& image_block, int size=5, double Q=1){
double sum1=0, sum2=0;
for(int k1 = 0; k1 < size; k1++){
for(int k2 = 0; k2 < size; k2++){
sum1 += pow(double(image_block.at<uchar>(k1, k2)), Q);
sum2 += pow(double(image_block.at<uchar>(k1, k2)), Q+1);
}
}
return int(sum2 / sum1);
}
// 3.1 中值滤波
int middleValueConvolution(cv::Mat& image_block, int size=5){
int min = 0, k = 0, pos = size*size/2;
std::vector<int> nums;
for(int k1 = 0; k1 < size; k1++)
for(int k2 = 0; k2 < size; k2++)
nums.push_back(image_block.at<uchar>(k1,k2));
int middle = findMiddleNum(nums, 0, size*size - 1, pos);
return middle;
}
// 3.2.1 快速查中位数
int findMiddleNum(std::vector<int>& nums, int begin, int end, int n){
int i = partition(nums, begin, end);
if(i == n)
return nums[i];
else if(i > n)
return findMiddleNum(nums, begin, i-1, n);
else
return findMiddleNum(nums, i+1, end, n);
}
// 3.2.2 交换
void exchange(std::vector<int>& nums, int a,int b){
int c = nums[a];
nums[a] = nums[b];
nums[b] = c;
return;
}
// 3.2.2 快速查中位数
int partition(std::vector<int>& nums, int begin, int end){
int i = begin, j = end + 1;
int x = nums[begin];
while (true) {
while (nums[++i] < x) {// 向右扫描
if (i == end)
break;
}
while (nums[--j] > x) {// 向左扫描
if (j == begin)
break;
}
if (i >= j) // 指针相遇,切分位置确定
break;
exchange(nums, i, j);// 交换左右逆序元素
}
// 运⾏到最后:i指向从左往右第⼀个⼤于x的元素,j指向从右往左第⼀个⼩于x的元素。
exchange(nums, begin, j);// 将切分元素放在切分位置
return j;
}
// 4、⾃适应均值滤波
int selfAdaptionMeanValueConvolution(cv::Mat& image_block, int value, int size=7, int sigma_n=3000){        int center = size/2;
int mean = computerMeanValue(image_block);
int sigma = computerVariance(image_block, mean);
//std::cout<<sigma<<"\n";
double rate = double(sigma_n)/double(sigma);
if(rate > 1.0)
rate = 1;
int ans = value - rate * (value - mean);
return ans;
}
// 4.1 计算图像块的平均值
int computerMeanValue(cv::Mat& image_block, int size=7){
int sum = 0,n = size*size;
for(int k1 = 0; k1 < size; k1++)
for(int k2 = 0; k2 < size; k2++)

本文发布于:2024-09-22 03:54:20,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/2/358203.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:图像   实验   均值   滤波   噪声   元素
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议