【OpenCV C++Python】(五)图像平滑(模糊)

文章目录

  • 图像平滑
    • 均值滤波
    • 高斯滤波
    • 中值滤波
    • 双边滤波(Bilateral Filtering )
  • Python
  • C++

图像线性平滑空间滤波(加权均值滤波器,几何均值滤波,谐波均值滤波,逆谐波均值滤波),非线性平滑空间滤波(中值滤波,最大值滤波,最小值滤波)MATLAB自写函数实现

图像平滑

图像平滑,又称图像模糊,是一种简单而常用的图像处理操作,常用于图像去噪。

为了进行平滑操作,我们将对图像使用滤波。最常见的滤波器是线性的,其输出的像素值(即 g ( i , j ) ) g(i,j)) g(i,j))为输入像素值(即 f ( i + k , j + l ) f(i+k,j+l) f(i+k,j+l))的加权和,可以将滤波操作用卷积操作表示:

在这里插入图片描述

h ( k , l ) h (k,l) h(k,l)叫做核(kernel)。

下面简单介绍OpenCV中常用的滤波方法,包括均值滤波、高斯滤波中值滤波和双边滤波。

均值滤波

均值滤波的核为:
在这里插入图片描述

输出的每个像素是它的核覆盖的所有像素的平均值。

OpenCV提供了函数cv.blur()cv.boxFilter()实现均值滤波。cv.blur()的主要参数有:

  • src:输入图像;它可以有任意数量的通道,但类型应该是CV_8U, CV_16U, CV_16S, CV_32F或CV_64F。
  • dst:与src大小和类型相同的输出图像。
  • ksize:核的大小。
  • anchor:表示锚点(计算的像素)相对于整个核邻域的位置。如果为负值,则核的中心被视为锚点。默认值Point(-1,-1)
  • borderType:在图像边界补充像素,防止核的某些元素位于图像之外,有以下补充类型(BORDER_WRAP除外,默认为BORDER_DEFAULT )。等价于:
boxFilter(src, dst, src.type(), ksize, anchor, true, borderType)

高斯滤波

二维高斯函数可以表示:
在这里插入图片描述
其中 μ μ μ为均值(峰值), σ 2 σ^2 σ2为方差。

根据高斯函数得到的核示例:

3x35x5
1 16 [ 1 2 1 2 4 2 1 2 1 ] \frac{1}{16}\left[\begin{array}{lll}1 & 2 & 1 \\2 & 4 & 2 \\1 & 2 & 1\end{array}\right] 161 121242121 1 159 × [ 2 4 5 4 2 4 9 12 9 4 5 12 15 12 5 4 9 12 9 4 2 4 5 4 2 ] \frac{1}{159} \times\left[\begin{array}{ccccc}2 & 4 & 5 & 4 & 2 \\4 & 9 & 12 & 9 & 4 \\5 & 12 & 15 & 12 & 5 \\4 & 9 & 12 & 9 & 4 \\2 & 4 & 5 & 4 & 2\end{array}\right] 1591× 245424912945121512549129424542

高斯滤波是线性的,通过高斯核与输入图像的卷积进行计算,在OpenCV中可以通过函数cv.GaussianBlur()实现。

主要参数有:

  • src:源图像
  • dst:目标图像
  • ksize:需要两个参数,分别表示高和宽。wh必须是奇数和正数,否则将使用sigmaXsigmaY按照OpenCV内置的函数计算。
  • sigmaX:表示 x x x中的标准差,如果值为0,则按照OpenCV内置的函数由核大小计算 σ x σ_x σx
  • sigmaY:表示 y y y的标准差。写入0表示 σ y σ_y σy由核大小计算。
  • borderType:与均值滤波相同。

中值滤波

中值滤波器遍历图像的每个元素,并将每个像素替换为核区域内所有像素的中值。
中值滤波通过函数cv.medianBlur()完成的。主要参数有:

  • src:源图像
  • dst:目标图像,必须与src类型相同
  • ksize:核的大小。因为我们使用的是方形窗口,所以只有一个参数。另外,还必须是奇数。

双边滤波(Bilateral Filtering )

高斯滤波它在滤除图像中噪声信号的同时,也会对图像中的边缘信息进行平滑。 双边滤波则可以缓解这个问题。

原理推荐阅读:https://blog.csdn.net/u013921430/article/details/84532068

使用cv.bilateralFilter()实现双边滤波,参数有:

  • src:源图像
  • dst:目标图像
  • d:每个像素邻域的直径。
  • sigmaColor:颜色空间的标准差。
  • sigmaSpace:坐标空间的标准差。d<=0时,dsigmaSpace成正比。
  • borderType :与均值滤波相同

Python

import sys
import cv2 as cv
import numpy as np

#  Global Variables
DELAY_CAPTION = 1500
DELAY_BLUR = 100
MAX_KERNEL_LENGTH = 31
src = None
dst = None
window_name = 'Smoothing Demo'


def main(argv):
    cv.namedWindow(window_name, cv.WINDOW_AUTOSIZE)
    # Load the source image
    imageName = argv[0] if len(argv) > 0 else 'lena.jpg'
    global src
    src = cv.imread(cv.samples.findFile(imageName))
    if src is None:
        print('Error opening image')
        print('Usage: smoothing.py [image_name -- default ../data/lena.jpg] \n')
        return -1
    if display_caption('Original Image') != 0:
        return 0
    global dst
    dst = np.copy(src)
    if display_dst(DELAY_CAPTION) != 0:
        return 0
    # 均值滤波
    if display_caption('Homogeneous Blur') != 0:
        return 0

    for i in range(1, MAX_KERNEL_LENGTH, 2):
        dst = cv.blur(src, (i, i))
        if display_dst(DELAY_BLUR) != 0:
            return 0

    # 高斯滤波
    if display_caption('Gaussian Blur') != 0:
        return 0

    for i in range(1, MAX_KERNEL_LENGTH, 2):
        dst = cv.GaussianBlur(src, (i, i), 0)
        if display_dst(DELAY_BLUR) != 0:
            return 0

    # 中值滤波
    if display_caption('Median Blur') != 0:
        return 0

    for i in range(1, MAX_KERNEL_LENGTH, 2):
        dst = cv.medianBlur(src, i)
        if display_dst(DELAY_BLUR) != 0:
            return 0

    # 双边滤波
    if display_caption('Bilateral Blur') != 0:
        return 0

    for i in range(1, MAX_KERNEL_LENGTH, 2):
        dst = cv.bilateralFilter(src, i, i * 2, i / 2)
        if display_dst(DELAY_BLUR) != 0:
            return 0

    #  Done
    display_caption('Done!')
    return 0


def display_caption(caption):
    global dst
    dst = np.zeros(src.shape, src.dtype)
    rows, cols, _ch = src.shape
    cv.putText(dst, caption,
               (int(cols / 4), int(rows / 2)),
               cv.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255))
    return display_dst(DELAY_CAPTION)


def display_dst(delay):
    cv.imshow(window_name, dst)
    c = cv.waitKey(delay)
    if c >= 0: return -1
    return 0


if __name__ == "__main__":
    main(sys.argv[1:])

C++

#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace std;
using namespace cv;
int DELAY_CAPTION = 1500;
int DELAY_BLUR = 100;
int MAX_KERNEL_LENGTH = 31;
Mat src; Mat dst;
char window_name[] = "Smoothing Demo";
int display_caption( const char* caption );
int display_dst( int delay );
int main( int argc, char ** argv )
{
    namedWindow( window_name, WINDOW_AUTOSIZE );
    const char* filename = argc >=2 ? argv[1] : "lena.jpg";
    src = imread( samples::findFile( filename ), IMREAD_COLOR );
    if (src.empty())
    {
        printf(" Error opening image\n");
        printf(" Usage:\n %s [image_name-- default lena.jpg] \n", argv[0]);
        return EXIT_FAILURE;
    }
    if( display_caption( "Original Image" ) != 0 )
    {
        return 0;
    }
    dst = src.clone();
    if( display_dst( DELAY_CAPTION ) != 0 )
    {
        return 0;
    }
    if( display_caption( "Homogeneous Blur" ) != 0 )
    {
        return 0;
    }
    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
    {
        blur( src, dst, Size( i, i ), Point(-1,-1) );
        if( display_dst( DELAY_BLUR ) != 0 )
        {
            return 0;
        }
    }
    if( display_caption( "Gaussian Blur" ) != 0 )
    {
        return 0;
    }
    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
    {
        GaussianBlur( src, dst, Size( i, i ), 0, 0 );
        if( display_dst( DELAY_BLUR ) != 0 )
        {
            return 0;
        }
    }
    if( display_caption( "Median Blur" ) != 0 )
    {
        return 0;
    }
    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
    {
        medianBlur ( src, dst, i );
        if( display_dst( DELAY_BLUR ) != 0 )
        {
            return 0;
        }
    }
    if( display_caption( "Bilateral Blur" ) != 0 )
    {
        return 0;
    }
    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
    {
        bilateralFilter ( src, dst, i, i*2, i/2 );
        if( display_dst( DELAY_BLUR ) != 0 )
        {
            return 0;
        }
    }
    display_caption( "Done!" );
    return 0;
}
int display_caption( const char* caption )
{
    dst = Mat::zeros( src.size(), src.type() );
    putText( dst, caption,
             Point( src.cols/4, src.rows/2),
             FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );
    return display_dst(DELAY_CAPTION);
}
int display_dst( int delay )
{
    imshow( window_name, dst );
    int c = waitKey ( delay );
    if( c >= 0 ) { return -1; }
    return 0;
}

原始图像:

均值滤波(核大小递增:1,3,5,…31):

在这里插入图片描述

高斯滤波

在这里插入图片描述

中值滤波

在这里插入图片描述

双边滤波
在这里插入图片描述

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

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

相关文章

2024 年 5 个 Linux 开源数字化学习平台

与其他行业一样&#xff0c;教育界多年来一直在经历数字化转型的过程。随着数字化学习平台的建立&#xff0c;目前只要能上网&#xff0c;任何人都可以接受教育。 “e-learning”一词的意思是“数字化学习”&#xff0c;是当今最常用的词之一。 它指的是通常在互联网上进行的培…

unity Mirror网络同步

我们直接来剖析&#xff0c;上干货 在github上的主页代码&#xff0c;稍微修改了下&#xff1a; using System.Collections; using System.Collections.Generic; using Mirror; using UnityEngine;public class Player : NetworkBehaviour {// Synced automatically //自动同…

0201线性方程组和矩阵-矩阵及其运算-线性代数

文章目录 一、线性方程组二、矩阵的定义结语 一、线性方程组 设有 n 个未知数 m n个未知数m n个未知数m个方程的线性方程组 { a 11 x 1 a 12 x 2 ⋯ a 1 n x n b 1 , a 21 x 1 a 22 x 2 ⋯ a 2 n x n b 2 , ⋯ a m 1 x 1 a m 2 x 2 ⋯ a m n x n b m , \begin{ca…

[AutoSar]BSW_Com017 COM模块介绍(一)

目录 关键词平台说明一、COM 所处架构位置二、COM 的功能概述三、Functional Specification3.1 AUTOSAR COM basis function3.2 Signal Gateway3.2.1 Signal routing requirements3.2.2 Routing of signal groups3.2.3 Routing latency for normal Signal Gateway3.2.4 Gateway…

Nacos介绍和Eureka的区别

Nacos&#xff08;全称为 Alibaba Cloud Nacos&#xff0c;或简称为 Nacos&#xff09;是一个开源的分布式服务发现和配置管理系统。它由阿里巴巴集团开发并开源&#xff0c;旨在帮助开发人员简化微服务架构下的服务注册、发现和配置管理。 1、Nacos 提供了以下主要功能&#…

Django在日志中使用AdminEmailHandler发送邮件(同步),及celery异步发送日志邮件的实现

目录 一、使用AdminEmailHandler实现发送日志通知邮件 1&#xff0c;配置日志项 2&#xff0c;配置邮件项 3&#xff0c;在视图里使用日志 二、继承AdminEmailHandler使用celery实现异步发送邮件 1&#xff0c;安装配置celery 2&#xff0c;继承AdminEmailHandler类&…

V2X技术与智能传感器的完美融合:提升城市道路安全

在科技不断创新的今天&#xff0c;城市交通领域涌现了大量新技术。有时候我们不仅仅需要独立应用这些新技术来实现交通的变革&#xff0c;更需要将它们巧妙地结合连接起来&#xff0c;以获取更高效更安全的交通环境。本文将探讨V2X技术与智能传感器的结合&#xff0c;如何在城市…

uni-app打包证书android

Android平台打包发布apk应用&#xff0c;需要使用数字证书&#xff08;.keystore文件&#xff09;进行签名&#xff0c;用于表明开发者身份。 Android证书的生成是自助和免费的&#xff0c;不需要审批或付费。 可以使用JRE环境中的keytool命令生成。 以下是windows平台生成证…

1升级powershell后才能安装WSL2--最后安装linux--Ubuntu 22.04.3 LTS

视频 https://www.bilibili.com/video/BV1uH4y1W7UX特殊开启–Hyper-V虚拟机 把一下代码保存到【a.bat】的执行文件中&#xff0c;进行Hyper-V虚拟机的安装开启【Windows 批处理文件 (.bat)】 pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mu…

elasticsearch的数据搜索

DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括: 查询所有:查询出所有数据,一般测试用。例如:match_all 全文检索(full text)查询:利用分词器对用户…

鸿蒙Harmony应用开发—ArkTS(@Styles装饰器:定义组件重用样式)

如果每个组件的样式都需要单独设置&#xff0c;在开发过程中会出现大量代码在进行重复样式设置&#xff0c;虽然可以复制粘贴&#xff0c;但为了代码简洁性和后续方便维护&#xff0c;我们推出了可以提炼公共样式进行复用的装饰器Styles。 Styles装饰器可以将多条样式设置提炼…

学点儿Java_Day9_String、包装类

1 String 详解“”和equals的区别 Testpublic void test1() {//"abc"双引号括起来的字符串&#xff1a;字符串常量&#xff0c;它也是一个对象// 1.8之后常量池放到堆&#xff0c;在常量池里面找有没有这个"abc"对象&#xff0c;// 如果常量池里面没有这…

是德科技keysight N1912A双通道功率计

181/2461/8938产品概述&#xff1a; Keysight(原Agilent) N1912A P系列双通道功率计可提供峰值、峰均比、平均功率、上升时间、下降时间、最大功率值、最小功率值以及宽带信号的统计数据。 Keysight(原Agilent) N1912A P系列双通道功率计, 可提供峰值、峰均比、平均功率、上升…

nodejs各版本下载

https://registry.npmmirror.com/binary.html 然后进入nodejs各个版本&#xff0c;然后按需选择

JAVA 栈和队列总结

除了最底层下面三个是实现类&#xff0c;其他都是接口。 双端队列&#xff08;队头队尾都可以插入和删除元素&#xff09;的方法&#xff1a; 普通队列方法&#xff1a; 常用的是add(),poll(), element() 我们用Deque(双端队列)实现栈 Deque当栈用的时候的方法。 deque.push…

百度小程序入口在哪里找到怎么打开百度词令关键词口令直达小程序?

百度小程序入口在哪里找到怎么打开百度词令关键词口令直达小程序&#xff1f; 一、百度搜索找到百度词令小程序 打开手机百度搜索「词令」即可找到百度词令关键词口令直达小程序&#xff1b; 二、百度小程序中心找到百度小程序 2.1、打开手机百度&#xff0c;点击底部我的&a…

解决用POI库生成的word文件中的表格在python-docx无法解析的问题

问题背景 用apache-poi生成word文件中表格&#xff0c;在使用python-docx库解析时报错&#xff1a; 问题分析 1. word文档本质上是一个rar压缩包&#xff0c;用winrar解析后如下&#xff1a; 2. 查看document.xml&#xff0c;可以看到table元素下面是没有<w:tblGrid>这…

Carla 自动驾驶挑战赛 搭建环境

1. 系统设置 1.1 下载CARLA排行榜包 下载打包的CARLA 排行榜版本。 将包解压到一个文件夹中&#xff0c;例如 CARLA。 在以下命令中&#xff0c;更改${CARLA_ROOT}变量以对应于您的 CARLA 根文件夹。 为了使用 CARLA Python API&#xff0c;您需要在您喜欢的环境中安装一些…

ARM-Linux 开发板下安装编译 OpenCV 和 Dlib

安装 OpenCV 和 Dlib 不像在 x86 平台下那样简单&#xff0c;用一句命令就可以自动安装完。而在 ARM 平台中许多软件都需要自行下载编译&#xff0c;且还有许多问题&#xff0c;本篇文章就是记录在 ARM 平台下载 OpenCV 踩过的坑。 硬件环境&#xff1a; RK3568 Ubuntu20.04…

一文读懂I2C协议

一.硬件连接 I2C必须使用开漏&#xff08;或集电极开路&#xff09;的引脚&#xff0c;其引脚框图如下所示。 SCL0对应78K0的P6.0引脚&#xff0c;SDA0对应78K0的P6.1引脚。 在使用开漏引脚通信时&#xff0c;需注意如下事项&#xff1a; 1&#xff09;两条总线须外接…