NV12转化为RGB

计算机视觉-图像缩放算法-cuda实现 最近邻点插值法 针对目标图中每一个像素点,按照缩放比例去原图中找对应的点,比值不为整数的就选目标图中最近的点。然后给目标图取对应的值。 双线性插值法 找到原图的4个点,然后再求出目标图的像素值。 使用CUDA在GPU中进行计算,然后再返回给CPU端。 阅读详情





/*
    NV12ToARGB color space conversion CUDA kernel


    This sample uses CUDA to perform a simple NV12 (YUV 4:2:0 planar)
    source and converts to output in ARGB format
*/




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cudaProcessFrame.h"


__constant__ uint32 constAlpha;


#define MUL(x,y)    (x*y)
__constant__ float  constHueColorSpaceMat[9];




__device__ void YUV2RGB(uint32 *yuvi, float *red, float *green, float *blue)
{
    float luma, chromaCb, chromaCr;


    // Prepare for hue adjustment
    luma     = (float)yuvi[0];
    chromaCb = (float)((int32)yuvi[1] - 512.0f);
    chromaCr = (float)((int32)yuvi[2] - 512.0f);


    // Convert YUV To RGB with hue adjustment
    *red  = MUL(luma,     constHueColorSpaceMat[0]) +
            MUL(chromaCb, constHueColorSpaceMat[1]) +
            MUL(chromaCr, constHueColorSpaceMat[2]);
    *green= MUL(luma,     constHueColorSpaceMat[3]) +
            MUL(chromaCb, constHueColorSpaceMat[4]) +
            MUL(chromaCr, constHueColorSpaceMat[5]);
    *blue = MUL(luma,     constHueColorSpaceMat[6]) +
            MUL(chromaCb, constHueColorSpaceMat[7]) +
            MUL(chromaCr, constHueColorSpaceMat[8]);
}




__device__ uint32 RGBAPACK_8bit(float red, float green, float blue, uint32 alpha)
{
    uint32 ARGBpixel = 0;


    // Clamp final 10 bit results
    red   = min(max(red,   0.0f), 255.0f);
    green = min(max(green, 0.0f), 255.0f);
    blue  = min(max(blue,  0.0f), 255.0f);


    // Convert to 8 bit unsigned integers per color component
    ARGBpixel = (((uint32)blue) |
                 (((uint32)green) << 8)  |
                 (((uint32)red) << 16) | (uint32)alpha);


    return  ARGBpixel;
}


__device__ uint32 RGBAPACK_10bit(float red, float green, float blue, uint32 alpha)
{
    uint32 ARGBpixel = 0;


    // Clamp final 10 bit results
    red   = min(max(red,   0.0f), 1023.f);
    green = min(max(green, 0.0f), 1023.f);
    blue  = min(max(blue,  0.0f), 1023.f);


    // Convert to 8 bit unsigned integers per color component
    ARGBpixel = (((uint32)blue  >> 2) |
                 (((uint32)green >> 2) << 8)  |
                 (((uint32)red   >> 2) << 16) | (uint32)alpha);


    return  ARGBpixel;
}




// CUDA kernel for outputing the final ARGB output from NV12;
extern "C"
__global__ void Passthru_drvapi(uint32 *srcImage,   size_t nSourcePitch,
                                uint32 *dstImage,   size_t nDestPitch,
                                uint32 width,       uint32 height)
{
    int32 x, y;
    uint32 yuv101010Pel[2];
    uint32 processingPitch = ((width) + 63) & ~63;
    uint32 dstImagePitch   = nDestPitch >> 2;
    uint8 *srcImageU8     = (uint8 *)srcImage;


    processingPitch = nSourcePitch;


    // Pad borders with duplicate pixels, and we multiply by 2 because we process 2 pixels per thread
    x = blockIdx.x * (blockDim.x << 1) + (threadIdx.x << 1);
    y = blockIdx.y *  blockDim.y       +  threadIdx.y;


    if (x >= width)
        return; //x = width - 1;


    if (y >= height)
        return; // y = height - 1;


    // Read 2 Luma components at a time, so we don't waste processing since CbCr are decimated this way.
    // if we move to texture we could read 4 luminance values
    yuv101010Pel[0] = (srcImageU8[y * processingPitch + x    ]);
    yuv101010Pel[1] = (srcImageU8[y * processingPitch + x + 1]);


    // this steps performs the color conversion
    float luma[2];


    luma[0]   = (yuv101010Pel[0]        & 0x00FF);
    luma[1]   = (yuv101010Pel[1]        & 0x00FF);


    // Clamp the results to RGBA
    dstImage[y * dstImagePitch + x     ] = RGBAPACK_8bit(luma[0], luma[0], luma[0], constAlpha);
    dstImage[y * dstImagePitch + x + 1 ] = RGBAPACK_8bit(luma[1], luma[1], luma[1], constAlpha);
}




// CUDA kernel for outputing the final ARGB output from NV12;
extern "C"
__global__ void NV12ToARGB_drvapi(uint32 *srcImage,     size_t nSourcePitch,
                                  uint32 *dstImage,     size_t nDestPitch,
                                  uint32 width,         uint32 height)
{
    int32 x, y;
    uint32 yuv101010Pel[2];
    uint32 processingPitch = ((width) + 63) & ~63;
    uint32 dstImagePitch   = nDestPitch >> 2;
    uint8 *srcImageU8     = (uint8 *)srcImage;


    processingPitch = nSourcePitch;


    // Pad borders with duplicate pixels, and we multiply by 2 because we process 2 pixels per thread
    x = blockIdx.x * (blockDim.x << 1) + (threadIdx.x << 1);
    y = blockIdx.y *  blockDim.y       +  threadIdx.y;


    if (x >= width)
        return; //x = width - 1;


    if (y >= height)
        return; // y = height - 1;


    // Read 2 Luma components at a time, so we don't waste processing since CbCr are decimated this way.
    // if we move to texture we could read 4 luminance values
    yuv101010Pel[0] = (srcImageU8[y * processingPitch + x    ]) << 2;
    yuv101010Pel[1] = (srcImageU8[y * processingPitch + x + 1]) << 2;


    uint32 chromaOffset    = processingPitch * height;
    int32 y_chroma = y >> 1;


    if (y & 1)  // odd scanline ?
    {
        uint32 chromaCb;
        uint32 chromaCr;


        chromaCb = srcImageU8[chromaOffset + y_chroma * processingPitch + x    ];
        chromaCr = srcImageU8[chromaOffset + y_chroma * processingPitch + x + 1];


        if (y_chroma < ((height >> 1) - 1)) // interpolate chroma vertically
        {
            chromaCb = (chromaCb + srcImageU8[chromaOffset + (y_chroma + 1) * processingPitch + x    ] + 1) >> 1;
            chromaCr = (chromaCr + srcImageU8[chromaOffset + (y_chroma + 1) * processingPitch + x + 1] + 1) >> 1;
        }


        yuv101010Pel[0] |= (chromaCb << (COLOR_COMPONENT_BIT_SIZE       + 2));
        yuv101010Pel[0] |= (chromaCr << ((COLOR_COMPONENT_BIT_SIZE << 1) + 2));


        yuv101010Pel[1] |= (chromaCb << (COLOR_COMPONENT_BIT_SIZE       + 2));
        yuv101010Pel[1] |= (chromaCr << ((COLOR_COMPONENT_BIT_SIZE << 1) + 2));
    }
    else
    {
        yuv101010Pel[0] |= ((uint32)srcImageU8[chromaOffset + y_chroma * processingPitch + x    ] << (COLOR_COMPONENT_BIT_SIZE       + 2));
        yuv101010Pel[0] |= ((uint32)srcImageU8[chromaOffset + y_chroma * processingPitch + x + 1] << ((COLOR_COMPONENT_BIT_SIZE << 1) + 2));


        yuv101010Pel[1] |= ((uint32)srcImageU8[chromaOffset + y_chroma * processingPitch + x    ] << (COLOR_COMPONENT_BIT_SIZE       + 2));
        yuv101010Pel[1] |= ((uint32)srcImageU8[chromaOffset + y_chroma * processingPitch + x + 1] << ((COLOR_COMPONENT_BIT_SIZE << 1) + 2));
    }


    // this steps performs the color conversion
    uint32 yuvi[6];
    float red[2], green[2], blue[2];


    yuvi[0] = (yuv101010Pel[0] &   COLOR_COMPONENT_MASK);
    yuvi[1] = ((yuv101010Pel[0] >>  COLOR_COMPONENT_BIT_SIZE)       & COLOR_COMPONENT_MASK);
    yuvi[2] = ((yuv101010Pel[0] >> (COLOR_COMPONENT_BIT_SIZE << 1)) & COLOR_COMPONENT_MASK);


    yuvi[3] = (yuv101010Pel[1] &   COLOR_COMPONENT_MASK);
    yuvi[4] = ((yuv101010Pel[1] >>  COLOR_COMPONENT_BIT_SIZE)       & COLOR_COMPONENT_MASK);
    yuvi[5] = ((yuv101010Pel[1] >> (COLOR_COMPONENT_BIT_SIZE << 1)) & COLOR_COMPONENT_MASK);


    // YUV to RGB Transformation conversion
    YUV2RGB(&yuvi[0], &red[0], &green[0], &blue[0]);
    YUV2RGB(&yuvi[3], &red[1], &green[1], &blue[1]);


    // Clamp the results to RGBA
    dstImage[y * dstImagePitch + x     ] = RGBAPACK_10bit(red[0], green[0], blue[0], constAlpha);
    dstImage[y * dstImagePitch + x + 1 ] = RGBAPACK_10bit(red[1], green[1], blue[1], constAlpha);
}





CUDA YV12/NV12 转换成 RGB24 一、YV12格式说明 二、NV12格式说明 三、YUV420格式一览 四、 NV12转RGB24kernel函数实现 /* * pYdata:Y分量数据起始地址 * pUVdata:UV分量数据起始地址 * stepY:Y分量一行的宽度,等于图像一行的像素点数 * stepUV:UV分量一行的宽度,等于图像一行的像素点数 * pImgData:输出的RGB数据 * channels:rgb共3个channel,所以这个参数是3 */ __global__ voi.. 阅读详情

相关推荐

关于RV1126开发板 摄像头数据在qt显示

rv1126开发板获取摄像头图像在qt显示

qq_37797583的博客 2028

nv12图像转RGB888的几种公式

NV12 是一种 YUV420 格式,常用于视频编码和处理。在 NV12 格式中,像素数据按照特定的排列方式进行存储。具体来说,NV12 格式将亮度(Y)分量存储在一个平面中,而色度(UV)分量交错存储在另一个平面中。下面是 NV12 图像排列的简要说明和示意图:亮度平面(Y plane):亮度数据以连续的方式存储在一个平面中,每个像素对应一个亮度值。色度平面(UV plane):色度数据以交错的方式存储在另一个平面中。对于每个 2x2 的亮度块,只有一个色度块(包含两个色度值)与之对应。

weixin_42549534的博客 2425

用NEON intrinsic实现RGB转YUV420SP(NV12)

如题,现在要把RGB图像的数据转成YUV数据。 1. 数据的排列方式   先来看看两种数据在内存里是按什么方式排列的 1.1 RGB的排列   如图所示,1组RGB表示1个像素的颜色,每个像素依次排列。图中有8组RGB数据,即8个像素点。 1.2 YUV的排列   如图所示,这里是 YUV420SP(NV12) 的排列方式,YUV的比例为Y:U:V=4:1:1。Y代表像素点的明亮度(灰阶),图中有48个Y,即48个像素点。UV代表像素点的色度,1个U和1个V组合到一起能表示一种颜色,在YUV420

Yemiekai的博客 4853

nv12转rgb

YUV格式详解_走出去拍拍照的博客-优快云博客_yuv

wjhtu_csdn的博客 1733

OpenGL Shader编程:NV12 转 RGB

OpenGL Shader编程:NV12 转 RGB最近在学习FFmpeg调用Nvidia硬件编解码,其中在解码这里计划做一个多路硬件解码加显示。由于使用了显卡来干活那么CPU注定是个酱油角色,初步规划CPU只完成解码后的scale工作。据我观察老黄的显卡里面有个视频引擎应该是个独立的部分只负责处理编解码,视频引擎之外的计算能力当然不能浪费,格式转换准备拿到GPU中完成。

WuNL的博客 6345

convert 8bit/10bit RGB444,YUV444,NV12,NV21 to PNG

convert 8bit/10bit RGB444,YUV444,NV12,NV21 to PNG 下面的代码写的粗糙(汗~),将就着看,仅做参考。。。 def yuv2bgr(filename,height,width,bit_depth,format_,output_name): path=os.path.dirname(filename) base=os.path.ba...

honk2012的博客 2850

使用妙算开发M100----NV12转化为RGB图像方法

cv::cvtColor(buffer,srcImg,CV_YUV2RGB_NV12)版本:OPENCV 3.4.10

leo-wkd的博客 1399

Unity 工具之 YUV(YUV420 :I420,YV12,NV12,NV21)使用 shader 转为 RGB 显示 封装 YUV420ToRGBWrapper

Unity 工具之 YUV(YUV420 :I420,YV12,NV12,NV21)使用 shader 转为 RGB 显示 封装 YUV420ToRGBWrapper 目录 Unity 工具之 YUV(YUV420 :I420,YV12,NV12,NV21)使用 shader 转为 RGB 显示 封装 YUV420ToRGBWrapper 一、简单介绍 二、YUV相关知识 1、...

仙魁XAN 3055

C语言通过libjpeg-turbo将NV12转为jpeg

OpenHarmony5.0.0的环境中需要将底层生成的NV12格式照片转化为jpeg并保存。搜了一下相关的文章,发现没有合适的源码可以拿来用,于是尝试了“文心一言”竟然是可以的。稍作调试即可使用。

qqq1112345的博客 803

raw/rgb/yuv/nv21图像格式总结

1、RAW raw格式sensor的输出格式,是sensor将光信号转换为电信号时的电平高低的原始记录,没有经过处理的原始数据 raw数据在输出的时候使用一定的顺序的,主要有四种: GRBG, RGGB, BGGR, GBRG raw数据主要有3中常见的格式: raw8, raw10, raw12 2、RGB rgb格式:即每一个像素由三原色R、G、B蓝色组成 RGB565 每个像素用16位表示,RGB分量分别使用5位、6位、5位 RGB555 每个像素用16位表示,RGB分量分别使用5位、5位、5位(剩

zzsxyl的博客 7932

基于libyuv库的NV12格式图片的缩放

使用libyuv库在Linux下对NV12格式进行缩放

Flypei的博客 1万+

iTOP-i.MX8MM开发板Yocto系统使用Gstarwmra视频颜色空间转换

将 gstreamer 自带的 NV12 格式的视频源转换为 RGB16 格式的视频,输入以下命令:将 h264 视频解码后,再使用 imxvideoconvert_g2d 转换成 RGB16 格式的视频,输入以下命令:qtdemux!queue \!h264parse!vpudec!

mucheni的博客 177

rgb 和 yuv_nv12 数据相互转换

rgb转换为nv12格式,并保存为raw。 nv12转换为rgb格式,并保存为bmp。

Opengl中NV12和YUV420p的fragment Shader(Android平台)

项目中在android平台上,需要对nv12的yuv数据支持,其实在cpu中利用libyuv可以很快速的转换,但是为了性能,能直接从渲染器中支持是再好不过了。 Fragment Shader的代码 texture2D()函数生成的对象有rgba四个成员变量,在yuv中,rgb是一样的(猜的,因为别人的shader用的r,我这个用的是g),这里需要非常注意的是,在代码中glTexImage2D函数,就是创建texture的函数中,nv12因为是uv放在一起的,所以它的类型应该是GL_LUMINANCE_.

Niap的博客 908

uniapp 开发微信小程序请求问题 , 真机调试正常,开发工具正常,但是使用扫码预览接口都是不通的,发布到体验版也是请求失败

uniapp开发小程序体验版接口请求失败(真机可以)

weixin_60408555的博客 3953

Excel地理探测器实战:5分钟搞定空间分异性分析(附完整数据集)

本文详细介绍了如何使用Excel地理探测器插件进行空间分异性分析。通过5分钟实战教程,手把手指导数据格式准备、软件操作及四大探测器(分异及因子、交互作用、风险区、生态探测器)的结果解读,帮助规划师、研究者快速验证地理因素对现象分布的影响,大幅降低GIS分析门槛。

peace的博客 607

RGB、YUV、NV21、BMP相互转换

概述 最近学习雷神的博客,深受启发。后面的代码或者借鉴原作的代码,或者修改自原作。一般的图片播放器无法显示rgb和yuv格式的图片,为了方便查看rgb和yuv图片,雷神修改了一个网上的YUV/RGB播放器,既支持YUV又支持RGB的播放器。不过要求图片名字类似于test_320x420.yuv,320x420是图片的宽和高。 rgb24转yuv420p 首先要了解rgb24和yuv420p的存储方...

Z_baobao的博客 2691

ROS2节点通信实战:用C++手写一个‘智能小车’控制模型(附完整代码)

本文详细介绍了如何使用ROS2和C++构建一个智能小车控制模型,涵盖运动控制节点、电池管理服务、参数动态配置和Rviz可视化等核心功能。通过实战项目演示ROS2节点通信机制,帮助开发者快速掌握机器人开发的关键技术,并提供了完整的代码实现和系统集成方案。

weixin_30607029的博客 259

NV12转RGB24算法

#include <QtCore/QCoreApplication> #include <QFile> #include <QDebug> #include <QApplication> #include <QImage> #include <QLabel> #include <QPixmap> #include...

jueying6449的博客 3679

SAP CPI 之使用国密算法实现SM系列算法加解密

System.out.println("SM2-私钥:" + privateKey);System.out.println("SM2-公钥:" + publicKey);System.out.println("SM2-密文:" + encrypts);System.out.println("SM2-明文:" + data2);新建groovy,通过import之后,调用jar包中的方法。在CP中导入jar包,选择Upload,选中导入的jar包。的密钥和向量值,不安全!的公钥和私钥,不安全!

u012830826的博客 1333

芯片测试:WAT、CP、FT

最近部门来了一个日本回来的同事,虽然他尽量用非常Poor的中文给我解释一些东西,其中还夹杂着一些英文让我很受挫,于是最近来学一下WAT中的常用的单词含义。直接去查缩写、查单词很难去记住,要把具体的东西放在具体的场景,引发知识的连接才会在脑子里留下一定的映像。感兴趣的一起来学习一下这篇不错的文章吧。注释是我查询记录,如有不妥,欢迎指出修正。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 5079

图像基础:读取BMP图片,转换为RGB与YU12(YUV420P)格式,同时YU12、NV12、NV21之间相互转换

BMP转RGB //输入:1、申请的RGB内存 // 2、打开的BMP文件 void ReadBmp(unsigned char *RGB, FILE *fp) { int i, j; unsigned char temp; //int fseek(FILE *stream, long offset, int fromwhere); //指向以fromwhere为基准,偏移offs...

weixin_43455834的博客 1687

科研必备:15款顶尖AI科研工具全面分析汇总(持续更新ing)

科研必备:15款AI科研工具全面分析汇总(持续更新ing)

Code_流苏:在代码中寻诗意,在实践中觅真知 9629

yuv数据(nv12和nv21)和RGB数据之间转换的c++代码

yuv数据(以nv21和nv12为例)和RGB数据之间转换代码(c++)

weixin_42450976的博客 6469

3 路由引入

在大型企业网络中,网络规模十分庞大,选用单一的路由协议无法满足网络的需求,因此多种路由协议共存的情况十分常见。或者出于业务逻辑或行政管理的考虑,会在不同的网络结构中设计和部署不同的路由协议,使路由的层次结构更加清晰可控。路由引入是具有方向性的,将路由信息从路由协议A引入到路由协议B(A-to-B),则路由协议B可获知A中的路由信息,但是此时,A还并不知晓B路由协议中的路由信息,除非配置B-to-A的路由引入。表3-1:各种路由协议的优先级。通过路由引入,可以实现路由信息在不同路由协议间传递。

lwljh134的博客 621

RT-DETR改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进

1️⃣本专栏已更新260多种不同的改进方法,所使用并改进的每一个模块均包含详细的模块分析、原理讲解、个人总结、多种改进方式以及完整的修改流程,所有改进100%可直接运行。2️⃣所有改进点均为近三年顶会,顶刊提出的先进算法,将其融入到中,紧跟学术热点,适应不同的任务场景。3️⃣团队内发表数篇SCI论文,熟悉完整的发表流程,订阅专栏即可进群享受模型训练、模型改进、论文写作、投稿选刊,从入门到论文的各种答疑内容。4️⃣专栏内容会持续更新,最近更新时间:2024-12-4。项目介绍在大家购买专栏后,加入学习

Limiiiing的博客 2万+
上一篇: 角点检测
下一篇: extern "C"用法
tkp2014
博客等级 码龄12年 137粉丝 241原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值