继上一篇线性滤波之方框滤波,均值滤波,高斯滤波之后,加入非线性滤波操作中值滤波和双边滤波。
http://blog.youkuaiyun.com/oliverkingli/article/details/54022075
代码;
#include"stdafx.h"
#include <opencv2/core/utility.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include"opencv2/core/core.hpp"
#include <iostream>
using namespace cv;
using namespace std;
// 定义全局变量
Mat image, dstImage1, dstImage2, dstImage3, dstImage4, dstImage5;
int g_nBoxFilterValue = 3;
int g_nMeanBlurValue = 3;
int g_nGaussianBlurValue = 3;
int g_nMedianBlurValue = 3;
int g_nBilateralFilterValue = 3;
//函数声明
void salt(Mat image, int n);
void pepper(Mat image, int n);
void on_BoxFilter(int, void*);
void on_MeanBlur(int, void*);
void on_GaussianBlur(int, void*);
void on_MedianBlur(int, void*);
void on_BilateralFilter(int, void*);
int main() {
system("color 5E");
//读取图片
image = imread("E:\\pictures\\For_Project\\New_opencv\\Fruits.jpg");
namedWindow("【原始图像】", 1);
imshow("【原始图像】", image);
Mat dstImage1 = image.clone();
Mat dstImage2 = image.clone();
Mat dstImage3 = image.clone();
Mat dstImage4 = image.clone();
Mat dstImage5 = image.clone();
//分别添加盐椒噪声
salt(dstImage1, 1000);
pepper(dstImage1, 1000);
salt(dstImage2, 1000);
pepper(dstImage2, 1000);
salt(dstImage3, 1000);
pepper(dstImage3, 1000);
salt(dstImage4, 1000);
pepper(dstImage4, 1000);
salt(dstImage5, 1000);
pepper(dstImage5, 1000);
imshow("【添加盐椒噪声图片】", dstImage1);
double time1 = static_cast<double>(getTickCount());
namedWindow("【方框滤波】", 1);
createTrackbar("内核值:", "【方框滤波】", &g_nBoxFilterValue, 40, on_BoxFilter);
on_BoxFilter(g_nBoxFilterValue, 0);
//计算运行时间并输出
time1 = ((double)getTickCount() - time1) / getTickFrequency();
cout << "方框滤波方法运行时间为:" << time1 << "秒" << endl;
double time2 = static_cast<double>(getTickCount());
namedWindow("【均值滤波】", 1);
createTrackbar("内核值:", "【均值滤波】", &g_nMeanBlurValue, 40, on_MeanBlur);
on_MeanBlur(g_nMeanBlurValue, 0);
//计算运行时间并输出
time2 = ((double)getTickCount() - time2) / getTickFrequency();
cout << "均值滤波方法运行时间为:" << time2 << "秒" << endl;
double time3 = static_cast<double>(getTickCount());
namedWindow("【高斯滤波】", 1);
createTrackbar("内核值:", "【高斯滤波】", &g_nGaussianBlurValue, 40, on_GaussianBlur);
on_GaussianBlur(g_nGaussianBlurValue, 0);
//计算运行时间并输出
time3 = ((double)getTickCount() - time3) / getTickFrequency();
cout << "高斯滤波方法运行时间为:" << time3 << "秒" << endl;
double time4 = static_cast<double>(getTickCount());
namedWindow("【中值滤波】", 1);
createTrackbar("内核值:", "【中值滤波】", &g_nMedianBlurValue, 40, on_MedianBlur);
on_MedianBlur(g_nMedianBlurValue, 0);
//计算运行时间并输出
time4 = ((double)getTickCount() - time4) / getTickFrequency();
cout << "中值滤波方法运行时间为:" << time4 << "秒" << endl;
double time5 = static_cast<double>(getTickCount());
namedWindow("【双边滤波】", 1);
createTrackbar("内核值:", "【双边滤波】", &g_nBilateralFilterValue, 40, on_BilateralFilter);
on_BilateralFilter(g_nBilateralFilterValue, 0);
//计算运行时间并输出
time5 = ((double)getTickCount() - time5) / getTickFrequency();
cout << "高斯滤波方法运行时间为:" << time5 << "秒" << endl;
//等待键盘按键‘q’退出
while (char(waitKey(1)) != 'q') {}
return 0;
}
void on_BoxFilter(int, void*) {
boxFilter(image, dstImage1, -1, Size(g_nBoxFilterValue + 1, g_nBoxFilterValue + 1));
imshow("【方框滤波】", dstImage1);
}
void on_MeanBlur(int, void*) {
blur(image, dstImage2, Size(g_nMeanBlurValue + 1, g_nMeanBlurValue + 1),Point(-1,-1));
imshow("【均值滤波】", dstImage2);
}
void on_GaussianBlur(int, void*) {
GaussianBlur(image, dstImage3, Size(g_nGaussianBlurValue*2 + 1, g_nGaussianBlurValue*2 + 1),0,0);
imshow("【高斯滤波】", dstImage3);
}
void on_MedianBlur(int, void*) {
medianBlur(image, dstImage4, g_nMedianBlurValue * 2 + 1);
imshow("【中值滤波】", dstImage4);
}
void on_BilateralFilter(int, void*) {
bilateralFilter(image, dstImage5, g_nBilateralFilterValue, g_nBilateralFilterValue * 2, g_nBilateralFilterValue / 2);
imshow("【双边滤波】", dstImage5);
}
void salt(Mat image, int n) {
int i, j;
for (int k = 0; k<n / 2; k++) {
// rand() is the random number generator
i = std::rand() % image.cols; // % 整除取余数运算符,rand=1022,cols=1000,rand%cols=22
j = std::rand() % image.rows;
if (image.type() == CV_8UC1) { // gray-level image
image.at<uchar>(j, i) = 255; //at方法需要指定Mat变量返回值类型,如uchar等
}
else if (image.type() == CV_8UC3) { // color image
image.at<cv::Vec3b>(j, i)[0] = 255; //cv::Vec3b为opencv定义的一个3个值的向量类型
image.at<cv::Vec3b>(j, i)[1] = 255; //[]指定通道,B:0,G:1,R:2
image.at<cv::Vec3b>(j, i)[2] = 255;
}
}
}
//椒噪声
void pepper(Mat image, int n) {
int i, j;
for (int k = 0; k<n; k++) {
// rand() is the random number generator
i = std::rand() % image.cols; // % 整除取余数运算符,rand=1022,cols=1000,rand%cols=22
j = std::rand() % image.rows;
if (image.type() == CV_8UC1) { // gray-level image
image.at<uchar>(j, i) = 0; //at方法需要指定Mat变量返回值类型,如uchar等
}
else if (image.type() == CV_8UC3) { // color image
image.at<cv::Vec3b>(j, i)[0] = 0; //cv::Vec3b为opencv定义的一个3个值的向量类型
image.at<cv::Vec3b>(j, i)[1] = 0; //[]指定通道,B:0,G:1,R:2
image.at<cv::Vec3b>(j, i)[2] = 0;
}
}
}