Isp

RGB変換NV21(YUVのストレージフォーマット)(コード実装)



Rgb Conversion Nv21 Storage Format



インターンシップの2番目のタスクは、RGB画像をNV21(YUVのストレージ形式であり、Android携帯の画像の最も一般的なrawストレージ形式でもあります)に変換することです。

NV21や他の同様のストレージフォーマットを見てみましょう〜



NV21(YUV420)の紹介
NV12とNV21はYUV420フォーマット(2x2ごとに4つのY、uvのグループを共有)に属し、2プレーンモードです。つまり、YとUVは2つのプレーンに分割されますが、CbCr)は分割されるのではなくインターリーブされたストレージです3つの平面に。すべてのYを最初に保存し、次にUVスタッガードストレージ:NV12を最初にU、次にV、NV21を最初にV、次にU。

YUV420spのフォーマット例は次のとおりです。



NV21:
è&iquestéåå&frac34çæè&iquest°

NV12:

è&iquestéåå&frac34çæè&iquest°



NV21とNV12のストレージ形式は、RBGストレージ形式のようなストレージ形式ではなく、YコンポーネントとUコンポーネントとVコンポーネントの分離であることがわかります。

私が気付いた機能は、RGB形式の画像をNV21のバイナリ形式として保存し、YUV-7YUVを開くように特別に設計されたソフトウェアを使用してファイルを開くことです。

まずはカンカン効果に来てください〜

RGB.jpg(元の画像)

opencvでNV21に保存されている画像を開きます。

下の灰色のスペースは、opencvでのUコンポーネントとVコンポーネントの表示です。

7YUVソフトウェアで開いた後のレンダリング:

具体的なコードの実装は次のとおりです。

#include #include #include #include #include #include #include void RGB2NV21() { const char *filename = 'yuv.yuv' cv::Mat Img = cv::imread('RGB.jpg') FILE *fp = fopen(filename,'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[1.5 * rows * cols] cv::Mat NV21(rows+rows/2, cols, CV_8UC1) cv::Mat OpencvYUV cv::Mat OpencvImg cv::cvtColor(Img, OpencvYUV, CV_BGR2YUV_YV12) int UVRow{ 0 } for (int i=0i> 8 YPointer[j] = Y yuvbuff[Yindex++] = (Y 255) ? 255 : Y) uchar* UVPointer = NV21.ptr(rows+i/2) //Calculate the values ​​of U and V, and sample 2x2 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 UVPointer[j] = V UVPointer[j+1] = U yuvbuff[UVindex++] = (V 255) ? 255 : V) yuvbuff[UVindex++] = (U 255) ? 255 : U) } } } for (int i=0i<1.5 * rows * colsi++) { fwrite(&yuvbuff[i], 1, 1, fp) } fclose(fp) std::cout << 'write to file ok!' << std::endl std::cout << 'srcImg: ' << 'rows:' << Img.rows << 'cols:' << Img.cols << std::endl std::cout << 'NV21: ' << 'rows:' << NV21.rows << 'cols:' << NV21.cols << std::endl std::cout << 'opencv_YUV: ' << 'rows:' << OpencvYUV.rows << 'cols:' << OpencvYUV.cols << std::endl cv::imshow('src', Img)//Original picture cv::imshow('YUV', NV21)//The converted picture cv::imshow('opencv_YUV', OpencvYUV) //Opencv converted picture cv::imwrite('NV21.jpg', NV21) cv::waitKey(30000) } int main() { RGB2NV21() return 0 }

上記はRBGからNV21までの全内容です