【OpenCV • c++】图像平滑处理(2) —— 方框滤波 | 盒滤波 | 源码分析

news2024/10/6 12:24:15

文章目录

    • 前言
    • 一、方框滤波
      • 代码演示
    • 二、源码分析

前言

  前文我们了解了什么是图像平滑处理、图像滤波、邻域算子与线性邻域滤波、以及如何使用方框滤波,本文我们来分析一下方框滤波的源码。

一、方框滤波

 	void boxFilter(InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1, -1), boolnormalize=true, int borderType=BORDEX_DEFAULT)

  其中,第一个参数表示输入的原图像,第二个参数表示目标图像,需要和原图像一样尺寸和类型,第三个参数表示输出图像的深度,-1代表使用原深度,即src.depth(),第四个参数表示 Size 类型的 ksize ,内核的大小。一般用 Size(w, h) 表示内核的大小,其中 w 为像素宽度,h 为像素的高度。Size(3, 3)的核大小。第五个参数表示锚点(平滑的那个点)。默认是 Point(-1, -1)。如果这个点的坐标是负值的话,就取核的中心为锚点。第六个参数六表示内核是否被其区域归一化了,第七个参数表示用于推断图像外部像素的某种边界模式。

代码演示

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;

int main()
{
    // 读取输入图像
    Mat src = imread("D://cc.jpg", IMREAD_COLOR);
    if (src.empty())
    {
        std::cout << "无法读取图像" << std::endl;
        return -1;
    }

    // 创建输出矩阵
    Mat dst;

    // 应用方框滤波器
    int ddepth = -1;  // 使用与输入图像相同的深度
    Size ksize(3, 3); // 内核的大小
    Point anchor(-1, -1); // 内核中的锚点
    bool normalize = true; // 归一化内核
    int borderType = BORDER_DEFAULT; // 边界类型

    boxFilter(src, dst, ddepth, ksize, anchor, normalize, borderType);

    // 显示结果
    imshow("输入", src);
    imshow("输出", dst);
    waitKey(0);

    return 0;
}

在这里插入图片描述

二、源码分析

//方框滤波器基类生成函数
Ptr<FilterEngine> createBoxFilter(int srcType, int dstType, Size ksize,
    Point anchor, bool normalize, int borderType)
{

    int sdepth = CV_MAT_DEPTH(srcType);  // 获取输入矩阵的深度
    int cn = CV_MAT_CN(srcType), sumType = CV_64F;  // 获取输入矩阵的通道数,并设置默认的累加类型为CV_64F
    if (sdepth == CV_8U && CV_MAT_DEPTH(dstType) == CV_8U &&
        ksize.width * ksize.height <= 256)
        sumType = CV_16U;  // 如果输入矩阵和输出矩阵的深度都是CV_8U,并且滤波核的大小不超过256,则将累加类型设置为CV_16U
    else if (sdepth <= CV_32S && (!normalize ||
        ksize.width * ksize.height <= (sdepth == CV_8U ? (1 << 23) :
            sdepth == CV_16U ? (1 << 15) : (1 << 16))))
        sumType = CV_32S;  // 如果输入矩阵的深度小于等于CV_32S,并且滤波核的大小不超过一定阈值,则将累加类型设置为CV_32S
    sumType = CV_MAKETYPE(sumType, cn);  // 根据累加类型和通道数创建累加矩阵的数据类型

    Ptr<BaseRowFilter> rowFilter = getRowSumFilter(srcType, sumType, ksize.width, anchor.x);  // 获取行方向上的累加滤波器
    Ptr<BaseColumnFilter> columnFilter = getColumnSumFilter(sumType,
        dstType, ksize.height, anchor.y, normalize ? 1. / (ksize.width * ksize.height) : 1);  // 获取列方向上的累加滤波器

    return makePtr<FilterEngine>(Ptr<BaseFilter>(), rowFilter, columnFilter,
        srcType, dstType, sumType, borderType);  // 创建FilterEngine对象并返回
}

//方框滤波器实现
void boxFilter(InputArray _src, OutputArray _dst, int ddepth,
    Size ksize, Point anchor,
    bool normalize, int borderType)
{
    Mat src = _src.getMat();  // 获取输入矩阵
    int sdepth = src.depth(), cn = src.channels();
    if (ddepth < 0)
        ddepth = sdepth;
    _dst.create(src.size(), CV_MAKETYPE(ddepth, cn));  // 创建输出矩阵
    Mat dst = _dst.getMat();
    if (borderType != BORDER_CONSTANT && normalize && (borderType & BORDER_ISOLATED) != 0)
    {
        if (src.rows == 1)
            ksize.height = 1;  // 如果输入矩阵的行数为1,则将滤波核的高度设置为1
        if (src.cols == 1)
            ksize.width = 1;  // 如果输入矩阵的列数为1,则将滤波核的宽度设置为1
    }

    Point ofs;  // 偏移量
    Size wsz(src.cols, src.rows);  // 窗口大小
    if (!(borderType & BORDER_ISOLATED))
        src.locateROI(wsz, ofs);  // 定位输入矩阵的感兴趣区域(ROI)

    Ptr<FilterEngine> f = createBoxFilter(src.type(), dst.type(),
        ksize, anchor, normalize, borderType);  // 创建方框滤波器

    f->apply(src, dst, wsz, ofs);  // 应用方框滤波器
}

  通过阅读方框滤波的部分源码,可以发现,boxFilter()函数在调用后先是进行了一系列的判断,确定图像属性,再通过调用createBoxFilter()函数来创建方框滤波器。

  • 🚀 个人简介:CSDN「博客新星」TOP 10 , C/C++ 领域新星创作者
  • 💟 作    者:锡兰_CC ❣️
  • 📝 专    栏:【OpenCV • c++】计算机视觉
  • 🌈 若有帮助,还请关注➕点赞➕收藏,不行的话我再努努力💪💪💪

其他

更多专栏订阅推荐:

  • 👍 【开卷数据结构】
  • 💛 【备战蓝桥,冲击省一】
  • 💕   从零开始的 c++ 之旅
  • 💖 【OpenCV • c++】计算机视觉

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

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

相关文章

面试常见 | 项目上没有亮点,如何包装?

很多技术人在公司用的老技术&#xff0c;而且很多都是搬业务代码且做枯燥乏味的CRUD&#xff0c;在面试提交简历或做自我介绍的时候并不突出&#xff0c;这种情况&#xff0c;如何破局&#xff1f; 首先不管你做的啥项目&#xff0c;全世界不可能只有你自己在做&#xff0c;比…

Android Handler用法

Android Handler用法 为什么要设计Handler机制&#xff1f;Handler的用法1、创建Handler2、Handler通信2.1 sendMessage 方式2.2 post 方式 Handler常用方法1、延时执行2、周期执行 HandlerThread用法主线程-创建Handler子线程-创建Handler FAQMessage是如何创建主线程中Looper…

Agent AI智能体的未来

未来社会中的智能使者&#xff1a;Agent AI智能体的可能性与挑战 随着科技的迅速进步&#xff0c;人工智能已深入我们生活的各个领域&#xff0c;而Agent AI智能体作为与人工智能紧密相关的一个分支&#xff0c;其未来发展无疑是值得期待的。Agent AI智能体&#xff0c;或称为…

JAVA Coding 规范

Coding 规范 文章目录 Coding 规范一.文件规范1.1 声明1.2 缩进1.3 空行1.4 空格1.5 对齐1.6 小括号1.7 花括号1.8 代码长度 二.命名规范2.1 命名总则2.2 命名空间2.3 类与接口2.4 方法命名2.5 属性命名2.6 常量命名2.7 变量命名 三.语句规范3.1 语句总则3.2 循环语句3.3 Switc…

【note3】linux驱动基础,

文章目录 1.互斥锁和自旋锁选择&#xff1a;自旋锁&#xff08;开销少&#xff09;的自旋时间和被锁住的代码执行时间成正比关系2.linux错误码&#xff1a;64位错误指针指向内核空间最后一页&#xff0c;对于 1.互斥锁和自旋锁选择&#xff1a;自旋锁&#xff08;开销少&#x…

QT:核心控件-QWidget

文章目录 控件enableobjectNamegeometrysetWindowTitleopacitycursorFonttooltipstyleSheet 控件 什么是控件&#xff1f; 如上所示&#xff0c;就是控件&#xff0c;而本篇要做的就是对于这些控件挑选一些比较有用的常用的进行讲解分析 在QT的右侧&#xff0c;会有对应的空间…

【面试经典 150 | 分治】将有序数组转换为二叉搜索树

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;中序遍历递归建树 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等…

如何有效地合并和分类多个文件目录?

在现代办公环境中&#xff0c;文件管理和组织是至关重要的。随着科技的发展&#xff0c;我们不再仅仅依赖于纸质文件&#xff0c;而是更多地使用电子设备来存储和管理信息。这种转变带来了一些新的挑战&#xff0c;其中之一就是如何有效地合并和分类多个目录文件。一&#xff0…

Sortable 拖拽行实现el-table表格顺序号完整例子,vue 实现表格拖拽行顺序号完整例子

npm install sortable<template><vxe-modalref"modalRef"v-model"showModal"title"详情"width"70vw"height"60vh"class"his"transfer><el-table ref"tableRef" :data"tableData&q…

树莓派5用docker运行Ollama3

书接上回&#xff0c;树莓派5使用1panel安装 Ollama 点击终端就可以进入容器 输入以下代码 ollama run llama3Llama3 是市场推崇的版本。您的 树莓派5上必须至少有 4.7GB 的可用空间&#xff0c;因此用树莓派玩机器学习就必须配置大容量的固态硬盘。用1panel部署网络下载速度…

4G远程温湿度传感器在农业中的应用—福建蜂窝物联网科技有限公司

解决方案 农业四情监测预警解决方案 农业四情指的是田间的虫情、作物的苗情、气候的灾情和土壤墒情。“四情”监测预警系统的组成包括管式土壤墒情监测站、虫情测报灯、气象站、农情监测摄像机&#xff0c;可实时监测基地状况,可以提高监测的效率和准确性&#xff0c;为农业生…

“Unite“ > MacOS下很不错的网站转应用App的工具

前言 前不久在浏览mac论坛&#xff0c;无意了解到一款非常好的工具&#xff0c;可以将网站转换为app&#xff0c;考虑到我们现在的主要应用都从本地客户端转成web形式使用&#xff0c;但基于本能的使用习惯&#xff0c;还是希望有个快捷的访问信息&#xff0c;这个应用非常适合…

202012青少年软件编程(Python)等级考试试卷(一级)

第 1 题 【单选题】 运行下方代码段&#xff0c;输出是6&#xff0c;则输入的可能是&#xff08; &#xff09;。 a eval(input())print(a)A :8%2 B :8/2 C :3*2 D :3**2 正确答案:C 试题解析: 第 2 题 【单选题】 关于Python变量&#xff0c;下列叙述正确的是&#x…

Offer必备算法33_DFS爆搜深搜回溯剪枝_八道力扣题详解(由易到难)

目录 ①力扣784. 字母大小写全排列 解析代码1_path是全局变量 解析代码2_path是函数参数 ②力扣526. 优美的排列 解析代码 ③力扣51. N 皇后 解析代码 ④力扣36. 有效的数独 解析代码 ⑤力扣37. 解数独 解析代码 ⑥力扣79. 单词搜索 解析代码 ⑦力扣1219. 黄金矿…

[嵌入式系统-58]:RT-Thread-内核:线程间通信,邮箱mailbox、消息队列MsgQueue、信号Signal

目录 线程间通信 1. 邮箱 1.1 邮箱的工作机制 1.2 邮箱控制块 1.3 邮箱的管理方式 &#xff08;1&#xff09;创建和删除邮箱 &#xff08;2&#xff09;初始化和脱离邮箱 &#xff08;3&#xff09;发送邮件 &#xff08;4&#xff09;等待方式发送邮件 &#xff08…

excel 和 text 文件的读写操作

excel 和 text 文件的读写操作 1. text 文件读写包 open语句 在文件存在的时候&#xff0c;即打开文件&#xff08;此时操作会覆盖文件&#xff0c;实际就是删除文件重后重新创建&#xff09;&#xff1b;在文件不存在的时候&#xff0c;即创建文件。 import sys print(sys.…

商务谈判技巧与口才书籍有哪些类型

商务谈判技巧与口才书籍有哪些类型&#xff08;3篇&#xff09; 商务谈判技巧与口才书籍的类型丰富多样&#xff0c;以下从三个角度进行介绍&#xff1a; **篇&#xff1a;基础理论与策略类书籍 这类书籍通常深入剖析谈判的本质&#xff0c;系统介绍谈判的原理、技巧和策略。…

S-Clustr+Nets3e 僵尸网络偷拍照片插件

项目地址:https://github.com/MartinxMax/S-Clustr-Ring 更新内容 本次将Nets3e(https://github.com/MartinxMax/Nets3e/tree/Nets3e_V1.1.4)插件成功嵌入,意味着你可以指定任意节点下的主机进行拍照 一些嵌入式设备与工业PLC设备与个人PC计算机回连控制 核心服务端搭建 最好…

MySQL-----多表查询(二)

目录 一.子查询概述&#xff1a; 二&#xff1a;标量子查询&#xff1a; 三&#xff1a;列子查询&#xff1a; 四&#xff1a;行子查询&#xff1a; 五&#xff1a;表子查询&#xff1a; 六&#xff1a;练习部分&#xff1a; 写在之前&#xff1a;本文承接上文MySQL-----多…

邦注科技 温控箱对企业的重要性

注塑加工是将加热的熔融塑料注入模具中形成所需产品的工艺过程。良好的注塑加工工艺需要控制好许多参数&#xff0c;其中最重要的因素之一就是模具的温度。模具温度的不稳定会导致产品尺寸大小、表面缺陷等方面的问题&#xff0c;甚至会导致生产不良品&#xff0c;加大生产成本…