当前位置: 首页 > news >正文

opencv 滤波

1. 卷积核

卷积核就是一个小数字矩阵 ,在图像上滑动,小数字矩阵和对应位置的像素做运算,实现模糊、锐化、边缘检测。

blurGaussianBlurmedianBlurfilter2D全部底层都是卷积运算

假设 3×3 卷积核,滑动到图像某一块:

图像像素 卷积核kernel [10 20 30] [a b c] [40 50 60] [d e f] [70 80 90] [g h i]

输出中心像素 =10*a + 20*b +30*c +40*d +50*e +60*f +70*g +80*h +90*i

核窗口逐像素向右、向下滑动,遍历整张图,生成输出图像。

2. 均值滤波

void blur(

InputArray src,

InputArray dst,

Size ksize,

Point point = Point(-1, -1),

int borderType = BORDER_DEFAULT

);

原理:在图像上滑动一个矩形窗口(卷积核),把窗口内所有像素求算术平均值,赋值给窗口中心输出像素。

cv::Mat src,dst; src = imread("test.jpg"); cv::blur(src,dst,cv::Size(5,5));

cv::Size(3,3) 卷积核大小,必须奇数, size越大越模糊

2. 高斯模糊

void GaussianBlur(

InputArray src,

InputArray dst,

Size ksize,

double sigmaX,

double sigmaY = 0,

int borderType = BORDER_DEFAULT

);

Size 设置卷积核的大小,必须是奇数 Size(0,0) 核大小有sigmaX自动计算

sigmaX:X方向高斯标准差;数值越大,模糊越强 sigmaX = 0 ,sigmaX由Size()自动计算

sigmaY: Y方向高斯标准差;sigmaY传0就自动等于sigmaX

Mat src,dst; GaussianBlur(src,dst,Size(5,5),0); // sigmaX由size自动计算 GaussianBlue(src,dst,Size(0,0),4); // Size(0,0) 核大小由sigmaX 自动计算

3. 中值滤波

void medianBlur(InputArray src, InputArray dst, int ksize);

原理:取卷积窗口内像素中位数,不是平均值。

ksize 窗口大小,取像素值,必须是奇数

cv::Mat src,dst; medianBlure(src, dst, 5);

4. 双边滤波

void bilateral(

InputArray src,

InputArray dst,

int d,

double sigmaColor,

double sigmaSpace,

int borderType = BORDER_DEAFAULT

);

双边滤波:保边缘的模糊,美颜算法底层。

❗不是固定卷积核,权重是动态计算,每一个位置的权重都不一样,计算开销大。

  1. d:滤波邻域直径。
    • d = 0:程序自动根据sigmaSpace计算邻域大小(推荐写 0)
  2. sigmaColor:颜色域标准差
    • 值越大:允许相差更大的颜色参与平滑;越大模糊越强。
    • 一般取值:25 ~ 100
  3. sigmaSpace:空间域标准差,单位像素
    • 值越大:参与计算的像素范围越大。
    • 一般取值:25 ~ 100
  4. borderType:边界填充,默认即可,不用修改

实例代码:

mainwindow.cpp

#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { qDebug() << __func__ << __LINE__; ui->setupUi(this); initMainWindow(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::initMainWindow() { qDebug() << __func__ << __LINE__; ui->blurViewLabel->setFixedSize(723,399); ui->gaussianViewLabel->setFixedSize(723,399); ui->medianViewLabel->setFixedSize(723,399); ui->bilateralViewLabel->setFixedSize(723,399); QString imgPath = R"(D:\new_share\016_opencv\OpenCVFilter\1.jpg)"; Mat imgData = imread(imgPath.toStdString()); // BGR 格式 cvtColor(imgData, imgData , COLOR_BGR2RGB); // 转为 RGB 格式 myImg = imgData; blurImg = QImage((const unsigned char*)imgData.data, imgData.cols, imgData.rows, static_cast<int>(imgData.step),QImage::Format_RGB888).copy(); gaussianImg = blurImg; medianImg = blurImg; bilateralImg = blurImg; imgShow(); } void MainWindow::imgShow() { qDebug() << __func__ << __LINE__; ui->blurViewLabel->setPixmap(QPixmap::fromImage(blurImg.scaled(ui->blurViewLabel->size()))); ui->gaussianViewLabel->setPixmap(QPixmap::fromImage(gaussianImg.scaled(ui->gaussianViewLabel->size()))); ui->medianViewLabel->setPixmap(QPixmap::fromImage(medianImg.scaled(ui->medianViewLabel->size()))); ui->bilateralViewLabel->setPixmap(QPixmap::fromImage(bilateralImg.scaled(ui->bilateralViewLabel->size()))); } void MainWindow::imgProc(int kernel) { qDebug() << __func__ << __LINE__; Mat imgSrc = myImg; Mat imgBlurDst = imgSrc.clone(); Mat imgGaussianDst = imgSrc.clone(); Mat imgMedianDst = imgSrc.clone(); Mat imgBilateralDst = imgSrc.clone(); int value = 1; value = value + kernel*2; blur(imgSrc,imgBlurDst,Size(value,value),Point(-1,-1)); GaussianBlur(imgSrc, imgGaussianDst, Size(value,value),0); medianBlur(imgSrc,imgMedianDst,value); bilateralFilter(imgSrc, imgBilateralDst, value, value*2.0, value/2.0); blurImg = QImage((const unsigned char*)imgBlurDst.data, imgBlurDst.cols, imgBlurDst.rows, static_cast<int>(imgBlurDst.step),QImage::Format_RGB888).copy(); gaussianImg = QImage((const unsigned char*)imgGaussianDst.data, imgGaussianDst.cols, imgGaussianDst.rows, static_cast<int>(imgGaussianDst.step), QImage::Format_RGB888).copy(); medianImg = QImage((const unsigned char*)imgMedianDst.data, imgMedianDst.cols, imgMedianDst.rows, static_cast<int>(imgMedianDst.step), QImage::Format_RGB888).copy(); bilateralImg = QImage((const unsigned char*)imgBilateralDst.data, imgBilateralDst.cols, imgBilateralDst.rows, static_cast<int>(imgBilateralDst.step), QImage::Format_RGB888).copy(); imgShow(); } void MainWindow::on_verticalSlider_valueChanged(int value) { qDebug() << __func__ << __LINE__; imgProc(value); }

mainwindow.h

#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <opencv2/opencv.hpp> QT_BEGIN_NAMESPACE using namespace cv; namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); void initMainWindow(); void imgShow(); void imgProc(int kernel); private slots: void on_verticalSlider_valueChanged(int value); private: Ui::MainWindow *ui; Mat myImg; QImage blurImg; QImage gaussianImg; QImage medianImg; QImage bilateralImg; }; #endif // MAINWINDOW_H

http://www.jsqmd.com/news/1351170/

相关文章:

  • 神奇弹幕:打造你的B站直播智能助手,让互动更高效
  • 电磁场边界条件:原理、记忆法与工程应用
  • 构建高可靠AI Agent工具调用层的四层防御架构与实践
  • COMSOL流固耦合仿真:自动网格划分策略与工程实践详解
  • 2026年乐山亮化工程与广告制作市场观察:本地化服务能力成核心竞争力! - 优质品牌商家
  • OpenCV C++实战:工业视觉物体计数与尺寸测量系统开发指南
  • 2026实测可用的免费视频转MP4的工具 亲测避坑指南 - 图片处理研究员
  • Agent编排与自定义Workflow设计:从ReAct模式到复杂AI系统构建
  • 后端性能优化,先从数据库查询和缓存设计入手
  • 自抗扰控制(ADRC)原理与工程实践:从PID局限到电机控制实例
  • 猴痘皮肤图像数据集
  • 医疗NLP本地化部署:OpenMed实现数据不离端的安全智能
  • 陇南本地防水补漏哪家专业?屋顶、卫生间、外墙、地下室、阳台漏水师傅测评(2026年8月新) - 北京优选
  • 移动开发双系统时代:安卓与鸿蒙技术栈解析
  • ENVI图像自动配准:从原理到实战的完整指南
  • 如何实现天猫多店防关联管理自动化?底层架构降维碾压,把店群做成工业流水线
  • Valhalla 静态工程审阅 |OpenClaw 源码证据驱动评测【开源基础设施特辑】
  • 2026年一次成型PE储罐实力厂家甄选:滚塑工艺耐腐蚀化工防腐源头企业精析 - 优企名品
  • OpenClaw AI智能体持久化记忆系统部署与优化指南
  • SQL优化实战:提升数据库性能的核心技巧
  • 若依框架核心架构与实战应用解析
  • 30L除湿机选购指南:从技术参数到实战场景的深度解析
  • 从提示词到上下文工程:OpenClaw如何构建大模型智能体基础设施
  • Agent多到眼花缭乱,到底哪个最好用
  • 沈阳本地防水补漏怎么选?屋顶卫生间外墙地下室阳台渗水检测大盘点(2026年8月新) - 金信达
  • 工业自动化10轴联动控制系统的设计与实现
  • NVIDIA GPU环境搭建与深度学习部署实战指南
  • Valhalla 静态工程审阅 |PilotDeck 源码证据驱动评测【开源基础设施特辑】
  • AI工程开发标准化指令模板:提升大模型应用开发效率与协作性
  • AI Agent上下文管理与知识库构建实战:从向量检索到智能记忆系统