//-------------------------------------------------------------
//作者:不用先生,2018.11.26
//自实现的图像双边滤波算法
//bilateral.cpp
//-------------------------------------------------------------
#include "opencv2/core/core.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <cmath>
using namespace std;
using namespace cv;
//--------------------------------------------------------------
//函数名:my_Bilateral
//函数功能:自己编写的可用于灰度图及彩色图的双边滤波函数;
//参数:Mat &scr:输入图像,为单通道灰度图或三通道彩色图;
//参数:Mat &dst:输出图像,尺寸与通道数与输入图像吻合;
//参数:int d:滤波器大小,应该保证为奇数;
//参数:double sigmaColor:颜色域/像素值域方差,sigmaColor越大,平滑效果越好,对边缘的保护越弱;
//参数:double sigmaSpace:空间域方差,sigmaSpace越大,结果越平滑;
//--------------------------------------------------------------
bool my_Bilateral(Mat &scr, Mat &dst, int d, double sigmaColor, double sigmaSpace)
{
if (!scr.data)
{
cerr << "输入图像错误,请检查" << endl;;
return false;
}
if (d % 2 == 0)
{
cerr << "输入窗口大小应该为奇数,请修改"<<endl;
return false;
}
dst = scr.clone();
int row = dst.rows; //获取图像大小;
int col = dst.cols;
int copyBorderSize =floor(0.5+ d / 2);
Mat copyBorder_dst;
copyMakeBorder(dst, copyBorder_dst, copyBorderSize, copyBorderSize, copyBorderSize, copyBorderSize, BORDER_REFLECT);
int channels = dst.channels();
if (channels == 1) //如果是灰度图像
{
for (int i = 0; i < row; i++) //对每一个点进行处理
{
for (int j = 0; j < col; j++)
{
double weightSum = 0;
double filterValue = 0;
for (int row_d = -(d / 2); row_d <= (d / 2); row_d++) //以图像中的一点为中心,d为边长的方形区域内进行计算
{
for (int col_d = -(d / 2); col_d <= (d / 2); col_d++)
{
double distance_Square = row_d*row_d + col_d*col_d;
double value_Square = pow((scr.at<uchar>(i, j) - copyBorder_dst.at<uchar>(i + (d / 2) + row_d, j + (d / 2) + col_d)), 2);
double weight = exp(-1 * (distance_Square / (2 * sigmaSpace*sigmaSpace) + value_Square / (2 * sigmaColor*sigmaColor)));
weightSum += weight; //求滤波窗口内的权重和,用于归一化;
filterValue += (weight*copyBorder_dst.at<uchar>(i + (d / 2) + row_d, j + (d / 2) + col_d));
}
}
dst.at<uchar>(i, j) = filterValue / weightSum;
}
}
return true;
}
else if (channels == 3) //如果是RGB图像
{
for (int c = 0; c < channels; c++) //逐通道进行处理
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
double weightSum = 0;
double filterValue = 0;
for (int row_d = -(d / 2); row_d <= (d / 2); row_d++)
{
for (int col_d = -(d / 2); col_d <= (d / 2); col_d++)
{
double distance_Square = row_d*row_d + col_d*col_d;
double value_Square = pow((scr.at<Vec3b>(i, j)[c] - copyBorder_dst.at<Vec3b>(i + (d / 2) + row_d, j + (d / 2) + col_d)[c]), 2);
double weight = exp(-1 * (distance_Square / (2 * sigmaSpace*sigmaSpace) + value_Square / (2 * sigmaColor*sigmaColor)));
weightSum += weight;
filterValue += (weight*copyBorder_dst.at<Vec3b>(i + (d / 2) + row_d, j + (d / 2) + col_d)[c]);
}
}
dst.at<Vec3b>(i, j)[c] = filterValue / weightSum;
}
}
}
return true;
}
else
{
cerr << "图像通道数有误,请确定";
return false;
}
}
//----------------
//主函数
//----------------
void main()
{
Mat scr = imread("03.jpg", IMREAD_UNCHANGED); //以默认的方式读入图像
if (!scr.data) //判断图像是否被正确读取;
{
return;
}
int half_Window_Size = 10; //窗口半宽大小
int window_Size = 2 * half_Window_Size + 1; //窗口大小,应该为奇数;
double sigmaColor = 10; //像素值域的方差
double sigmaSpace = 10; //空间域的方差
//使用自实现的双边滤波对结果进行处理
Mat my_dst = scr.clone();
if (!my_Bilateral(scr, my_dst, window_Size, sigmaColor, sigmaSpace))
{
cerr << "自编写的双边滤波再计算过程中出差,请查验" << endl;
}
//用OpenCV自带的双边滤波函数进行处理
Mat auto_dst = scr.clone();
bilateralFilter(scr, auto_dst, window_Size, sigmaColor, sigmaSpace);
//用高斯函数记性处理
Mat gau_dst = scr.clone();
Size gauSize(window_Size, window_Size);
GaussianBlur(scr, gau_dst, gauSize, sigmaSpace);
imwrite("temp1.jpg", my_dst);
imwrite("temp2.jpg", auto_dst);
imwrite("temp3.jpg", gau_dst);
system("pause");
return;
}

不用先生
- 粉丝: 916
- 资源: 6
最新资源
- 基于kinect 的人体动作识别新版算法源码+说明.zip
- 基于MATLAB的车牌识别系统新版算法源码+说明.zip
- 基于lumen5.5开发的高性能高并发图片识别平台API源码+说明.zip
- 混合动力汽车动态规划算法理论油耗计算及模块化编程教学:基于MATLAB的快速计算程序与参数自定义配置技术 ,混合动力汽车动态规划算法:基于MATLAB的油耗计算程序与模块化教学平台 通过控制量与状态量
- 基于LSTM的中文情绪识别新版源码+数据.zip
- 基于MLKit实现二维码+条形码识别(实现微信效果样式).zip
- 基于mtcnn_facenet_tensorflow 实现人脸识别登录系统新版源码+说明.zip
- 基于MFCC语音特征提取和识别新版算法源码+说明.zip
- 基于HTML+JavaScript的瑞吉外卖系统设计源码及优化实践
- 基于MTCNN和MobileFaceNet实现的人脸识别算法源码(提供三种预测方式,满足各种需求).zip
- 基于Java语言的优优租车系统设计源码
- 基于opencv的java车牌检测识别库(支持linux、windows、mac、Android平台).zip
- MATLAB仿真:TMM计算光学薄膜与一维光子晶体透射谱、反射谱,可定制多种膜层与入射条件,MATLAB仿真TMM法:定制计算光学薄膜与一维光子晶体透反谱随入射角及波型变化,MATLAB仿真传输矩阵法
- 基于ocr主流算法gru_lstm+ctc+cnn架构进行不定长度验证码识别,达到不分割字符而识别验证码内容的效果.zip
- 基于STM32、ESP8266与OneNet的智能家电控制系统设计源码
- 基于opencv的图像识别基础库.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈


