引言

在大部分的图像处理程序中,其中必不可少的一步就是对传入的彩图进行灰度处理,将三个通道的RGB图片转化为单通道的Gray图,而对于灰度图进行直方图统计同样是观察检测图像特征的常用方法。在OpenCV中已经有成熟的封装函数进行上述功能的实现,本文主要讲述CUDA实现,加快对大图像的处理速度。

任务要求

输入一张彩色图片,通过CUDA将其转换为灰度图,并对灰度图进行灰度直方图统计。

实现思路

关于彩色图片灰度化原理可参照此博客图像灰度化总结简单来说就是将传入的RGB图中三个通道的像素值分别乘以一定系数即可得到对应像素点灰度值。而在灰度值统计时,由于在CUDA中block内的线程同时并行,故无法采用简单的累加统计,需用到CUDA内自带的原子操作函数atomicAdd()

实现代码

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <cuda.h>
#include <device_functions.h>
#include <opencv2\opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;//输入图像为BGR图,将其转化为gray图
__global__ void rgb2grayInCuda(uchar3 *dataIn, unsigned char *dataOut, int imgHeight, int imgWidth)
{int xIndex = threadIdx.x + blockIdx.x * blockDim.x;int yIndex = threadIdx.y + blockIdx.y * blockDim.y;if (xIndex < imgWidth && yIndex < imgHeight){uchar3 rgb = dataIn[yIndex * imgWidth + xIndex];dataOut[yIndex * imgWidth + xIndex] = 0.299f * rgb.x + 0.587f * rgb.y + 0.114f * rgb.z;}
}//灰度直方图统计
__global__ void imHistInCuda(unsigned char *dataIn, int *hist)
{int threadIndex = threadIdx.x + threadIdx.y * blockDim.x;int blockIndex = blockIdx.x + blockIdx.y * gridDim.x;int index = threadIndex + blockIndex * blockDim.x * blockDim.y;atomicAdd(&hist[dataIn[index]], 1);}int main()
{//传入图片Mat srcImg = imread("out1.bmp");int imgHeight = srcImg.rows;int imgWidth = srcImg.cols;Mat grayImg(imgHeight, imgWidth, CV_8UC1, Scalar(0));//输出灰度图int hist[256];//灰度直方图统计数组memset(hist, 0, 256 * sizeof(int));//在GPU中开辟输入输出空间uchar3 *d_in;unsigned char *d_out;int *d_hist;cudaMalloc((void**)&d_in, imgHeight * imgWidth * sizeof(uchar3));cudaMalloc((void**)&d_out, imgHeight * imgWidth * sizeof(unsigned char));cudaMalloc((void**)&d_hist, 256 * sizeof(int));//将图像数据传入GPU中cudaMemcpy(d_in, srcImg.data, imgHeight * imgWidth * sizeof(uchar3), cudaMemcpyHostToDevice);cudaMemcpy(d_hist, hist, 256 * sizeof(int), cudaMemcpyHostToDevice);dim3 threadsPerBlock(32, 32);dim3 blocksPerGrid((imgWidth + threadsPerBlock.x - 1) / threadsPerBlock.x, (imgHeight + threadsPerBlock.y - 1) / threadsPerBlock.y);//灰度化rgb2grayInCuda << <blocksPerGrid, threadsPerBlock >> >(d_in, d_out, imgHeight, imgWidth);//灰度直方图统计imHistInCuda << <blocksPerGrid, threadsPerBlock >> >(d_out, d_hist);//将数据从GPU传回CPUcudaMemcpy(hist, d_hist, 256 * sizeof(int), cudaMemcpyDeviceToHost);cudaMemcpy(grayImg.data, d_out, imgHeight * imgWidth * sizeof(unsigned char), cudaMemcpyDeviceToHost);cudaFree(d_in);cudaFree(d_out);cudaFree(d_hist);return 0;
}

实现结果

输入图片

输出图片

通过比对发现CUDA输出结果与OpenCV输出结果一致~

CUDA精进之路(三):图像处理——图像灰度化、灰度直方图统计相关推荐

  1. CUDA精进之路(四):图像处理——Sobel算子边缘检测

    引言 关于图像边缘检测,记得刚开始接触图像处理时,第一个自己实现的程序是通过笔记本摄像头采集图像,利用OpenCV自带的算法库进行Canny算子边缘检测,那时候当看到程序运行后,视频窗口实时显示经Ca ...

  2. CUDA精进之路(五):图像处理——OTSU二值算法(最大类间方差法、大津法)

    引言 最近在做医疗设备相关的项目,故在项目中大量用到了各类图像分割的算法,为了在图像中分割出特定目标,用到的算法可以有很多,比如阈值分割,多通道分割,边缘分割以及一些前沿的组合分割.而对大多数图像来说 ...

  3. CUDA精进之路(零):CUDA开篇

    前言 着手机器视觉项目时接触到了并行编程这一概念,那时候的目的是为了在图像识别的时候通过多个线程同时对多张传入的图片进行并行处理以达到加速程序运行速度,运用的方法主要是利用了C++自带的future库 ...

  4. 图像的灰度化灰度值的读取Matlab

    matlab中图像的灰度化: H = imread('test.png'); I = rgb2gray(H); 原图和灰度图: 在matlab工作区选取灰度矩阵I,即可得到图像详细的灰度值矩阵 图片上 ...

  5. CUDA精进之路(一):图像处理——大图像分块处理(包括求均值、最大值)

    引言 在我的第一篇文章中我简单介绍了CUDA以及我的一些个人学习见解,在本文中我将开始正式开始CUDA实践之旅,众做周知CUDA目前应用的领域十分广泛,它能把一些普通的CPU代码提速几十倍甚至几百倍. ...

  6. CUDA精进之路(二):图像处理——形态学滤波(膨胀、腐蚀、开闭运算)

    引言 从这篇文章起,开始将一些较为典型的OpenCV算法通过CUDA进行实现,本文实现的为图像处理中最为常见的形态学腐蚀以及膨胀,由于本文目的在于算法移植后的验证,故在图片的选择上用小图像作为输入的示 ...

  7. 数字识别java开源_Java基于opencv实现图像数字识别(三)—灰度化和二值化

    Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ...

  8. Unity3D Shader系列之UI Image灰度化

    目录 1.灰度化是什么 2.灰度值计算方法 3.灰度化的目的 4.Shader实现 5.参考文章 在<OpenCV for Unity学习笔记(1)--Mat及灰度化图像>我们看到,使用O ...

  9. 车牌识别之预处理(灰度化,去噪,二值化,分割)

    灰度化 灰度即R=G=B 二值化只取255 0 对图片进行灰度化处理,目的是 1 减少数据量 (减少不明显) 2 为二值化准备 对数据进行灰度发现数据量减少并不明显 尤其是 最大 和 平均 灰度法 权 ...

最新文章

  1. STL容器迭代过程中删除元素技巧
  2. Turn off UAC, Windows Firewall, Set time zone
  3. struts2 跳转类型 result type=chain、dispatcher、redirect
  4. VTK:可视化之ChooseTextColor
  5. (7) hibernate之级联cascade和关系维持inverse
  6. mysql replace into 语法_mysql Replace into与Insert update
  7. 腾讯视频客户端导出MP4格式
  8. 风变编程课 囚徒困境 答案_当您对所有这些有用的在线编程课程感到不知所措时,如何摆脱困境...
  9. linux系统怎么装搜狗输入法_Ubuntu系统安装搜狗(sougou for linux)输入法详细教程...
  10. Web报表工具iReport 1.2.2 详解
  11. 小鼠大脑解剖图分区_大鼠解剖图_求助:大鼠#47;小鼠脑部解剖图谱
  12. 鸿蒙石之鉴老猴死了怎么办,智取芭蕉扇那个剧情选分支1过不了怎么办
  13. 传奇GOM引擎授权过期解决方法.
  14. 程序员面试 算法研究 编程艺术 红黑树 机器学习5大系列集锦
  15. [漫画]120430 混血男孩
  16. ae 创建图像等高线 蒙版_「PS软件」工具使用,图层蒙版与橡皮擦的应用分析
  17. macOS根目录上无法写入文件和创建目录的问题
  18. mysql8数据库有值但是查询结果为空_Mysql数据库编码为UTF-8,但查询结果依旧乱码、为空解决办法...
  19. 加密算法之SHA(SHA1、SHA256)
  20. iOS -- 友盟工具进行Crash分析/dsym文件

热门文章

  1. 中科院计算机所网络安全,中科院着力培养网络空间安全人才
  2. 数字后端基本概念介绍<Tap Cell>
  3. 计数显示器c语言程序,51单片机计数显示器Proteus仿真程序
  4. ERROR 1045 (28000): Access denied for user 'backup'@'mysql' (using password: YES)
  5. 使用 IntraWeb (29) - 基本控件之 TIWAutherList、TIWAutherINI、TIWAutherEvent
  6. 一款iPhone App推广中得来的18条经验教训
  7. java输入验证码代码,JavaWeb 实现验证码功能(demo)
  8. Asp.net Web Api 路由 和 异常处理
  9. 职教高中计算机专业知识,新课改背景下计算机专业教学(职教)三维目标设计初探...
  10. git中.ssh文件夹在哪_关于git中的https和ssh,权限等问题