1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 如何将yuv420p图像数据转换为RGB数据并使用opencv保存为jpg图片

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

时间:2024-04-17 18:04:12

相关推荐

如何将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; // bluepixel[1] = g; // greenpixel[2] = r; //redreturn 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;}

如果有任何问题,欢迎评论。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。