首页 > 其他分享 >【代码实现】opencv 高斯模糊和pytorch 高斯模糊

【代码实现】opencv 高斯模糊和pytorch 高斯模糊

时间:2024-09-30 18:19:44浏览次数:7  
标签:kernel 高斯 image 模糊 padding opencv sigma size

wiki百科

Gaussian Blur,也叫高斯平滑,是在Adobe Photoshop、GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次。

opencv实现

opencv实现高斯滤波有两种方式,

1、是使用自带的cv2.GaussianBlur
2、自己构造高斯kernel ,然后调用cv2.filter2D函数,

方法2这个高斯kernel也可以使用opencv自带的cv2.getGaussianKernel来创建,并通过乘以转置来获得NXN的核。
以下是示例代码。

import cv2
import numpy as np
original_image = np.random.rand(256, 256, 3).astype(np.float32)

# 设置高斯核大小和标准差
sigma = 0.334

# 确定高斯核大小
kernel_size = int(6 * sigma + 1)  # 通常选择为 6*sigma + 1

# 使用 OpenCV 进行高斯模糊,方法1
a = cv2.GaussianBlur(original_image, (0, 0), sigma)

# 使用 OpenCV 进行高斯模糊,方法2
kernel = cv2.getGaussianKernel(kernel_size, sigma)
kernel = kernel * kernel.transpose()

b = cv2.filter2D(original_image, -1, kernel)
print(np.abs(a - b).max())
np.allclose(a, b, atol=1e-3)

pytorch 实现

有可能在构建的网络中需要使用高斯滤波,但是又不想通过opencv实现,也可以在tensor层面对图像进行高斯滤波。也就是使用卷积的方式来实现filter
同样实现方式也有两种,

1、使用 F.conv2d的方式
2、使用nn.Conv2d ,但权重 需要固定

需要先定义高斯核,然后在采用上述两种方式来具体实现

# 定义高斯核
def gaussian_kernel(size, sigma):
    x = torch.arange(size, dtype=torch.float32) - size // 2
    kernel_1d = torch.exp(-0.5 * (x / sigma) ** 2)
    kernel_1d /= kernel_1d.sum()
    kernel_2d = torch.outer(kernel_1d, kernel_1d)
    return kernel_2d.unsqueeze(0).unsqueeze(0)

特别需要注意的是group 要设置为3,RGB通道分别使用高斯核,不然结果会出错。
以下是两种方法的实现。

# 方法1 F.conv2d应用高斯模糊
def apply_gaussian_blur(image, kernel_size, sigma):
    padding = (kernel_size - 1) // 2

    # 使用 ReflectionPad2d 进行填充
    img_torch_pad = F.pad(image, pad=(padding, padding, padding, padding), mode='reflect')

    kernel = gaussian_kernel(kernel_size, sigma)
    kernel = kernel.repeat(3, 1, 1, 1)  # 重复以匹配输入图像的通道数
    kernel = kernel.to(image.device)

    # 使用卷积操作进行高斯模糊
    blurred_image = F.conv2d(img_torch_pad, kernel, padding=0, groups=3)
    return blurred_image
# 方法2 创建带有固定高斯核的Conv2D层
class GaussianBlur(nn.Module):
    def __init__(self, kernel_size, sigma, in_channels=3):
        super(GaussianBlur, self).__init__()
        kernel = gaussian_kernel(kernel_size, sigma)
        kernel = kernel.repeat(in_channels, 1, 1, 1)  # 重复以匹配输入图像的通道数
        self.conv = nn.Conv2d(in_channels, in_channels, kernel_size=kernel_size, padding=0,stride=1,groups=in_channels, bias=False)
        self.padding = (kernel_size-1)//2
        self.conv.weight.data = kernel
    def forward(self, x):
        x = F.pad(x, pad=(self.padding, self.padding, self.padding, self.padding), mode='reflect')
        #x = self.pad(x)
        return self.conv(x)

比较四种方法的差异

# 创建一个形状为 (1, 3, 256, 56) 的随机图像
original_image = np.random.rand(1, 3, 256, 56)
original_image_np = original_image[0].transpose(1, 2, 0)

# 将 NumPy 数组转换为 PyTorch 张量
original_image_tensor = torch.tensor(original_image, dtype=torch.float32)

# 设置高斯核大小和标准差
sigma = 0.334

# 确定高斯核大小
kernel_size = int(6 * sigma + 1)  # 通常选择为 6*sigma + 1


# opencv 方法1
opencv1 = cv2.GaussianBlur(original_image_np, (0, 0), sigma).transpose(2, 0, 1)[np.newaxis, ...] #根据sigma创建kernel,一般是6s +1 
# opencv 方法2
# 使用 OpenCV 进行高斯模糊,方法2
kernel = cv2.getGaussianKernel(kernel_size, sigma)
kernel = kernel * kernel.transpose()
opencv2 = cv2.filter2D(original_image_np, -1, kernel).transpose(2, 0, 1)[np.newaxis, ...]
# torch 方法1
torch1 = apply_gaussian_blur(original_image_tensor, kernel_size, sigma).numpy()
# torch 方法2
blur_layer = GaussianBlur(kernel_size, sigma)
torch2  = blur_layer(original_image_tensor).detach().numpy()

def all_arrays_close(*arrays):
    reference = arrays[0]
    for array in arrays[1:]:
        if not np.allclose(reference, array,rtol=1e-5, atol=1e-8):
            return False
    return True

if all_arrays_close(opencv1, opencv2, torch1, torch2):
    print("All arrays are close to each other.")
else:
    print("Arrays are not close to each other.")

输出
在这里插入图片描述
说明四种方法是等价的。

标签:kernel,高斯,image,模糊,padding,opencv,sigma,size
From: https://blog.csdn.net/weixin_43707042/article/details/142642642

相关文章

  • OpenCV(图像对比度增强)
    目录1.直方图均衡化2.自适应直方图均衡化3.限制对比度自适应直方图均衡化4.线性对比度拉伸5.Gamma校正6.Retinex方法7.多尺度对比度增强8.方法选择与应用场景总结增强图像对比度是图像处理中的一个重要步骤,旨在提高图像中不同亮度区域之间的差异,使细节更加清晰和明显......
  • 加油站智能视频监控预警系统(AI识别烟火打电话抽烟) Python 和 OpenCV 库
    加油站作为存储和销售易燃易爆油品的场所,是重大危险源之一,随着科技的不断发展,智能视频监控预警系统在加油站的安全保障方面发挥着日益关键的作用,尤其是其中基于AI的烟火识别、抽烟识别和打电话识别功能,以及其独特的系统组网方式。加油站重大危险源监测(一)油品的易燃易爆性加油站储......
  • OPENCV判断图像中目标物位置及多目标物聚类
    文章目录在最近的项目中,又碰到一个有意思的问题需要通过图像算法来解决。就是显微拍摄的到的医疗图像中,有时候目标物比较偏,也就是在图像的比较偏的位置,需要通过移动样本,将目标物置于视野正中央,然后再次进行拍摄。就类似于下面的图像:基于这个需求,在图像上就需要使......
  • opencv实战项目二十九:GrabCut分割人像
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、GrabCut介绍:二、opencv实现:三、效果:前言在数字图像处理领域,人像分割是一项极具挑战性的任务,它旨在从复杂背景中准确提取出人物图像。随着技术的不断发展,人像分割技术在许多领域都展......
  • 《OpenCV 计算机视觉》—— Harris角点检测、SIFT特征检测
    文章目录一、Harris角点检测1.基本思想2.检测步骤3.OpenCV实现二、SIFT特征检测1.SIFT特征检测的基本原理2.SIFT特征检测的特点3.OpenCV实现一、Harris角点检测OpenCV中的Harris角点检测是一种基于图像灰度值变化的角点提取算法,它通过计算每个像素点的响应函......
  • 基于OpenCV的实时年龄与性别识别(支持CPU和GPU)
    关于深度实战社区我们是一个深度学习领域的独立工作室。团队成员有:中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等,曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万+粉丝,拥有2篇国家级人工智能发明专利。社区特色:深度实战算法创新获取全部完整项目......
  • PbootCMS上传的缩略图为什么变模糊尺寸还变小了了?
    如果你在使用PbootCMS后台发布内容时,发现上传的缩略图在上传成功后变得模糊且尺寸变小,这通常是由于PbootCMS默认的图片尺寸限制导致的。以下是如何解决这个问题的具体步骤:解决方案打开配置文件打开config目录下的config.php文件。修改缩略图配置在config.php文件中找......
  • 《深度学习》【项目】OpenCV 发票识别 透视变换、轮廓检测解析及案例解析
    目录一、透视变换1、什么是透视变换2、操作步骤    1)选择透视变换的源图像和目标图像    2)确定透视变换所需的关键点    3)计算透视变换的变换矩阵    4)对源图像进行透视变换    5)对变换后的图像进行插值处理二、轮廓检测1、......
  • 03_OpenCV像素操作
    importcv2img=cv2.imread('libaray.JPG',1)(b,g,r)=img[100,100]print(b,g,r)#bgr#10100---110100i=j=0forjinrange(1,500):img[i,j]=(255,255,255)foriinrange(1,500):img[i,j]=(255,255,255)#cv2.imshow('......
  • WFUZZ模糊测试
    WFUZZ模糊测试使用指南选项:-h/--help:这个帮助--help:高级帮助--filter-help:过滤语言规范--version:Wfuzz版本详细信息-e<type>:可用编码器/有效负载/迭代器/打印机/......