如何将yuv420p图像数据转换为RGB数据并使用opencv保存为jpg图片

这篇具有很好参考价值的文章主要介绍了如何将yuv420p图像数据转换为RGB数据并使用opencv保存为jpg图片。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

yuv420是用4个byte存储4个Y的信息,用1个Byte存储U的信息,一个Byte存储V的信息,
这4个Y共用这2个U和V ,也就是用6个Byte 存储4个像素信息,也就是一个像素需要12个Bits(6*8/4),也就是12bpp。
注意yuv420p里面的p是指planar,也就是分层存储,先存全部Y的信息,然后是U的信息,最后是V的信息,
或者这样说: 如果把一个图片按yuv420p的格式保存为二进制数据文件,那么把这个文件均分为6份,那么前面的4份是Y,第5份是U,第6份是V。

以下程序的流程是:

1 使用 ffmpeg 先将一张图片保存为 yuv420p的数据文件。
2 使用下面的程序读取此文件,然后将yuv数据转为rgb,最后使用opencv保存为jpg格式的图片。
3 主要是熟悉yuv420p的数据格式,以及熟悉yuv如何转为RGB。
4 最后就是使用opencv将RGB数据保存为图片,注意opencv是需要BGR的数据.

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <string.h>
#include <sys/mman.h>
#include <assert.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;

#define  IMAGE_W 1280
#define  IMAGE_H 720

#define  FILE_NAME "output420.yuv"

int convert_yuv_to_rgb_pixel(int y, int u, int v) {
	unsigned int pixel32 = 0;
	unsigned char *pixel = (unsigned char*) &pixel32;
	int r, g, b;
	r = y + (1.370705 * (v - 128));
	g = y - (0.698001 * (v - 128)) - (0.337633 * (u - 128));
	b = y + (1.732446 * (u - 128));

	if (r > 255)
		r = 255;
	if (g > 255)
		g = 255;
	if (b > 255)
		b = 255;
	if (r < 0)
		r = 0;
	if (g < 0)
		g = 0;
	if (b < 0)
		b = 0;
   //注意opencv是需要BGR的数据
	pixel[0] = b;  // blue
	pixel[1] = g;  // green
	pixel[2] = r;  //red
	return pixel32;
}

int convert_yuv420p_to_rgb888_buffer(unsigned char *yuv, unsigned char *rgb,
		unsigned int width, unsigned int height) {
	unsigned int pixel32;
	unsigned char *ptr = rgb;
	int y0, y1, y2, y3, u, v;
	int i = 0;
	unsigned char *a = yuv + width * height * 0;
	unsigned char *b = yuv + width * height * 1;
	unsigned char *c = yuv + (int) (width * height * 1.25);

	while (i < width * height) {
		i += 4;
		u = *(b++);
		v = *(c++);
		for (int j = 0; j < 4; j++) {
			y0 = *(a++);
			pixel32 = convert_yuv_to_rgb_pixel(y0, u, v);
			*(ptr++) = (pixel32 & 0x000000ff);
			*(ptr++) = (pixel32 & 0x0000ff00) >> 8;
			*(ptr++) = (pixel32 & 0x00ff0000) >> 16;
		}

	}
	return 0;
}

/**
 * 	 yuyv420p to rgb to jpg.
 *   ffmpeg -i in.jpg -pix_fmt yuv420p output420.yuv -y
 *   ffmpeg  -pix_fmts
 *   yuyv420 use 12bits to store 1 pixes.
 *
 */
int main() {
	int ret;
	int fd = open(FILE_NAME, O_RDWR);
	if (ret == -1) {
		perror("open");
		return -1;
	}
	unsigned char yuv[IMAGE_W * IMAGE_H * 3 + 1000];

	ret = read(fd, yuv, IMAGE_W * IMAGE_H * 3 + 1000);
	if (ret == -1) {
		perror("read");
		return -1;
	}

	assert(ret == IMAGE_W * IMAGE_H * 12 / 8);
	char rgb24[IMAGE_W * IMAGE_H * 3];
	convert_yuv420p_to_rgb888_buffer((unsigned char*) yuv,
			(unsigned char*) rgb24,
			IMAGE_W, IMAGE_H);
	Mat image(IMAGE_H, IMAGE_W, CV_8UC3, rgb24);
	imwrite("output.jpg", image);
	cout << "success" << endl;
	return 0;
}

如果有任何问题,欢迎评论。文章来源地址https://www.toymoban.com/news/detail-578163.html

到了这里,关于如何将yuv420p图像数据转换为RGB数据并使用opencv保存为jpg图片的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

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

    nv21 Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y V U V U V U V U nv21 Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y U V U V U V U V 主要就是UV的顺序不同,交互一下UV的位置就可以互换NV12和NV21. 一般手机等移动端的数据流格式都是yuv格式,而神经网络的输入一般都是rgb格式,所以需要进行转换,这里给出c++的代码示例。 cv

    2024年02月11日
    浏览(31)
  • “Python OpenCV 图像格式转换:RGB与BGR互转“——使用OpenCV库进行图像处理的过程中,经常需要进行不同格式之间的转换。其中最为常见的就是R...

    “Python OpenCV 图像格式转换:RGB与BGR互转”——使用OpenCV库进行图像处理的过程中,经常需要进行不同格式之间的转换。其中最为常见的就是RGB和BGR格式之间的转换。本文将详细介绍如何使用opencv-python库将图像从RGB格式转换为BGR格式以及从BGR格式转换为RGB格式。 要实现图像格

    2024年02月12日
    浏览(57)
  • 【音视频原理】图像相关概念 ③ ( RGB 色彩简介 | RGB 排列 | YUV 色彩简介 | YUV 编码好处 )

    RGB 是 计算机 中的 颜色编码方法 , 红 ( R ) / 绿 ( G ) / 蓝 ( B ) 三个颜色通道 可以设置不同的值 , 每个 通道 的 颜色值都可以取值 0 ~ 255 , 这样 三个通道 叠加 , 可以表示出 25 6 3 = 16777216 256 ^3 = 16777216 25 6 3 = 16777216 种颜色值 ; 红 ( R ) / 绿 ( G ) / 蓝 ( B ) 三个颜色通道 都取值 255

    2024年01月20日
    浏览(50)
  • 彩色图像灰度化 (RGB ⇒ Gray )(RGB ⇒ YUV)(Verilog)

    简介:         把一个彩色图像,也称为 RGB(红,绿,蓝)图像转化为灰度图像的行为称为彩色图像灰度化处理。也就是由原来的三个通道 RGB 转化为一个通道 YCrCb(从三个亮度值转换为一个亮度值), 也即 YUV(亮度,饱和度)的过程。常见的 24 位深度彩色图像 RGB888 中的每

    2024年01月25日
    浏览(34)
  • RAW、RGB、YUV 图像格式区别

    颜色是人的视觉系统对光谱中可见区域的感知效果,它仅存在于人的眼睛和大脑中。为了准确地描述颜色,必须引入色彩空间的概念。正如几何上用坐标空间来描述坐标集合,色彩空间用数学方式来描述颜色集合。 RAW 图像就是图像感应器将捕捉到的光源信号转化为数字信号

    2024年02月04日
    浏览(33)
  • 【图像处理】音视频色彩:RGB/YUV

    目录 1.RGB  1.1介绍        1.2分类 1.2.1RGB16 1)RGB565 2)RGB555 1.2.2RGB24 1.2.3RGB222 /

    2024年02月20日
    浏览(37)
  • 视频图像的两种表示方式YUV与RGB(4)

    本篇主要讲YUV与RGB之间的转换,包括YUV444 颜色编码格式 转为 RGB 格式 ,RGB颜色编码格式转为 YUV444 格式。 一、 YUV与RGB之间的转换 YUV与RGB颜色格式之间进行转换时 , 涉及一系列的数学运算 ; YUV 颜色编码格式转为RGB格式的转换公式 取决于 于 YUV 的具体子采样格式 : YUV444 YUV42

    2024年04月11日
    浏览(27)
  • 图像处理算法大全(基于libyuv或IPP)----NV12转成I420,RGB24,ARGB集合

    《周星星教你学ffmpeg》技巧 libyuv源码: static void NV12ToI420(BYTE* pNV12_Y, BYTE* pNV12_UV, BYTE* pYV12, int width, int height) {     libyuv::NV12ToI420(pNV12_Y, width, pNV12_UV, width, pYV12, width, pYV12 + height*width, width / 2, pYV12 + height*width * 5 / 4, width / 2, width, height);//去掉注释就是libyuv了 } static void NV12ToBGR

    2024年02月12日
    浏览(29)
  • 【超直白讲解opencv RGB与BGR】RGB模式与BGR模式有什么不同,如何相互转换?

    一、为什么会有BGR和RGB两种通道? 首先RGB与BGR本质都没有什么区别,OpenCV和PIL读取图片的格式分别是BGR和RGB。 当我们使用OpenCV读取图像时,你应该也会发现读取的数组其实是 BGR 格式,而不是我们听得最多、用得最多的 RGB 格式。那为什么要用BGR通道而不用RGB通道来描述图像

    2024年02月01日
    浏览(31)
  • 浅析YUV422/YUV420模式

    有两种理解: 每4个像素,Y分量采样4次,U分量采样2次,V分量采样2次,即每2个Y分量共享一组UV分量。若每个色彩分量, 存储长度 为1Byte(8bit),则一个像素点占用总长度为:(1byte*4 + 1byte*2 + 1byte*2)/4 = 2bytes 在[Y0 U0 Y1 V0](32bit)中,Y0U0V0 组成第一个像素, Y1U0V0 组成第二个像素

    2024年02月07日
    浏览(26)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包