结合OpenCV和CUDA扩展自定义函数接口之导向滤波算法实现

本文主要是介绍结合OpenCV和CUDA扩展自定义函数接口之导向滤波算法实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

声明:本文内容原创,首发于CSDN博客。未经许可禁止转载。需要更多帮助请私信或邮件联系。

前言

CUDA(Compute Unified Device Architecture,统一计算架构)是由NVIDIA所推出的一种集成技术,是其对于GPGPU(A General-Purpose Graphics Processing Unit)的正式名称。通过该技术,开发者可以利用NVIDIA的GeForce 8以后的GPU进行计算。极大加速计算型应用的效率。通常用于游戏开发、视频编解码、图像处理等领域。

OpenCV从3.0版后集成了关于CUDA相关操作的高级封装,其中GpuMat数据类型可以看做Mat的GPU版本,有极好的数据属性封装,且能够内部隐式转化成可以直接作为核函数参数的PtrStepSz、PtrStep。
在这里插入图片描述

我们可以很方便使用OpenCV搭建好的框架来扩展实现需要的算法,本文将以导向滤波算法为例,记录使用CUDA使能的OpenCV来实现的GuidedFilter

分析

在使用OpenCV扩展实现算法前,需要了解OpenCV源码的结构。

在OpenCV Doc官网,可以看到OpenCV的模块包含Main modulesExtra modules两大部分,分别放在opencv和opencv_contrib中:
在这里插入图片描述
在这里插入图片描述
对应到GitHub源码,可以很清晰的看出modules的结构:

Main modules部分源码:
在这里插入图片描述
Extra modules部分源码:
在这里插入图片描述
本文主要考虑CUDA加速的导向滤波算法实现,因此以Extra modules部分源码为基准进行扩展。

例如对于cudaimgproc模块,在opencv_contrib/modules/cudaimgproc/路径下的结构如下:
在这里插入图片描述
包括了头文件、实现源文件、测试代码以及CMakeLists.txt,其中CMakeLists.txt定义了该模块下需要编译的模块内容选项,其内容如下:

if(IOS OR WINRT OR (NOT HAVE_CUDA AND NOT BUILD_CUDA_STUBS))ocv_module_disable(cudaimgproc)
endif()set(the_description "CUDA-accelerated Image Processing")ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4100 /wd4324 /wd4512 /wd4515 -Wundef -Wmissing-declarations -Wshadow -Wunused-parameter)ocv_define_module(cudaimgproc opencv_imgproc OPTIONAL opencv_cudev opencv_cudaarithm opencv_cudafilters WRAP python)

而头文件的文件夹"include/opencv2"中只包含了cudaimgproc.hpp一个头文件,其中定义了编译完成后可供外部调用的函数接口,例如CUDA版双边滤波算法接口定义如下:
在这里插入图片描述
关于可供Python调用接口生成部分的内容可以看之前的博客《使用OpenCV自带gen2.py等工具生成C++的Python binding示例》内容。

再看实现源文件的文件夹src,可以看到如下结构:
在这里插入图片描述
还是以双边滤波为例,打开bilateral_filter.cpp文件,可以看到具体的实现内容:
在这里插入图片描述
需要注意的是其调用了cuda文件夹下的bilateral_filter.cu CUDA核函数实现源码。

另外被包含的precomp.hpp头文件中定义了OpenCV在编译这个modules时需要的一些依赖头文件:

#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__#include "opencv2/cudaimgproc.hpp"#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#include "opencv2/core/private.cuda.hpp"#include "opencv2/opencv_modules.hpp"#ifdef HAVE_OPENCV_CUDAARITHM
#  include "opencv2/cudaarithm.hpp"
#endif#ifdef HAVE_OPENCV_CUDAFILTERS
#  include "opencv2/cudafilters.hpp"
#endif#include <limits>
#include <algorithm>#endif /* __OPENCV_PRECOMP_H__ */

关于CUDA版双边滤波的实现源码只在这些文件中出现,在OpenCV编译生成后则可以正常的使用相应的接口“cv::cuda::bilateralFilter()”了。

类似于双边滤波,导向滤波其实也可以类似实现。

实现

要实现基于OpenCV的CUDA版导向滤波算法,需要定义接口、编写头文件以及对类和方法进行实现。

一、接口定义

考虑到导向滤波和双边滤波的相似性,可以选择在cudaimgproc模块中实现相应源码。

先在cudaimgproc模块的头文件"include/opencv2/cudaimgproc.hpp"中定义导向滤波的接口:


// Guided Filter ///
class CV_EXPORTS_W  GuidedFilter  : public Algorithm{public:CV_WRAP virtual void update(InputArray guide, int dDepth = -1, Stream &stream = Stream::Null()) = 0;CV_WRAP virtual void filter(InputArray src, OutputArray dst, int dDepth = -1, Stream &stream = Stream::Null()) = 0;
};CV_EXPORTS_W Ptr<GuidedFilter> createGuidedFilter(Size size, int radius, double eps, int dDepth, int type, int channels = 3);CV_EXPORTS_W void guidedFilter(InputArray guide, InputArray src, OutputArray dst, int radius, double eps, int dDepth = -1, Stream& stream = Stream::Null());

通过定义接口,我们可以使用cv::cuda::guidedFilter(C++)或者createGuidedFilter & update & filter的方式来调用CUDA导向滤波。

在这里插入图片描述

二、头文件实现

在src源码中新建guided_filter.hpp文件,定义相应的导向滤波类和方法:

/*M///
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form

这篇关于结合OpenCV和CUDA扩展自定义函数接口之导向滤波算法实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/922136

相关文章

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

在Linux中改变echo输出颜色的实现方法

《在Linux中改变echo输出颜色的实现方法》在Linux系统的命令行环境下,为了使输出信息更加清晰、突出,便于用户快速识别和区分不同类型的信息,常常需要改变echo命令的输出颜色,所以本文给大家介... 目python录在linux中改变echo输出颜色的方法技术背景实现步骤使用ANSI转义码使用tpu

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

golang版本升级如何实现

《golang版本升级如何实现》:本文主要介绍golang版本升级如何实现问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录golanwww.chinasem.cng版本升级linux上golang版本升级删除golang旧版本安装golang最新版本总结gola

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具