CUDA小白 - NPP(2) -图像处理-算数和逻辑操作(2)

这篇具有很好参考价值的文章主要介绍了CUDA小白 - NPP(2) -图像处理-算数和逻辑操作(2)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

cuda小白
原始API链接 NPP

GPU架构近些年也有不少的变化,具体的可以参考别的博主的介绍,都比较详细。还有一些cuda中的专有名词的含义,可以参考《详解CUDA的Context、Stream、Warp、SM、SP、Kernel、Block、Grid》

常见的NppStatus,可以看这里。

如有问题,请指出,谢谢

Logical Operations

逻辑操作主要就是与、或、异或、右移、左移,非等逻辑操作,同样还是分为两个大类,一个是基于单张图像和常数的,另外一个是基于多张图像的。

AndC

第一大类以AndC为例子,主要是就是比较图像与提供的constant(每个通道一个值)进行与操作之后的结果。

// 有无I的区别在于是否直接对图像进行操作
NppStatus nppiAndC_8u_C3R(const Npp8u *pSrc1,
						  int nSrc1Step,
					      const Npp8u aConstants[3],
					      Npp8u *pDst,
						  int nDstStep,
						  NppiSize oSizeROI);
NppStatus nppiAndC_8u_C3IR(const Npp8u aConstants[3],
						   Npp8u *pSrcDst,
						   int nSrcDstStep,
						   NppiSize oSizeROI);
code
#include <iostream>
#include <cuda_runtime.h>
#include <npp.h>
#include <opencv2/opencv.hpp>

#define PRINT_VALUE(value) {  \
  std::cout << "[GPU] " << #value << " = " << value << std::endl; }

#define CUDA_FREE(ptr) { if (ptr != nullptr) { cudaFree(ptr); ptr = nullptr; } }

int main() {
  std::string directory = "../";
  // =============== load image ===============
  cv::Mat image = cv::Mat(500, 500, CV_8UC3, cv::Scalar(255, 255, 255));
  cv::Rect rc1 = cv::Rect(150, 150, 200, 200);
  cv::Rect rc2 = cv::Rect(200, 200, 200, 200);
  cv::Rect rc3 = cv::Rect(300, 0, 100, 200);
  cv::Rect rc4 = cv::Rect(0, 0, 200, 100);
  cv::Mat(200, 200, CV_8UC3, cv::Scalar(75, 75, 75)).copyTo(image(rc1));
  cv::Mat(200, 200, CV_8UC3, cv::Scalar(100, 100, 100)).copyTo(image(rc2));
  cv::Mat(200, 100, CV_8UC3, cv::Scalar(125, 125, 125)).copyTo(image(rc3));
  cv::Mat(100, 200, CV_8UC3, cv::Scalar(150, 150, 150)).copyTo(image(rc4));
  cv::imwrite(directory + "orin.jpg", image);

  int image_width = image.cols;
  int image_height = image.rows;
  int image_size = image_width * image_height * 3;
  std::cout << "Image info : image_width = " << image_width
            << ", image_height = " << image_height << std::endl;

  // =============== malloc && cpy ===============
  uint8_t *in_ptr;
  cudaMalloc((void**)&in_ptr, image_size * sizeof(uint8_t));
  cudaMemcpy(in_ptr, image.data, image_size, cudaMemcpyHostToDevice);

  uint8_t *out_ptr, *out_ptr1;
  cudaMalloc((void**)&out_ptr, image_size * sizeof(uint8_t));
  cudaMalloc((void**)&out_ptr1, image_size * sizeof(uint8_t));
  
  NppiSize roi1, roi2;
  roi1.width = image_width;
  roi1.height = image_height;
  roi2.width = image_width / 2;
  roi2.height = image_height / 2;

  uint8_t constant[3] = { (uint8_t)100, (uint8_t)100, (uint8_t)100 };

  // nppiAdd_8u_C3RSfs
  cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  cv::Mat out_image1 = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  NppStatus status;
  status = nppiAndC_8u_C3R(in_ptr, image_width * 3, constant, out_ptr, 
                           image_width * 3, roi1);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAndC_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "and.jpg", out_image);

  status = nppiAndC_8u_C3R(in_ptr, image_width * 3, constant, out_ptr1, 
                           image_width * 3, roi2);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAndC_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image1.data, out_ptr1, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "and_roi.jpg", out_image1);

  // free
  CUDA_FREE(in_ptr)
  CUDA_FREE(out_ptr)
  CUDA_FREE(out_ptr1)
}
make
cmake_minimum_required(VERSION 3.20)
project(test)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

find_package(CUDA REQUIRED)
include_directories(${CUDA_INCLUDE_DIRS})
file(GLOB CUDA_LIBS "/usr/local/cuda/lib64/*.so")

add_executable(test test.cpp)
target_link_libraries(test
                      ${OpenCV_LIBS}
                      ${CUDA_LIBS}
)
result

CUDA小白 - NPP(2) -图像处理-算数和逻辑操作(2),c++,CUDA,NPP
注意点:

  1. 该函数是将图像的三个通道分别于Constant的值进行按位与的操作,测试的例子中分别使用了255,75, 100, 125, 150三种像素,与100与之后分别为100,4,4,100,100,4。
  2. 由于roi的存在,可以仅保存roi区域内的结果,也就是说输出的地址其可以仅申请roi的区域的大小。
And

针对两张图的操作,包含与、或、非、异或。

NppStatus nppiAnd_8u_C3R(const Npp8u *pSrc1,
						 int nSrc1Step,
					 	 const Npp8u *pSrc2,
					  	 int nSrc2Step,
					 	 Npp8u *pDst,
						 int nDstStep,
						 NppiSize oSizeROI);
	
NppStatus nppiAnd_8u_C3IR(const Npp8u *pSrc,
						  int nSrcStep,
						  Npp8u *pSrcDst,
						  int nSrcDstStep,
						  NppiSize oSizeROI);
code
#include <iostream>
#include <cuda_runtime.h>
#include <npp.h>
#include <opencv2/opencv.hpp>

#define PRINT_VALUE(value) {  \
  std::cout << "[GPU] " << #value << " = " << value << std::endl; }

#define CUDA_FREE(ptr) { if (ptr != nullptr) { cudaFree(ptr); ptr = nullptr; } }

int main() {
  std::string directory = "../";

  // =============== load image ===============
  cv::Mat image_dog = cv::imread(directory + "dog.png");
  int image_width = image_dog.cols;
  int image_height = image_dog.rows;
  int image_size = image_width * image_height * 3;

  cv::Mat image = cv::Mat(image_height, image_width, CV_8UC3, cv::Scalar(100, 125, 150));
  
  std::cout << "Image info : image_width = " << image_width
            << ", image_height = " << image_height << std::endl;

  // =============== malloc && cpy ===============
  uint8_t *in_ptr, *mask;
  cudaMalloc((void**)&in_ptr, image_size * sizeof(uint8_t));
  cudaMalloc((void**)&mask, image_size * sizeof(uint8_t));
  cudaMemcpy(in_ptr, image_dog.data, image_size, cudaMemcpyHostToDevice);
  cudaMemcpy(mask, image.data, image_size, cudaMemcpyHostToDevice);

  uint8_t *out_ptr, *out_ptr1;
  cudaMalloc((void**)&out_ptr, image_size * sizeof(uint8_t));
  cudaMalloc((void**)&out_ptr1, image_size * sizeof(uint8_t));
  
  NppiSize roi1, roi2;
  roi1.width = image_width;
  roi1.height = image_height;
  roi2.width = image_width / 2;
  roi2.height = image_height / 2;

  // nppiAdd_8u_C3RSfs
  cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  cv::Mat out_image1 = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  NppStatus status;
  status = nppiAnd_8u_C3R(in_ptr, image_width * 3, mask, image_width * 3, out_ptr, 
                          image_width * 3, roi1);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAnd_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "and.jpg", out_image);

  status = nppiAnd_8u_C3R(in_ptr, image_width * 3, mask, image_width * 3, out_ptr1, 
                          image_width * 3, roi2);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAnd_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image1.data, out_ptr1, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "and_roi.jpg", out_image1);

  // free
  CUDA_FREE(in_ptr)
  CUDA_FREE(out_ptr)
  CUDA_FREE(out_ptr1)
}
make
cmake_minimum_required(VERSION 3.20)
project(test)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

find_package(CUDA REQUIRED)
include_directories(${CUDA_INCLUDE_DIRS})
file(GLOB CUDA_LIBS "/usr/local/cuda/lib64/*.so")

add_executable(test test.cpp)
target_link_libraries(test![请添加图片描述](https://img-blog.yssmx.com/ce7447a784744aa88e9818c5b8c7a5e6.png)

                      ${OpenCV_LIBS}
                      ${CUDA_LIBS}
)
result

CUDA小白 - NPP(2) -图像处理-算数和逻辑操作(2),c++,CUDA,NPP

Alpha Composition

主要功能是图像的合成(AlphaComp)以及图像的不透明度调整(AlphaPremulC)。

AlphaCompC

该接口主要完成的两张图像(单通道,三通道,四通道)的合成,主要是操作是根据NppiAlphaOp来完成一定的操作。

NppStatus nppiAlphaCompC_8u_C3R(const Npp8u *pSrc1,
								int nSrc1Step,
								Npp8u nAlpha1,
								const Npp8u *pSrc2,
								int nSrc2Step,
								Npp8u nAlpha2,
								Npp8u *pDst,
								int nDstStep,
								NppiSize oSizeROI,
								NppiAlphaOp eAlphaOp);
AlphaComp

该接口主要完成的两张单通道或者四通道的图像的合成。主要是操作是根据NppiAlphaOp来完成一定的操作。

NppStatus nppiAlphaComp_8u_AC1R(const Npp8u *pSrc1,
								int nSrc1Step,
								const Npp8u *pSrc2,
								int nSrc2Step,
								Npp8u *pDst,
								int nDstStep,
								NppiSize oSizeROI,
								NppiAlphaOp eAlphaOp);

与AlphaCompC的区别在于,AlphaCompC可以指定每个输入图像的比例来完成对应的Operation,而AlphaComp则是没有。文章来源地址https://www.toymoban.com/news/detail-681579.html

到了这里,关于CUDA小白 - NPP(2) -图像处理-算数和逻辑操作(2)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python数字图像处理基础(四)——图像平滑处理、形态学操作、图像梯度

    让有噪音点(图像上显得突兀的像素点)的图像变得更加自然顺眼 1.均值滤波 blur() 根据核的大小(rowcol),每个像素值就等于以此像素为中心的周围rowcol个像素的平均值。 核大一点,显然越平滑、模糊。 result = cv2.blur(img, (15, 15)) 2.方框滤波 boxFilter() normalize=true的时候,效果同

    2024年01月18日
    浏览(77)
  • OpenCV基本图像处理操作(一)——图像基本操作与形态学操作

    图像显示 转hsv图像 颜色表示为三个组成部分:色调(Hue)、饱和度(Saturation)和亮度(Value)。常用于图像处理中,因为它允许调整颜色的感知特性,如色彩和亮度,这些在RGB颜色模型中不那么直观。 HSV模型特别适用于任务如图像分割和对象追踪,因为它可以更好地处理光

    2024年04月22日
    浏览(82)
  • Opencv 图像处理:图像基础操作与灰度转化

    本文已收录于Opencv系列专栏: 深入浅出OpenCV ,专栏旨在详解Python版本的Opencv,为计算机视觉的开发与研究打下坚实基础。免费订阅,持续更新。 1.图像格式 图像压缩比: 通过编码器压缩后的图象数字大小和原图象数字大小的压缩比。 BMP 格式 Windows系统下的 标准位图格式 ,

    2024年02月04日
    浏览(48)
  • python数字图像处理基础(二)——图像基本操作、滑动条、鼠标操作

    import cv2 import numpy as np import matplotlib.pyplot as plt 图像读取 cv2.MREAD_COLOR: 彩色图像 或用1 cv2.IMREAD_GRAYSCALE:灰度图像 或用0 img = cv2.imread(‘cat.jpg’, cv2.IMREAD_GRAYSCALE) 等同于: img = cv2.imread(‘cat.jpg’, 0) 图像的显示,也可以创建多个窗口 cv2.imshow(‘img’, img) 等待时间,毫秒级,0表示

    2024年01月18日
    浏览(59)
  • MATLAB【数字图像处理】 实验一:图像处理基本操作(平移、放大、缩小、旋转、插值)

    1、熟悉并掌握MATLAB工具的使用;  2、实现图像的读取、显示、存储、平移、镜像、放大、缩小及旋转操作; 3、掌握常用的插值方法,并了解其优缺点。 Matlab 2020B 1、读入一幅RGB图像,变换为灰度图像和二值图像,并在同一个窗口内分别显示RGB图像和灰度图像,注上文字标

    2024年02月06日
    浏览(46)
  • OpenCV基本图像处理操作(十)——图像特征harris角点

    角点 角点是图像中的一个特征点,指的是两条边缘交叉的点,这样的点在图像中通常表示一个显著的几角。在计算机视觉和图像处理中,角点是重要的特征,因为它们通常是图像中信息丰富的区域,可以用于图像分析、对象识别、3D建模等多种应用。 角点的识别可以帮助在进

    2024年04月23日
    浏览(58)
  • 【matlab图像处理】图像直方图操作和matlab画图

    中国史之【平王东迁】: 公元前771年,因镐京曾遭地震,残破不堪,又接近戎、狄等外患威胁,周平王遂在郑、秦、晋等诸侯的护卫下,将国都东迁至洛邑,东周历史由此开始。 ——来源:全历史APP 【路漫漫其修远兮,吾将上下而求索】 今天介绍图像的直方图操作以及用

    2024年02月04日
    浏览(42)
  • ENVI中图像处理-基本操作

    熟悉基本的图像处理操作,包括:图像显示、彩色合成、多波段影像叠加、查看头文件、编辑头文件信息、图像裁剪、两个时期影像的对比、关闭文件。 掌握图像处理的基本操作 内容一:打开影像,进行彩色合成:真彩色、标准假彩色、任意假彩色; 1、影像打开 数据:D

    2024年02月08日
    浏览(38)
  • OpenCV图像处理学习十,图像的形态学操作——膨胀腐蚀

    一.形态学操作概念 图像形态学操作是指基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学对图像进行处理。 形态学有四个基本操作:腐蚀、膨胀、开操作、闭操作,膨胀与腐蚀是图像处理中最常用的形态学操作手段。 二.形态学操作-膨胀 跟卷积

    2024年02月05日
    浏览(53)
  • 第一章 基本的图像操作和处理

    这是个PIL的简单例子:读入图片、转灰度图、显示图片(这两张图片显然有点太大了)。 1.1.1转图像格式 将jpg转成png 1.1.2创建缩略图 显然前面的 图片太大 了,我们可以创建缩略图显得小一点 需要注意的是,这个函数只能缩小、不能放大,缩小后就回不去了。 1.1.3复制和粘

    2024年02月14日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包