轉自:https://blog.csdn.net/LG1259156776/article/details/52006457?locationNum=10&fps=1
RGB組合格式
名字
RGB組合格式
描述
此格式用來匹配PC圖形幀緩存。每個像素占據8,16,24或32個位,他們都是組合像素格式,其意為在內存中所有像素數據都是相鄰排列的。當使用這些格式之一時,驅動應該上報顏色空間為V4L2_COLORSPACE_SRGB。
表2.6 組合RGB圖像格式
定義 | 碼 | Byte 0 | Byte 1 | Byte 2 | Byte 3 |
---|---|---|---|---|---|
V4L2_PIX_FMT_RGB332 | RGB1 | r2 r1 r0 g2 g1 g0 b1 b0 | - | - | - |
V4L2_PIX_FMT_RGB444 | R444 | g3 g2 g1 g0 b3 b2 b1 b0 | a3 a2 a1 a0 r3 r2 r1 r0 | - | - |
V4L2_PIX_FMT_RGB555 | RGBO | g2 g1 g0 b4 b3 b2 b1 b0 | a r4 r3 r2 r1 r0 g4 g3 | - | - |
V4L2_PIX_FMT_RGB565 | RGBP | g2 g1 g0 b4 b3 b2 b1 b0 | r4 r3 r2 r1 r0 g5 g4 g3 | - | - |
V4L2_PIX_FMT_RGB555X | RGBQ | a r4 r3 r2 r1 r0 g4 g3 | g2 g1 g0 b4 b3 b2 b1 b0 | - | - |
V4L2_PIX_FMT_RGB565X | RGBR | r4 r3 r2 r1 r0 g5 g4 g3 | g2 g1 g0 b4 b3 b2 b1 b0 | - | - |
V4L2_PIX_FMT_BGR666 | BGRH | b5 b4 b3 b2 b1 b0 g5 g4 | g3 g2 g1 g0 r5 r4 r3 r2 | r1 r0 | - |
V4L2_PIX_FMT_BGR24 | BGR3 | b7 b6 b5 b4 b3 b2 b1 b0 | g7 g6 g5 g4 g3 g2 g1 g0 | r7 r6 r5 r4 r3 r2 r1 r0 | - |
V4L2_PIX_FMT_RGB24 | RGB3 | r7 r6 r5 r4 r3 r2 r1 r0 | g7 g6 g5 g4 g3 g2 g1 g0 | b7 b6 b5 b4 b3 b2 b1 b0 | - |
V4L2_PIX_FMT_BGR32 | RGR4 | b7 b6 b5 b4 b3 b2 b1 b0 | g7 g6 g5 g4 g3 g2 g1 g0 | r7 r6 r5 r4 r3 r2 r1 r0 | a7 a6 a5 a4 a3 a2 a1 a0 |
V4L2_PIX_FMT_RGB32 | RGB4 | a7 a6 a5 a4 a3 a2 a1 a0 | r7 r6 r5 r4 r3 r2 r1 r0 | g7 g6 g5 g4 g3 g2 g1 g0 | b7 b6 b5 b4 b3 b2 b1 b0 |
第7位是符號位,a(alpha)的值在讀取驅動時並未定義,所以編寫驅動時忽略它吧,除非是在Overlay或輸出Overlay時候協商了透明度,又或是在使用V4L2_CID_ALPHA_COMPONENT控制視頻捕捉時候設置透明度部分。
例2.2 V4L2_PIX_FMT_BGR24 4 x 4像素圖像
-
start + 00: B00 G00 R00 B01 G01 R01 B02 G02 R02 B03 G03 R03
-
start + 12: B10 G10 R10 B11 G11 R11 B12 G12 R12 B13 G13 R13
-
start + 24: B20 G20 R20 B21 G21 R21 B22 G22 R22 B23 G23 R23
-
start + 36: B30 G30 R30 B31 G31 R31 B32 G32 R32 B33 G33 R33
V4L2_PIX_FMT_SBGGR8('BA81')
名字
V4L2_PIX_FMT_SBGGR8 貝爾RGB格式
描述
這一般是數字相機的本地格式,與CCD設備的傳感器陣列對應。每個像素只有一個值或是紅色、綠色、藍色,丟失的部分必須由相鄰像素插值而來。第一行從左到右由藍色和綠色組成,第二行是綠色和紅色,每兩行/列以此類推。
例2.3 V4L2_PIX_FMT_SBGGR8 4 x 4像素圖像
-
start + 0: B00 G01 B02 G03
-
start + 4: G10 R11 G12 R13
-
start + 8: B20 G21 B22 G23
-
start +12: G30 R31 G32 R33
V4L2_PIX_FMT_SGBRG8 ('GBRG')
名字
V4L2_PIX_FMT_SGBRG8 貝爾RGB格式
描述
貝爾格式描述基本相同,只是像素排列規則不同。此格式是第一行從做到有包含綠色和藍色,第二行是紅色和綠色,每兩行/列依此類推。
例2.4 V4L2_PIX_FMT_SGBRG8 4 x 4像素圖像
-
start + 0: G00 B01 G02 B03
-
start + 4: R10 G11 R12 G13
-
start + 8: G20 B21 G22 B23
-
start +12: R30 G31 R32 G33
V4L2_PIX_FMT_SGRBG8 ('GRBG')
名字
V4L2_PIX_FMT_SGRBG8 貝爾RGB格式
描述
第一行從左到右包含綠色和藍色,第二行包含紅色和綠色,每兩行/列依此類推。
例2.5 V4L2_PIX_FMT_SGRBG8 4 x 4像素圖像
-
start + 0: G00 R01 G02 R03
-
start + 4: R10 B11 R12 B13
-
start + 8: G20 R21 G22 R23
-
start +12: R30 B31 R32 B33
V4L2_PIX_FMT_SRGGB8 ('RGGB')
名字
V4L2_PIX_FMT_SRGGB8 貝爾RGB格式
描述
第一行從左到右包含紅色和綠色,第二行包含綠色和藍色,每兩行/列依此類推。
例2.6 V4L2_PIX_FMT_SRGGB8 4 x 4像素圖像
-
start + 0: R00 G01 R02 G03
-
start + 4: G10 B11 G12 B13
-
start + 8: R20 G21 R22 G23
-
start +12: G30 B31 G32 B33
V4L2_PIX_FMT_SBGGR16 ('BYR2')
名字
V4L2_PIX_FMT_SBGGR16 貝爾RGB格式
描述
此格式與V4L2_PIX_FMT_SBGGR8很相似,不同是每個像素擁有16位深度。低數據存儲在小地址內存中(低位機)。實際采樣精度可能會比16位低,必須每個像素10位,值范圍0~1023(如MT9T001)。
例2.7 V4L2_PIX_FMT_SBGGR16 4 x 4像素圖像
-
start + 0: B00low B00high G01low G01high B02low B02high G03low G03high
-
start + 8: G10low G10high R11low R11high G12low G12high R13low R13high
-
start +16: B20low B20high G21low G21high B22low B22high G23low G23high
-
start +24: G30low G30high R31low R31high G32low G32high R33low R33high
V4L2_PIX_FMT_SRGGB10 ('RG10'), V4L2_PIX_FMT_SGRBG10 ('BA10'), V4L2_PIX_FMT_SGBRG10 ('GB10'), V4L2_PIX_FMT_SBGGR10 ('BG10')
名字
V4L2_PIX_FMT_SRGGB10 ('RG10'), V4L2_PIX_FMT_SGRBG10 ('BA10'), V4L2_PIX_FMT_SGBRG10 ('GB10'), V4L2_PIX_FMT_SBGGR10 ('BG10') 10bit貝爾格式擴展的16位格式
描述
這4個像素格式是每個顏色10位的raw sRGB/貝爾格式。每個顏色部分都存儲在16位字段中,高6位是不用的,填充0。每n像素行包含n/2個綠色取樣和n/2個藍色取樣或紅色取樣,紅色和藍色行交替。字節以低位機序列存儲。他們通常是來描述如GRGR...BGBG...或RGRG...GBGB...等等。以下是其中的一個例子。
例2.8 V4L2_PIX_FMT_SBGGR10 4 x 4像素圖像
-
每個代表一個字節,高字節的高6位為0
-
start + 0: B00low B00high G01low G01high B02low B02high G03low G03high
-
start + 8: G10low G10high R11low R11high G12low G12high R13low R13high
-
start +16: B20low B20high G21low G21high B22low B22high G23low G23high
-
start +24: G30low G30high R31low R31high G32low G32high R33low R33high
V4L2_PIX_FMT_SBGGR10ALAW8 ('aBA8'), V4L2_PIX_FMT_SGBRG10ALAW8 ('aGA8'), V4L2_PIX_FMT_SGRBG10ALAW8 ('agA8'), V4L2_PIX_FMT_SRGGB10ALAW8 ('aRA8')
名字
V4L2_PIX_FMT_SBGGR10ALAW8 , V4L2_PIX_FMT_SGBRG10ALAW8 , V4L2_PIX_FMT_SGRBG10ALAW8 , V4L2_PIX_FMT_SRGGB10ALAW8 10位貝爾格式壓縮至8位。
描述
這些格式是每個顏色10位的raw sRGB/貝爾格式壓縮到8位,使用A-LAW算法。每個顏色部分在內存中占據8位,其他與V4L2_PIX_FMT_SRGGB8特性類似。
V4L2_PIX_FMT_SBGGR10DPCM8 ('bBA8'), V4L2_PIX_FMT_SGBRG10DPCM8 ('bGA8'), V4L2_PIX_FMT_SGRBG10DPCM8 ('BD10'), V4L2_PIX_FMT_SRGGB10DPCM8 ('bRA8')
名字
V4L2_PIX_FMT_SBGGR10DPCM8, V4L2_PIX_FMT_SGBRG10DPCM8, V4L2_PIX_FMT_SGRBG10DPCM8, V4L2_PIX_FMT_SRGGB10DPCM8 10位貝爾格式壓縮至8位。
描述
使用DPCM將每個顏色部分壓縮至8位。DPCM調整是有損耗的,每個顏色在內存中占用8位,其他部分與V4L2_PIX_FMT_SRGGB10 ('RG10'), V4L2_PIX_FMT_SGRBG10 ('BA10'), V4L2_PIX_FMT_SGBRG10 ('GB10'), V4L2_PIX_FMT_SBGGR10 ('BG10')類似。
V4L2_PIX_FMT_SRGGB12 ('RG12'), V4L2_PIX_FMT_SGRBG12 ('BA12'), V4L2_PIX_FMT_SGBRG12 ('GB12'), V4L2_PIX_FMT_SBGGR12 ('BG12')
名字
V4L2_PIX_FMT_SRGGB12, V4L2_PIX_FMT_SGRBG12, V4L2_PIX_FMT_SGBRG12, V4L2_PIX_FMT_SBGGR12 12位貝爾格式擴展為16位
描述
每個顏色12位的raw sRGB/貝爾格式,每個顏色部分被保存在16位的字段中,高6位為0。每個n像素行包含n/2個綠色取樣及n/2個藍色或紅色取樣,紅、藍行交替。字節按低位機順序存儲在內存中,通常用來描述如GEGE...BGBG...或RGRG...RBRB...等。下邊是其中一個的例子。
例2.9 V4L2_PIX_FMT_SBGGR12 4 x 4像素圖片
-
start + 0: B00low B00high G01low G01high B02low B02high G03low G03high
-
start + 8: G10low G10high R11low R11high G12low G12high R13low R13high
-
start +16: B20low B20high G21low G21high B22low B22high G23low G23high
-
start +24: G30low G30high R31low R31high G32low G32high R33low R33high
.........................................................................................................................
以下是根據上面的文檔寫的轉換代碼:RGGB/BGGR轉RGB
#include <fcntl.h> #include <getopt.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> static void raw10_to_raw8(char *in, char *out, int width, int height) { int i,j; char temp; //RAW10 --> RAW8 for(j = 0; j < height; j++) { for(i = 0; i < width * 2; i = i + 2) { temp = 0; temp = in[j * width * 2 + i]; //low out[j * width + i / 2] = temp; /* temp = 0; temp = in[j * width * 2 + i] >> 2; //low temp |= in[j * width * 2 + i + 1] << 6; //high out[j * width + i / 2] = temp; */ } } //printf("aa0 %x %x %x %x \n", out[0], out[1], out[2], out[3]); //printf("aa1 %x %x %x %x \n", out[width], out[width+1], out[width+2], out[width+3]); } #if 0 static int rggb2rgb(char *in, char *out, int width, int height) { /* R G1 ---> RG1B RG1B G2 B ---> RG2B RG2B */ int i,j; //RGRGRG for(j = 0; j < height; j= j + 2) { for(i = 0; i < width * 3; i = i + 6) { //(0,0) out[(j * width * 3) + (i + 0)] = in[(j * width) + (i / 3)]; //R out[(j * width * 3) + (i + 1)] = in[(j * width) + (i / 3) + 1]; //G1 out[(j * width * 3) + (i + 2)] = in[((j+1) * width) + (i / 3) + 1];//B //(0,1) == (0,0) out[(j * width * 3) + (i + 3)] = in[(j * width) + (i / 3)]; //R out[(j * width * 3) + (i + 4)] = in[(j * width) + (i / 3) + 1]; //G1 out[(j * width * 3) + (i + 5)] = in[((j+1) * width) + (i / 3) + 1];//B } } //GBGBGB for(j = 1; j < height; j= j + 2) { for(i = 0; i < width * 3; i = i + 6) { //(1,0) out[(j * width * 3) + (i + 0)] = in[((j-1) * width) + (i / 3)]; //R out[(j * width * 3) + (i + 1)] = in[(j * width) + (i / 3)]; //G2 out[(j * width * 3) + (i + 2)] = in[(j * width) + (i / 3) + 1]; //B //(1,0) == (1,1) out[(j * width * 3) + (i + 3)] = in[((j-1) * width) + (i / 3)]; //R out[(j * width * 3) + (i + 4)] = in[(j * width) + (i / 3)]; //G2 out[(j * width * 3) + (i + 5)] = in[(j * width) + (i / 3) + 1]; //B } } //printf("000 %x %x %x %x \n", out[0], out[1], out[2], out[3]); //printf("111 %x %x %x %x \n", out[width], out[width+1], out[width+2], out[width+3]); return width * height * 3; } #endif #if 1 static int bggr2rgb(char *in, char *out, int width, int height) { /* B G1 ---> RG1B RG1B G2 R ---> RG2B RG2B */ int i,j; //BGBGBG for(j = 0; j < height; j= j + 2) { for(i = 0; i < width * 3; i = i + 6) { //(0,0) out[(j * width * 3) + (i + 0)] = in[((j+1) * width) + (i / 3) + 1];//R out[(j * width * 3) + (i + 1)] = in[(j * width) + (i / 3) + 1]; //G1 out[(j * width * 3) + (i + 2)] = in[(j * width) + (i / 3)]; //B //(0,1) == (0,0) out[(j * width * 3) + (i + 3)] = in[((j+1) * width) + (i / 3) + 1];//R out[(j * width * 3) + (i + 4)] = in[(j * width) + (i / 3) + 1]; //G1 out[(j * width * 3) + (i + 5)] = in[(j * width) + (i / 3)]; //B } } //GRGRGR for(j = 1; j < height; j= j + 2) { for(i = 0; i < width * 3; i = i + 6) { //(1,0) out[(j * width * 3) + (i + 0)] = in[(j * width) + (i / 3) + 1]; //R out[(j * width * 3) + (i + 1)] = in[(j * width) + (i / 3)]; //G2 out[(j * width * 3) + (i + 2)] = in[((j-1) * width) + (i / 3)]; //B //(1,0) == (1,1) out[(j * width * 3) + (i + 3)] = in[(j * width) + (i / 3) + 1]; //R out[(j * width * 3) + (i + 4)] = in[(j * width) + (i / 3)]; //G2 out[(j * width * 3) + (i + 5)] = in[((j-1) * width) + (i / 3)]; //B } } //printf("000 %x %x %x %x \n", out[0], out[1], out[2], out[3]); //printf("111 %x %x %x %x \n", out[width], out[width+1], out[width+2], out[width+3]); return width * height * 3; } #endif static void usage( char * name ) { printf("usage: %s\n", name); printf(" --input,-i input file\n"); printf(" --output,-o output file\n"); printf(" --width,-w image width (pixels)\n"); printf(" --height,-v image height (pixels)\n"); printf(" --help,-h this helpful message\n"); } int main( int argc, char ** argv ) { int width = 0; int height = 0; int size_in = 0; int size_out = 0; char c; int optidx = 0; char *infile = NULL; char *outfile = NULL; FILE *input_fd = NULL; FILE *output_fd = NULL; char *buff_tmp = NULL; char *buff_in = NULL; char *buff_out = NULL; int param_num = 4; while (param_num--) { optidx = 0; struct option longopt[] = { {"input",1,NULL,'i'}, {"output",1,NULL,'o'}, {"width",1,NULL,'w'}, {"height",1,NULL,'v'}, {"help",0,NULL,'h'}, {0,0,0,0} }; c = getopt_long(argc, argv, "i:o:w:v:h", longopt, &optidx); if (c == -1) break; switch ( c ) { case 'i': infile = strdup( optarg ); break; case 'o': outfile = strdup( optarg ); break; case 'w': width = strtol( optarg, NULL, 10 ); break; case 'v': height = strtol( optarg, NULL, 10 ); break; case 'h': usage(argv[0]); return 0; break; default: printf("lsc bad arg %c\n", c); usage(argv[0]); //return 1; } } // arguments: infile outfile width height if( infile == NULL || outfile == NULL || width == 0 || height == 0 ) { printf("Bad parameter\n"); usage(argv[0]); return 1; } buff_tmp = calloc(width * height, sizeof(char)); buff_in = calloc(width * height * 2, sizeof(char)); buff_out = calloc(width * height * 4, sizeof(char)); if(NULL == buff_tmp || NULL == buff_in || NULL == buff_out) { printf("malloc error\n"); goto end; } input_fd = fopen(infile, "r"); if(NULL == input_fd) { printf("Problem opening input: %s\n", infile); return 1; } output_fd = fopen(outfile, "w"); if(NULL == output_fd) { printf("Problem opening output: %s\n", outfile); return 1; } //讀文件 size_in = fread(buff_in, 1, width * height * 2, input_fd); if(size_in != width * height * 2) { printf("error!! size_in != width * height 2, size_in= %d\n", size_in); goto end; } raw10_to_raw8(buff_in, buff_tmp, width, height); size_out = bggr2rgb(buff_tmp, buff_out, width, height); //size_out = rggb2rgb(buff_tmp, buff_out, width, height); //寫入數據到文件 fwrite(buff_out, 1, size_out, output_fd); end: if(input_fd) fclose(input_fd); if(output_fd) fclose(output_fd); if(NULL == buff_tmp) { free(buff_tmp); } if(NULL == buff_in) { free(buff_in); } if(NULL == buff_out) { free(buff_out); } return 0; }