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);

猜你喜欢

转载自www.cnblogs.com/wangha/p/12510774.html