基于opencv的几种图像滤波

一、介绍

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

    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.mfbz.cn/a/55217.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kafka系列之:记录一次Kafka Topic分区扩容,但是下游flink消费者没有自动消费新的分区的解决方法

Kafka系列之:记录一次Kafka Topic分区扩容,但是下游flink消费者没有自动消费新的分区的解决方法 一、背景二、解决方法三、实现自动发现新的分区一、背景 生产环境Kafka集群压力大,Topic读写压力大,消费的lag比较大,因此通过扩容Topic的分区,增大Topic的读写性能理论上下…

IDEA开启并配置services窗口

前言&#xff1a; 一般一个spring cloud项目中大大小小存在几个十几个module编写具体的微服务项目。此时&#xff0c;如果要调试测需要依次启动各个项目比较麻烦。 方法一&#xff1a; 默认第一次打开项目的时候&#xff0c;idea会提示是否增加这个选项卡&#xff0c;如果你没…

【ArcGIS Pro二次开发】(55):给多个要素或表批量添加字段

在工作中可能会遇到这样的场景&#xff1a;有多个GDB要素、表格&#xff0c;或者是SHP文件&#xff0c;需要给这个要素或表添加相同的多个字段。 在这种情况下&#xff0c;手动添加就变得很繁琐&#xff0c;于是就做了这个工具。 需求具体如下图&#xff1a; 左图是待处理数据…

【iOS】多线程 锁问题总结

文章目录 前言1. 你理解的多线程优点缺点 2. atomic 和 nonatomic 的区别及其作用3. GCD的队列类型 - 三种队列类型4. GCD的死锁问题5. 多线程之间的区别和联系6. 进程和线程&#xff1f;进程间的通信方式线程间的通信方式 6. iOS的线程安全手段如何保证 前言 iOS 锁和多线程的…

HCIP——BGP基础

BGP 一、BGP基础二、BGP的发展历史三、BGP在企业中的应用四、距离矢量型协议和路径矢量型协议五、BGP的特征六、BGP的对等关系七、BGP的数据包八、BGP的状态机九、BGP的工作过程十、BGP的路由黑洞十一、BGP的环路问题EBGP水平分割IBGP水平分割 十二、BGP的基本配置1、BGP的对等…

【机器学习】Classification using Logistic Regression

Classification using Logistic Regression 1. 分类问题2. 线性回归方法3. 逻辑函数&#xff08;sigmod&#xff09;4.逻辑回归5. 决策边界5.1 数据集5.2 数据绘图5.3 逻辑回归与决策边界的刷新5.4 绘制决策边界 附录 导入所需的库 import numpy as np %matplotlib widget imp…

开源代码分享(9)—面向100%清洁能源的发输电系统扩展规划(附matlab代码)

1.背景介绍 1.1摘要 本文提出了一种新颖的建模框架和基于分解的解决策略&#xff0c;将随机规划&#xff08;SP&#xff09;和鲁棒优化&#xff08;RO&#xff09;相结合&#xff0c;以应对协调中长期电力系统规划中的多重不确定性。从独立系统运营商&#xff08;ISO&#xff…

测试|性能测试相关理论

测试|性能测试相关理论&#xff08;了解&#xff09; 文章目录 测试|性能测试相关理论&#xff08;了解&#xff09;1.什么是性能测试生活中遇到的软件性能问题&#xff1a;性能测试定义&#xff1a;性能测试和功能测试有什么区别&#xff1a;性能好坏的评价指标影响一个软件性…

Redis安装部署(基于windows平台)

redis简介 键值对存储数据库是NoSQL数据库的一种类型&#xff0c;也是最简单的NoSQL数据库。顾名思义&#xff0c;键值对存储数据库中的数据是以键值对的形式来存储的。常见的键值对存储数据库有Redis、Tokyo Cabinet/Tyrant、Voldemort以及Oracle BDB数据库。 Remote Diction…

一起学算法(二维数组篇)

1.概念定义 1.矩阵的定义 矩阵A(nm)的定义时按照长方形排列的复数或实数集合&#xff0c;其中n代表的是行数&#xff0c;m代表的是列数。如下所示&#xff0c;代表的是一个4x3的矩阵 在Java中&#xff0c;我们可以用A[n][m]来代表一个n*m的矩阵&#xff0c;其中A[i][j]代表的是…

2023年的深度学习入门指南(23) - ChatGLM2

2023年的深度学习入门指南(23) - ChatGLM2 在《在你的电脑上运行大模型》这一节&#xff0c;我们曾经介绍过ChatGLM模型&#xff0c;它是当时最好的中文大模型之一。现在&#xff0c;它又更新到了第二代&#xff0c;即ChatGLM2。 当时&#xff0c;我们的技术储备还不足&#…

upload-labs详解------持续更新

目录 注&#xff1a; 搭建&#xff1a; pass-01&#xff08;前端绕过&#xff09; pass-02&#xff08;后缀绕过&#xff09; pass-03&#xff08;黑名单绕过&#xff09; pass-04&#xff08;Apache解析漏洞\.htaccess文件绕过&#xff09; 注&#xff1a; 本项目提供的…

Halcon学习之一维测量实战之测量矩形(一)

一、采集图像 (1)测量充电器 测量充电器的引脚,然后每次旋转充电器,让测量矩形都跟着它转,这就是定位+测量, (2)测量钥匙 (3)测量瓶盖 我们后面还会涉及到拟合的问

【Python】Web学习笔记_flask(1)——模拟登录

安装flask pip3 install flask 第一部分内容&#xff1a; 1、主页面输出hello world 2、根据不同用户名参数输出用户信息 3、模拟登录 from flask import Flask,url_for,redirectappFlask(__name__)app.route(/) def index():return hello worldapp.route(/user/<uname…

IDEA中连接虚拟机 管理Docker

IDEA中连接虚拟机 管理Docker &#x1f4d4; 千寻简笔记介绍 千寻简笔记已开源&#xff0c;Gitee与GitHub搜索chihiro-notes&#xff0c;包含笔记源文件.md&#xff0c;以及PDF版本方便阅读&#xff0c;且是用了精美主题&#xff0c;阅读体验更佳&#xff0c;如果文章对你有帮…

阻塞队列BlockingQueue详解

一、阻塞队列介绍 1、队列 队列入队从队首开始添加&#xff0c;直至队尾&#xff1b;出队从队首出队&#xff0c;直至队尾&#xff0c;所以入队和出队的顺序是一样的 Queue接口 add(E) &#xff1a;在指定队列容量条件下添加元素&#xff0c;若成功返回true&#xff0c;若当前…

Flask简介与基础入门

一、了解框架 Flask作为Web框架&#xff0c;它的作用主要是为了开发Web应用程序。那么我们首先来了解下Web应用程序。Web应用程序 (World Wide Web)诞生最初的目的&#xff0c;是为了利用互联网交流工作文档。 1、一切从客户端发起请求开始。 所有Flask程序都必须创建一个程序…

webScoket

webScoket是什么&#xff1f; 支持端对端通讯可以由客户端发起&#xff0c;也可以有服务端发起用于消息通知、直播间讨论区、聊天室、协同编辑等 做一个简单的webScoket 客户端配置&#xff1a; 1、新建一个页面叫web-scoket.html <!DOCTYPE html> <html lang"…

【CSS】ios上fixed固定定位的input输入框兼容问题

需求 &#xff1a; 实现一个简单的需求&#xff0c;上方是搜索框并且固定顶部&#xff0c;下方是滚动的内容list 问题 : 若如图上方使用固定定位, 下方用scroll-view, 在安卓上是没有问题的, 但是发现ios上会出现兼容问题 : 问题1: 当content list滚动到中间时再去搜索, 展…
最新文章