基于opencv的几种图像滤波

news2024/11/16 17:29:51

一、介绍

    盒式滤波、均值滤波、高斯滤波、中值滤波、双边滤波、导向滤波。

    boxFilter()

    blur()

    GaussianBlur()

    medianBlur()

    bilateralFilter()

二、代码

#include <opencv2/core/core.hpp>                      
#include <opencv2/highgui/highgui.hpp>          
#include <opencv2/imgproc/imgproc.hpp>      
#include <iostream> 

using namespace std;
using namespace cv;

#define WINDOWNAME "【滤波处理结果窗口】"  

//---------------【全局变量声明部分】-------------------------  
Mat g_srcIamge, g_dstImage1, g_dstImage2, g_dstImage3, g_dstImage4, g_dstImage5, g_dstImage6;
int g_nBoxFilterValue = 1;       //盒式滤波内核值  
int g_nMeanBlurValue = 1;        //均值滤波内核值  
int g_nGaussianBlurValue = 1;    //高斯滤波内核值  
int g_nMedianBlurValue = 1;      //中值滤波内核值  
int g_nBilateralFilterValue = 1; //双边滤波内核值  
int g_nGuidedFilterValue = 1;    //导向滤波内核值  
const int g_nMaxVal = 20;        //预设滑动条最大值 

//--------------【全局函数声明部分】-------------------------   
static void on_BoxFilter(int, void*);       //盒式滤波器  
static void on_MeanBlur(int, void*);        //均值滤波器  
static void on_GaussianBlur(int, void*);    //高斯滤波器  
static void on_MedianBlur(int, void*);      //中值滤波器  
static void on_BilateralFilter(int, void*); //双边滤波器  
static void on_GuidedFilter(int, void*);    //导向滤波器  
void guidedFilter(Mat& srcMat, Mat& guidedMat, Mat& dstImage, int radius, double eps); //导向滤波器  

//----------------------------【主函数】---------------------------  
int main()
{
    //------------【1】读取源图像并检查图像是否读取成功------------    
    g_srcIamge = imread("D:\\opencv4_1_2\\opencv\\sources\\samples\\data\\lena.jpg");
    if (!g_srcIamge.data)
    {
        cout << "读取图片错误,请重新输入正确路径!\n";
        system("pause");
        return -1;
    }
    namedWindow("【源图像】", 1);     //创建窗口  
    imshow("【源图像】", g_srcIamge); //显示窗口  
    
    //------------【2】在WINDOWNAME窗口上分别创建滤波6个滑动条------------         
    namedWindow(WINDOWNAME); //创建窗口    
    createTrackbar("方框滤波", WINDOWNAME, &g_nBoxFilterValue, g_nMaxVal, on_BoxFilter); //创建方框滤波轨迹条  
    on_BoxFilter(g_nBoxFilterValue, 0);
    createTrackbar("均值滤波", WINDOWNAME, &g_nMeanBlurValue, g_nMaxVal, on_MeanBlur); //创建均值滤波轨迹条  
    on_MeanBlur(g_nMeanBlurValue, 0);
    createTrackbar("高斯滤波", WINDOWNAME, &g_nGaussianBlurValue, g_nMaxVal, on_GaussianBlur); //创建高斯滤波轨迹条  
    on_GaussianBlur(g_nGaussianBlurValue, 0);
    createTrackbar("中值滤波", WINDOWNAME, &g_nMedianBlurValue, g_nMaxVal, on_MedianBlur); //创建中值滤波轨迹条  
    on_MedianBlur(g_nMedianBlurValue, 0);
    createTrackbar("双边滤波", WINDOWNAME, &g_nBilateralFilterValue, g_nMaxVal, on_BilateralFilter); //创建双边滤波轨迹条  
    on_BilateralFilter(g_nBilateralFilterValue, 0);
    createTrackbar("导向滤波", WINDOWNAME, &g_nGuidedFilterValue, g_nMaxVal, on_GuidedFilter); //创建导向滤波轨迹条  
    on_GuidedFilter(g_nGuidedFilterValue, 0);

    //------------【3】退出程序------------    
    cout << "\t按下'q'键,退出程序~!\n" << endl;
    while (char(waitKey(1)) != 'q') {}
    return 0;
}

//----------------------【on_BoxFilter()函数】------------------------  
static void on_BoxFilter(int, void*)
{
    boxFilter(g_srcIamge, g_dstImage1, -1, Size(g_nBoxFilterValue * 2 + 1, g_nBoxFilterValue * 2 + 1));
    cout << "\n当前为【盒式滤波】处理效果,其内核大小为:" << g_nBoxFilterValue * 2 + 1 << endl;
    imshow(WINDOWNAME, g_dstImage1);
}

//----------------------【on_MeanBlur()函数】------------------------  
static void on_MeanBlur(int, void*)
{
    blur(g_srcIamge, g_dstImage2, Size(g_nMeanBlurValue * 2 + 1, g_nMeanBlurValue * 2 + 1), Point(-1, -1));
    cout << "\n当前为【均值滤波】处理效果,其内核大小为:" << g_nMeanBlurValue * 2 + 1 << endl;
    imshow(WINDOWNAME, g_dstImage2);
}

//----------------------【on_GaussianBlur()函数】------------------------  
static void on_GaussianBlur(int, void*)
{
    GaussianBlur(g_srcIamge, g_dstImage3, Size(g_nGaussianBlurValue * 2 + 1, g_nGaussianBlurValue * 2 + 1), 0, 0);
    cout << "\n当前为【高斯滤波】处理效果,其内核大小为:" << g_nGaussianBlurValue * 2 + 1 << endl;
    imshow(WINDOWNAME, g_dstImage3);
}

//----------------------【on_MedianBlur()函数】------------------------  
static void on_MedianBlur(int, void*)
{
    medianBlur(g_srcIamge, g_dstImage4, g_nMedianBlurValue * 2 + 1);
    cout << "\n当前为【中值滤波】处理效果,其内核大小为:" << g_nMedianBlurValue * 2 + 1 << endl;
    imshow(WINDOWNAME, g_dstImage4);
}

//----------------------【on_BilateralFilter()函数】------------------------  
static void on_BilateralFilter(int, void*)
{
    bilateralFilter(g_srcIamge, g_dstImage5, g_nBilateralFilterValue, g_nBilateralFilterValue * 2, g_nBilateralFilterValue / 2);
    cout << "\n当前为【双边滤波】处理效果,其内核大小为:" << g_nBilateralFilterValue << endl;
    imshow(WINDOWNAME, g_dstImage5);
}

//----------------------【on_GuidedFilter()函数】------------------------  
static void on_GuidedFilter(int, void*)
{
    vector<Mat> vSrcImage, vResultImage;
    //【1】对源图像进行通道分离,并对每个分通道进行导向滤波操作  
    split(g_srcIamge, vSrcImage);
    for (int i = 0; i < 3; i++)
    {
        Mat tempImage;
        vSrcImage[i].convertTo(tempImage, CV_64FC1, 1.0 / 255.0); //将分通道转换成浮点型数据  
        Mat cloneImage = tempImage.clone(); //将tempImage复制一份到cloneImage  
        Mat resultImage;
        guidedFilter(tempImage, cloneImage, resultImage, g_nGuidedFilterValue * 2 + 1, 0.01); //对分通道分别进行导向滤波  
        vResultImage.push_back(resultImage); //将分通道导向滤波后的结果存放到vResultImage中  
    }
    //【2】将分通道导向滤波后结果合并  
    merge(vResultImage, g_dstImage6);
    cout << "\n当前处理为【导向滤波】,其内核大小为:" << g_nGuidedFilterValue * 2 + 1 << endl;
    imshow(WINDOWNAME, g_dstImage6);
}

//-------------------【实现导向滤波器函数部分】-------------------------  
void guidedFilter(Mat& srcMat, Mat& guidedMat, Mat& dstImage, int radius, double eps)
{
    //------------【0】转换源图像信息,将输入扩展为64位浮点型,以便以后做乘法------------  
    srcMat.convertTo(srcMat, CV_64FC1);
    guidedMat.convertTo(guidedMat, CV_64FC1);
    //--------------【1】各种均值计算----------------------------------  
    Mat mean_p, mean_I, mean_Ip, mean_II;
    boxFilter(srcMat, mean_p, CV_64FC1, Size(radius, radius)); //生成待滤波图像均值mean_p   
    boxFilter(guidedMat, mean_I, CV_64FC1, Size(radius, radius)); //生成导向图像均值mean_I     
    boxFilter(srcMat.mul(guidedMat), mean_Ip, CV_64FC1, Size(radius, radius)); //生成互相关均值mean_Ip  
    boxFilter(guidedMat.mul(guidedMat), mean_II, CV_64FC1, Size(radius, radius)); //生成导向图像自相关均值mean_II  
    //--------------【2】计算相关系数,计算Ip的协方差cov和I的方差var------------------  
    Mat cov_Ip = mean_Ip - mean_I.mul(mean_p);
    Mat var_I = mean_II - mean_I.mul(mean_I);
    //---------------【3】计算参数系数a、b-------------------  
    Mat a = cov_Ip / (var_I + eps);
    Mat b = mean_p - a.mul(mean_I);
    //--------------【4】计算系数a、b的均值-----------------  
    Mat mean_a, mean_b;
    boxFilter(a, mean_a, CV_64FC1, Size(radius, radius));
    boxFilter(b, mean_b, CV_64FC1, Size(radius, radius));
    //---------------【5】生成输出矩阵------------------  
    dstImage = mean_a.mul(srcMat) + mean_b;
}

三、显示

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/817168.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

01 制作Windows11启动盘及安装 || 包含校验ISO映像的方法

前言 由于空间越来越不够用了&#xff0c;上次为Ubuntu分配了96G的空间依然是快要被用完&#xff0c;连一个数据集都放不下了&#xff0c;因此我不得不选择换硬盘。 由于是离谱的华为Mate book D 15的2021款逆天机型&#xff0c;我没有第二个硬盘位。至于说移动硬盘的解决方案…

python3GUI--我的翻译器By:PyQt5(附下载地址)

文章目录 一&#xff0e;前言二&#xff0e;展示1.主界面2.段落翻译3.单词翻译 三&#xff0e;设计1.UI设计2.软件设计3.参考 四&#xff0e;总结 一&#xff0e;前言 很早之前写过一篇python3GUI–翻译器By:PyQt5&#xff08;附源码&#xff09; &#xff0c;但是发现相关引擎…

LED显示屏技术:数码时代的绚丽舞台

随着信息技术的飞速发展&#xff0c;LED显示屏技术成为现代社会不可或缺的一部分。这种技术以其高亮度、高清晰度和多样化的应用领域&#xff0c;在数字化时代展现出绚丽多彩的画面&#xff0c;为我们带来了前所未有的视觉体验。本文将探讨LED显示屏技术的原理、应用以及对于现…

【JavaEE】简单了解JVM

目录 一、JVM中的内存区域划分 二、JVM的类加载机制 1、类加载的触发时机 2、双亲委派模型 1.1、向上委派 1.2、向下委派 三、JVM中的垃圾回收机制&#xff08;GC&#xff09; 1、确认垃圾 1.1、引用计数&#xff08;Java实际上没有使用这个方案&#xff0c;但是Pytho…

超详细 | 模拟退火算法及其MATLAB实现

模拟退火算法(simulated annealing&#xff0c;SA)是20世纪80年代初期发展起来的一种求解大规模组合优化问题的随机性方法。它以优化问题的求解与物理系统退火过程的相似性为基础&#xff0c;利用Metropolis算法并适当地控制温度的下降过程实现模拟退火&#xff0c;从而达到求解…

RK3588平台开发系列讲解(调试篇)如何进行性能分析

文章目录 一、什么是性能分析呢?二、系统级工具三、源码级工具沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇将介绍性能分析(Performance Profiling) 最简单的性能分析工具是 top,可以快速查看进程的 CPU、内存使用情况;pstack 和 strace 能够显示进程在用…

大数据面试题:HBase的RegionServer宕机以后怎么恢复的?

面试题来源&#xff1a; 《大数据面试题 V4.0》 大数据面试题V3.0&#xff0c;523道题&#xff0c;679页&#xff0c;46w字 可回答&#xff1a;1&#xff09;HBase一个节点宕机了怎么办&#xff1b;2&#xff09;HBase故障恢复 参考答案&#xff1a; 1、HBase常见故障 导…

简要介绍 | 解析模态之间的联系:跨模态学习与多模态学习的区别和联系

注1&#xff1a;本文系“简要介绍”系列之一&#xff0c;仅从概念上对跨模态学习和多模态学习进行非常简要的介绍&#xff0c;不适合用于深入和详细的了解。 解析模态之间的联系&#xff1a;跨模态学习与多模态学习的区别和联系 在人工智能的广泛领域中&#xff0c;跨模态学习…

森林中的兔子(力扣)数学思维 JAVA

森林中有未知数量的兔子。提问其中若干只兔子 “还有多少只兔子与你&#xff08;指被提问的兔子&#xff09;颜色相同?” &#xff0c;将答案收集到一个整数数组 answers 中&#xff0c;其中 answers[i] 是第 i 只兔子的回答。 给你数组 answers &#xff0c;返回森林中兔子的…

Python自动化办公-文件整理脚本

哈喽大家好&#xff0c;今天给大家介绍python自动化办公-文件整理脚本 今天讲解文件整理脚本的实现过程。这是一个很有用的技能&#xff0c;可以帮助你管理你的电脑上的各种文件。需求如下&#xff1a; 需求内容&#xff1a;给定一个打算整理的文件夹目录&#xff0c;这个脚本…

django实现部门表的增删改查界面

1、前期准备 部署好mysql数据库&#xff0c;创建好unicom数据库下载好bootstap的插件下载好jquery的插件下载好mysqlclient-1.4.6-cp36-cp36m-win_amd64.whl的安装包&#xff0c;根据python的版本下载 2、创建项目 在pycharm中创建项目 在pycharm的终端创建虚拟环境 py -m v…

【软件测试】性能测试工具- LoadRunner的介绍和使用

目录 1. LoadRunner是什么2. LoadRunner环境搭建3. LoadRunner三大组件4. LoadRunner脚本录制4.1 WebTous项目介绍启动WebTous项目访问WebTous项目相关配置 4.2 脚本录制新建脚本录制脚本运行脚本 4.3 脚本加强插入事务插入集合点插入检查点插入日志字符串比较 1. LoadRunner是…

Nyan Progress Bar 更换进度条插件

打开idea 每天面对进度条怪无聊的&#xff0c;今天无意之中发现一个插件还挺有意思的 Nyan Progress Bar 当然啦&#xff0c;根据自己的喜欢进行选择 安装好之后&#xff0c;然后再打开idea

【计算机视觉|人脸建模】SOFA:基于风格、由单一示例的2D关键点驱动的3D面部动画

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;SOFA: Style-based One-shot 3D Facial Animation Driven by 2D landmarks 链接&#xff1a;SOFA: Style-based One-shot 3D Facial Animation Driven by 2D landmarks | Proceedings of …

Python 进阶(六):文件读写(I/O)

❤️ 博客主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;Python 入门核心技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; 文章目录 1. 打开文件2. 读取文件2.1 逐行读取文件2.2 读取所有行 3. 写入文件3.1 向文件中写入…

华为数通HCIA-ARP(地址解析协议)详细解析

地址解析协议 (ARP) ARP &#xff08;Address Resolution Protocol&#xff09;地址解析协议&#xff1a; 根据已知的IP地址解析获得其对应的MAC地址。 ARP&#xff08;Address Resolution Protocol&#xff0c;地址解析协议&#xff09;是根据IP地址获取数据链路层地址的一个…

ES-5-进阶

单机 & 集群 单台 Elasticsearch 服务器提供服务&#xff0c;往往都有最大的负载能力&#xff0c;超过这个阈值&#xff0c;服务器 性能就会大大降低甚至不可用&#xff0c;所以生产环境中&#xff0c;一般都是运行在指定服务器集群中 配置服务器集群时&#xff0c;集…

C++第三大特性:多态(1)

目录 一.多态的含义 1.普通调用&#xff1a; 2.多态调用 重写函数&#xff1a; 实现多态调用的三个条件&#xff1a;&#xff08;缺一不可&#xff09; 情况1&#xff1a;当只有父类中存在虚函数&#xff0c;两个子类都没有virtual形成的虚函数时&#xff0c;也能形成多态&…

测试开发人员如何进行局部探索性测试?一张图告诉你

我们都知道全局探索性测试的漫游测试法&#xff0c;也知道局部探索性测试可以从用户输入、状态、代码路径、用户数据和执行环境测试着手点。 那么&#xff0c;如果我们能够获取开发代码&#xff0c;我们怎么从代码入手&#xff0c;进行具体的局部探索性测试呢&#xff1f; 简单…

1227. 分巧克力(简单,易懂)

输入样例&#xff1a; 2 10 6 5 5 6输出样例&#xff1a; 2 这个题就是基础的二分问题&#xff0c;做题思路&#xff1a; 找到一个数&#xff0c;让其满足&#xff0c;所有小块的边值&#xff0c;且最终的总和要大于等于我们的K 第一次做错了&#xff01;&#xff01; #in…