JPG图像以NV21存储

JPG图像以NV21存储

因为遇到一些问题,需要将Jpg图片转化为NV21二进制文件保存,因此,在网上找了很多博客教程,都没能直接解决问题,因此,决定自己动手解决问题。

代码

使用了opencv::cvtColor()

void opencvRGB2NV21(string infile, char* outfile){
    Mat Img = cv::imread(infile);
    int buflen = (int)(Img.rows * Img.cols * 3 / 2);
    unsigned char* pYuvBuf = new unsigned char[buflen];
    Mat OpencvYUV;
    FILE* fout = fopen(outfile, "wb");
    cvtColor(Img, OpencvYUV, CV_BGR2YUV_YV12);
    memcpy(pYuvBuf, OpencvYUV.data, buflen*sizeof(unsigned char));
    fwrite(pYuvBuf, buflen*sizeof(unsigned char), 1, fout);
    fclose(fout);
}

不使用opencv::cvtColor()

void RGB2NV21(string infile, char* outfile){
	cv::Mat Img = cv::imread(infile);
	FILE  *fp = fopen(outfile, "wb");

	if (Img.empty()){
		std::cout << "empty!check your image";
		return;
	}
	int cols = Img.cols;
	int rows = Img.rows;
 
	int Yindex = 0;
	int UVindex = rows * cols;
 
	unsigned char* yuvbuff = new unsigned char[int(1.5 * rows * cols)];
 
	cv::Mat OpencvYUV;
	cv::Mat OpencvImg;
	cv::cvtColor(Img, OpencvYUV, CV_BGR2YUV_YV12);
	
	int UVRow{ 0 };
	for (int i=0;i<rows;i++){
		for (int j=0;j<cols;j++){
			int B = Img.at<cv::Vec3b>(i, j)[0];
			int G = Img.at<cv::Vec3b>(i, j)[1];
			int R = Img.at<cv::Vec3b>(i, j)[2];

			int Y = (77 * R + 150 * G + 29 * B) >> 8;
			yuvbuff[Yindex++] = (Y < 0) ? 0 : ((Y > 255) ? 255 : Y);
			if (i%2==0&&(j)%2==0)
			{
				int U = ((-44 * R - 87 * G + 131 * B) >> 8) + 128;
				int V = ((131 * R - 110 * G - 21 * B) >> 8) + 128;
				yuvbuff[UVindex++] = (V < 0) ? 0 : ((V > 255) ? 255 : V);
				yuvbuff[UVindex++] = (U < 0) ? 0 : ((U > 255) ? 255 : U);
			}
		}
	}
    for (int i=0;i< 1.5 * rows * cols;i++){
	    fwrite(&yuvbuff[i], 1, 1, fp);
    }
    fclose(fp);
posted @ 2020-03-17 15:02  wangha  阅读(1011)  评论(0编辑  收藏  举报