bayer, yuv, RGB转换方法

摘要:
网上找了很久也没找到格式转换工具,最后放弃了,觉得还是写个转换工具比较快。

http://blog.csdn.net/kickxxx/article/details/6642888

因为我的STVxxx USB camera输出格式是bayer格式,手头上只有YUVTOOLS这个查看工具,没法验证STVxxx在开发板上是否正常工作。

网上找了很久也没找到格式转换工具,最后放弃了,觉得还是写个转换工具比较快。抄写了部分libv4lconvert的代码, 我只验证了

V4L2_PIX_FMT_SGBRG8到V4L2_PIX_FMT_YUV420的转换。

bayer.c

##################################################################################

  1. /*
  2. *lib4lconvert,video4linux2formatconversionlib
  3. *(C)2008HansdeGoede<hdegoede@redhat.com>
  4. *
  5. *Thislibraryisfreesoftware;youcanredistributeitand/or
  6. *modifyitunderthetermsoftheGNULesserGeneralPublic
  7. *LicenseaspublishedbytheFreeSoftwareFoundation;either
  8. *version2.1oftheLicense,or(atyouroption)anylaterversion.
  9. *
  10. *Thislibraryisdistributedinthehopethatitwillbeuseful,
  11. *butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof
  12. *MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.SeetheGNU
  13. *LesserGeneralPublicLicenseformoredetails.
  14. *
  15. *YoushouldhavereceivedacopyoftheGNULesserGeneralPublic
  16. *Licensealongwiththislibrary;ifnot,writetotheFreeSoftware
  17. *Foundation,Inc.,51FranklinStreet,Suite500,Boston,MA02110-1335USA
  18. *
  19. *Note:originalbayer_to_bgr24codefrom:
  20. *1394-BasedDigitalCameraControlLibrary
  21. *
  22. *Bayerpatterndecodingfunctions
  23. *
  24. *WrittenbyDamienDouxchampsandFredericDevernay
  25. *
  26. *Notethattheoriginalbayer.cinlibdc1394supportsmanydifferent
  27. *bayerdecodealgorithms,forlib4lconverttheoneinthisfilehasbeen
  28. *chosen(andoptimizedabit)andtheotheralgorithm'shavebeenremoved,
  29. *seebayer.cfromlibdc1394forallsupportedalgorithms
  30. */
  31. #include<string.h>
  32. #include<linux/videodev2.h>
  33. #include<stdio.h>
  34. #include"convert.h"
  35. /**************************************************************
  36. *Colorconversionfunctionsforcamerasthatcan*
  37. *outputraw-Bayerpatternimages,suchassomeBaslerand*
  38. *PointGreycamera.Mostofthealgospresentedherecome*
  39. *fromhttp://www-ise.stanford.edu/~tingchen/andhavebeen*
  40. *convertedfromMatlabtoCandextendedtoallelementary*
  41. *patterns.*
  42. **************************************************************/
  43. /*inspiredbyOpenCV'sBayerdecoding*/
  44. staticvoidv4lconvert_border_bayer_line_to_bgr24(
  45. constunsignedchar*bayer,constunsignedchar*adjacent_bayer,
  46. unsignedchar*bgr,intwidth,intstart_with_green,intblue_line)
  47. {
  48. intt0,t1;
  49. if(start_with_green){
  50. /*Firstpixel*/
  51. if(blue_line){
  52. *bgr++=bayer[1];
  53. *bgr++=bayer[0];
  54. *bgr++=adjacent_bayer[0];
  55. }else{
  56. *bgr++=adjacent_bayer[0];
  57. *bgr++=bayer[0];
  58. *bgr++=bayer[1];
  59. }
  60. /*Secondpixel*/
  61. t0=(bayer[0]+bayer[2]+adjacent_bayer[1]+1)/3;
  62. t1=(adjacent_bayer[0]+adjacent_bayer[2]+1)>>1;
  63. if(blue_line){
  64. *bgr++=bayer[1];
  65. *bgr++=t0;
  66. *bgr++=t1;
  67. }else{
  68. *bgr++=t1;
  69. *bgr++=t0;
  70. *bgr++=bayer[1];
  71. }
  72. bayer++;
  73. adjacent_bayer++;
  74. width-=2;
  75. }else{
  76. /*Firstpixel*/
  77. t0=(bayer[1]+adjacent_bayer[0]+1)>>1;
  78. if(blue_line){
  79. *bgr++=bayer[0];
  80. *bgr++=t0;
  81. *bgr++=adjacent_bayer[1];
  82. }else{
  83. *bgr++=adjacent_bayer[1];
  84. *bgr++=t0;
  85. *bgr++=bayer[0];
  86. }
  87. width--;
  88. }
  89. if(blue_line){
  90. for(;width>2;width-=2){
  91. t0=(bayer[0]+bayer[2]+1)>>1;
  92. *bgr++=t0;
  93. *bgr++=bayer[1];
  94. *bgr++=adjacent_bayer[1];
  95. bayer++;
  96. adjacent_bayer++;
  97. t0=(bayer[0]+bayer[2]+adjacent_bayer[1]+1)/3;
  98. t1=(adjacent_bayer[0]+adjacent_bayer[2]+1)>>1;
  99. *bgr++=bayer[1];
  100. *bgr++=t0;
  101. *bgr++=t1;
  102. bayer++;
  103. adjacent_bayer++;
  104. }
  105. }else{
  106. for(;width>2;width-=2){
  107. t0=(bayer[0]+bayer[2]+1)>>1;
  108. *bgr++=adjacent_bayer[1];
  109. *bgr++=bayer[1];
  110. *bgr++=t0;
  111. bayer++;
  112. adjacent_bayer++;
  113. t0=(bayer[0]+bayer[2]+adjacent_bayer[1]+1)/3;
  114. t1=(adjacent_bayer[0]+adjacent_bayer[2]+1)>>1;
  115. *bgr++=t1;
  116. *bgr++=t0;
  117. *bgr++=bayer[1];
  118. bayer++;
  119. adjacent_bayer++;
  120. }
  121. }
  122. if(width==2){
  123. /*Secondtolastpixel*/
  124. t0=(bayer[0]+bayer[2]+1)>>1;
  125. if(blue_line){
  126. *bgr++=t0;
  127. *bgr++=bayer[1];
  128. *bgr++=adjacent_bayer[1];
  129. }else{
  130. *bgr++=adjacent_bayer[1];
  131. *bgr++=bayer[1];
  132. *bgr++=t0;
  133. }
  134. /*Lastpixel*/
  135. t0=(bayer[1]+adjacent_bayer[2]+1)>>1;
  136. if(blue_line){
  137. *bgr++=bayer[2];
  138. *bgr++=t0;
  139. *bgr++=adjacent_bayer[1];
  140. }else{
  141. *bgr++=adjacent_bayer[1];
  142. *bgr++=t0;
  143. *bgr++=bayer[2];
  144. }
  145. }else{
  146. /*Lastpixel*/
  147. if(blue_line){
  148. *bgr++=bayer[0];
  149. *bgr++=bayer[1];
  150. *bgr++=adjacent_bayer[1];
  151. }else{
  152. *bgr++=adjacent_bayer[1];
  153. *bgr++=bayer[1];
  154. *bgr++=bayer[0];
  155. }
  156. }
  157. }
  158. /*Fromlibdc1394,whichonturnwasbasedonOpenCV'sBayerdecoding*/
  159. staticvoidbayer_to_rgbbgr24(constunsignedchar*bayer,
  160. unsignedchar*bgr,intwidth,intheight,unsignedintpixfmt,
  161. intstart_with_green,intblue_line)
  162. {
  163. /*renderthefirstline*/
  164. v4lconvert_border_bayer_line_to_bgr24(bayer,bayer+width,bgr,width,
  165. start_with_green,blue_line);
  166. bgr+=width*3;
  167. return;
  168. /*reduceheightby2becauseofthespecialcasetop/bottomline*/
  169. for(height-=2;height;height--){
  170. intt0,t1;
  171. /*(width-2)becauseoftheborder*/
  172. constunsignedchar*bayer_end=bayer+(width-2);
  173. if(start_with_green){
  174. /*OpenCVhasabuginthenextline,whichwas
  175. t0=(bayer[0]+bayer[width*2]+1)>>1;*/
  176. t0=(bayer[1]+bayer[width*2+1]+1)>>1;
  177. /*Writefirstpixel*/
  178. t1=(bayer[0]+bayer[width*2]+bayer[width+1]+1)/3;
  179. if(blue_line){
  180. *bgr++=t0;
  181. *bgr++=t1;
  182. *bgr++=bayer[width];
  183. }else{
  184. *bgr++=bayer[width];
  185. *bgr++=t1;
  186. *bgr++=t0;
  187. }
  188. /*Writesecondpixel*/
  189. t1=(bayer[width]+bayer[width+2]+1)>>1;
  190. if(blue_line){
  191. *bgr++=t0;
  192. *bgr++=bayer[width+1];
  193. *bgr++=t1;
  194. }else{
  195. *bgr++=t1;
  196. *bgr++=bayer[width+1];
  197. *bgr++=t0;
  198. }
  199. bayer++;
  200. }else{
  201. /*Writefirstpixel*/
  202. t0=(bayer[0]+bayer[width*2]+1)>>1;
  203. if(blue_line){
  204. *bgr++=t0;
  205. *bgr++=bayer[width];
  206. *bgr++=bayer[width+1];
  207. }else{
  208. *bgr++=bayer[width+1];
  209. *bgr++=bayer[width];
  210. *bgr++=t0;
  211. }
  212. }
  213. if(blue_line){
  214. for(;bayer<=bayer_end-2;bayer+=2){
  215. t0=(bayer[0]+bayer[2]+bayer[width*2]+
  216. bayer[width*2+2]+2)>>2;
  217. t1=(bayer[1]+bayer[width]+bayer[width+2]+
  218. bayer[width*2+1]+2)>>2;
  219. *bgr++=t0;
  220. *bgr++=t1;
  221. *bgr++=bayer[width+1];
  222. t0=(bayer[2]+bayer[width*2+2]+1)>>1;
  223. t1=(bayer[width+1]+bayer[width+3]+1)>>1;
  224. *bgr++=t0;
  225. *bgr++=bayer[width+2];
  226. *bgr++=t1;
  227. }
  228. }else{
  229. for(;bayer<=bayer_end-2;bayer+=2){
  230. t0=(bayer[0]+bayer[2]+bayer[width*2]+
  231. bayer[width*2+2]+2)>>2;
  232. t1=(bayer[1]+bayer[width]+bayer[width+2]+
  233. bayer[width*2+1]+2)>>2;
  234. *bgr++=bayer[width+1];
  235. *bgr++=t1;
  236. *bgr++=t0;
  237. t0=(bayer[2]+bayer[width*2+2]+1)>>1;
  238. t1=(bayer[width+1]+bayer[width+3]+1)>>1;
  239. *bgr++=t1;
  240. *bgr++=bayer[width+2];
  241. *bgr++=t0;
  242. }
  243. }
  244. if(bayer<bayer_end){
  245. /*writesecondtolastpixel*/
  246. t0=(bayer[0]+bayer[2]+bayer[width*2]+
  247. bayer[width*2+2]+2)>>2;
  248. t1=(bayer[1]+bayer[width]+bayer[width+2]+
  249. bayer[width*2+1]+2)>>2;
  250. if(blue_line){
  251. *bgr++=t0;
  252. *bgr++=t1;
  253. *bgr++=bayer[width+1];
  254. }else{
  255. *bgr++=bayer[width+1];
  256. *bgr++=t1;
  257. *bgr++=t0;
  258. }
  259. /*writelastpixel*/
  260. t0=(bayer[2]+bayer[width*2+2]+1)>>1;
  261. if(blue_line){
  262. *bgr++=t0;
  263. *bgr++=bayer[width+2];
  264. *bgr++=bayer[width+1];
  265. }else{
  266. *bgr++=bayer[width+1];
  267. *bgr++=bayer[width+2];
  268. *bgr++=t0;
  269. }
  270. bayer++;
  271. }else{
  272. /*writelastpixel*/
  273. t0=(bayer[0]+bayer[width*2]+1)>>1;
  274. t1=(bayer[1]+bayer[width*2+1]+bayer[width]+1)/3;
  275. if(blue_line){
  276. *bgr++=t0;
  277. *bgr++=t1;
  278. *bgr++=bayer[width+1];
  279. }else{
  280. *bgr++=bayer[width+1];
  281. *bgr++=t1;
  282. *bgr++=t0;
  283. }
  284. }
  285. /*skip2borderpixels*/
  286. bayer+=2;
  287. blue_line=!blue_line;
  288. start_with_green=!start_with_green;
  289. }
  290. /*renderthelastline*/
  291. v4lconvert_border_bayer_line_to_bgr24(bayer+width,bayer,bgr,width,
  292. !start_with_green,!blue_line);
  293. }
  294. voidv4lconvert_bayer_to_rgb24(constunsignedchar*bayer,
  295. unsignedchar*bgr,intwidth,intheight,unsignedintpixfmt)
  296. {
  297. bayer_to_rgbbgr24(bayer,bgr,width,height,pixfmt,
  298. pixfmt==V4L2_PIX_FMT_SGBRG8/*startwithgreen*/
  299. ||pixfmt==V4L2_PIX_FMT_SGRBG8,
  300. pixfmt!=V4L2_PIX_FMT_SBGGR8/*blueline*/
  301. &&pixfmt!=V4L2_PIX_FMT_SGBRG8);
  302. }
  303. voidv4lconvert_bayer_to_bgr24(constunsignedchar*bayer,
  304. unsignedchar*bgr,intwidth,intheight,unsignedintpixfmt)
  305. {
  306. bayer_to_rgbbgr24(bayer,bgr,width,height,pixfmt,
  307. pixfmt==V4L2_PIX_FMT_SGBRG8/*startwithgreen*/
  308. ||pixfmt==V4L2_PIX_FMT_SGRBG8,
  309. pixfmt==V4L2_PIX_FMT_SBGGR8/*blueline*/
  310. ||pixfmt==V4L2_PIX_FMT_SGBRG8);
  311. }
  312. staticvoidv4lconvert_border_bayer_line_to_y(
  313. constunsignedchar*bayer,constunsignedchar*adjacent_bayer,
  314. unsignedchar*y,intwidth,intstart_with_green,intblue_line)
  315. {
  316. intt0,t1;
  317. if(start_with_green){
  318. /*Firstpixel*/
  319. if(blue_line){
  320. *y++=(8453*adjacent_bayer[0]+16594*bayer[0]+
  321. 3223*bayer[1]+524288)>>15;
  322. }else{
  323. *y++=(8453*bayer[1]+16594*bayer[0]+
  324. 3223*adjacent_bayer[0]+524288)>>15;
  325. }
  326. /*Secondpixel*/
  327. t0=bayer[0]+bayer[2]+adjacent_bayer[1];
  328. t1=adjacent_bayer[0]+adjacent_bayer[2];
  329. if(blue_line)
  330. *y++=(4226*t1+5531*t0+3223*bayer[1]+524288)>>15;
  331. else
  332. *y++=(8453*bayer[1]+5531*t0+1611*t1+524288)>>15;
  333. bayer++;
  334. adjacent_bayer++;
  335. width-=2;
  336. }else{
  337. /*Firstpixel*/
  338. t0=bayer[1]+adjacent_bayer[0];
  339. if(blue_line){
  340. *y++=(8453*adjacent_bayer[1]+8297*t0+
  341. 3223*bayer[0]+524288)>>15;
  342. }else{
  343. *y++=(8453*bayer[0]+8297*t0+
  344. 3223*adjacent_bayer[1]+524288)>>15;
  345. }
  346. width--;
  347. }
  348. if(blue_line){
  349. for(;width>2;width-=2){
  350. t0=bayer[0]+bayer[2];
  351. *y++=(8453*adjacent_bayer[1]+16594*bayer[1]+
  352. 1611*t0+524288)>>15;
  353. bayer++;
  354. adjacent_bayer++;
  355. t0=bayer[0]+bayer[2]+adjacent_bayer[1];
  356. t1=adjacent_bayer[0]+adjacent_bayer[2];
  357. *y++=(4226*t1+5531*t0+3223*bayer[1]+524288)>>15;
  358. bayer++;
  359. adjacent_bayer++;
  360. }
  361. }else{
  362. for(;width>2;width-=2){
  363. t0=bayer[0]+bayer[2];
  364. *y++=(4226*t0+16594*bayer[1]+
  365. 3223*adjacent_bayer[1]+524288)>>15;
  366. bayer++;
  367. adjacent_bayer++;
  368. t0=bayer[0]+bayer[2]+adjacent_bayer[1];
  369. t1=adjacent_bayer[0]+adjacent_bayer[2];
  370. *y++=(8453*bayer[1]+5531*t0+1611*t1+524288)>>15;
  371. bayer++;
  372. adjacent_bayer++;
  373. }
  374. }
  375. if(width==2){
  376. /*Secondtolastpixel*/
  377. t0=bayer[0]+bayer[2];
  378. if(blue_line){
  379. *y++=(8453*adjacent_bayer[1]+16594*bayer[1]+
  380. 1611*t0+524288)>>15;
  381. }else{
  382. *y++=(4226*t0+16594*bayer[1]+
  383. 3223*adjacent_bayer[1]+524288)>>15;
  384. }
  385. /*Lastpixel*/
  386. t0=bayer[1]+adjacent_bayer[2];
  387. if(blue_line){
  388. *y++=(8453*adjacent_bayer[1]+8297*t0+
  389. 3223*bayer[2]+524288)>>15;
  390. }else{
  391. *y++=(8453*bayer[2]+8297*t0+
  392. 3223*adjacent_bayer[1]+524288)>>15;
  393. }
  394. }else{
  395. /*Lastpixel*/
  396. if(blue_line){
  397. *y++=(8453*adjacent_bayer[1]+16594*bayer[1]+
  398. 3223*bayer[0]+524288)>>15;
  399. }else{
  400. *y++=(8453*bayer[0]+16594*bayer[1]+
  401. 3223*adjacent_bayer[1]+524288)>>15;
  402. }
  403. }
  404. }
  405. voidv4lconvert_bayer_to_yuv420(constunsignedchar*bayer,unsignedchar*yuv,
  406. intwidth,intheight,unsignedintsrc_pixfmt,intyvu)
  407. {
  408. intblue_line=0,start_with_green=0,x,y;
  409. unsignedchar*ydst=yuv;
  410. unsignedchar*udst,*vdst;
  411. if(yvu){
  412. vdst=yuv+width*height;
  413. udst=vdst+width*height/4;
  414. }else{
  415. udst=yuv+width*height;
  416. vdst=udst+width*height/4;
  417. }
  418. printf("bayeraddress(0x%p)",bayer);
  419. /*Firstcalculatetheuandvplanes2x2pixelsatatime*/
  420. switch(src_pixfmt){
  421. caseV4L2_PIX_FMT_SBGGR8:
  422. for(y=0;y<height;y+=2){
  423. for(x=0;x<width;x+=2){
  424. intb,g,r;
  425. b=bayer[x];
  426. g=bayer[x+1];
  427. g+=bayer[x+width];
  428. r=bayer[x+width+1];
  429. *udst++=(-4878*r-4789*g+14456*b+4210688)>>15;
  430. *vdst++=(14456*r-6052*g-2351*b+4210688)>>15;
  431. }
  432. bayer+=2*width;
  433. }
  434. blue_line=1;
  435. break;
  436. caseV4L2_PIX_FMT_SRGGB8:
  437. for(y=0;y<height;y+=2){
  438. for(x=0;x<width;x+=2){
  439. intb,g,r;
  440. r=bayer[x];
  441. g=bayer[x+1];
  442. g+=bayer[x+width];
  443. b=bayer[x+width+1];
  444. *udst++=(-4878*r-4789*g+14456*b+4210688)>>15;
  445. *vdst++=(14456*r-6052*g-2351*b+4210688)>>15;
  446. }
  447. bayer+=2*width;
  448. }
  449. break;
  450. caseV4L2_PIX_FMT_SGBRG8:
  451. for(y=0;y<height;y+=2){
  452. for(x=0;x<width;x+=2){
  453. intb,g,r;
  454. g=bayer[x];
  455. b=bayer[x+1];
  456. r=bayer[x+width];
  457. g+=bayer[x+width+1];
  458. *udst++=(-4878*r-4789*g+14456*b+4210688)>>15;
  459. *vdst++=(14456*r-6052*g-2351*b+4210688)>>15;
  460. }
  461. bayer+=2*width;
  462. }
  463. blue_line=1;
  464. start_with_green=1;
  465. break;
  466. caseV4L2_PIX_FMT_SGRBG8:
  467. for(y=0;y<height;y+=2){
  468. for(x=0;x<width;x+=2){
  469. intb,g,r;
  470. g=bayer[x];
  471. r=bayer[x+1];
  472. b=bayer[x+width];
  473. g+=bayer[x+width+1];
  474. *udst++=(-4878*r-4789*g+14456*b+4210688)>>15;
  475. *vdst++=(14456*r-6052*g-2351*b+4210688)>>15;
  476. }
  477. bayer+=2*width;
  478. }
  479. start_with_green=1;
  480. break;
  481. }
  482. bayer-=width*height;
  483. printf("bayeraddress(0x%p)",bayer);
  484. /*renderthefirstline*/
  485. v4lconvert_border_bayer_line_to_y(bayer,bayer+width,ydst,width,
  486. start_with_green,blue_line);
  487. ydst+=width;
  488. printf("bayeraddress(0x%p),height(%d)",bayer,height);
  489. /*reduceheightby2becauseoftheborder*/
  490. for(height-=2;height;height--){
  491. intt0,t1;
  492. /*(width-2)becauseoftheborder*/
  493. constunsignedchar*bayer_end=bayer+(width-2);
  494. if(start_with_green){
  495. t0=bayer[1]+bayer[width*2+1];
  496. /*Writefirstpixel*/
  497. t1=bayer[0]+bayer[width*2]+bayer[width+1];
  498. if(blue_line)
  499. *ydst++=(8453*bayer[width]+5516*t1+
  500. 1661*t0+524288)>>15;
  501. else
  502. *ydst++=(4226*t0+5516*t1+
  503. 3223*bayer[width]+524288)>>15;
  504. /*Writesecondpixel*/
  505. t1=bayer[width]+bayer[width+2];
  506. if(blue_line)
  507. *ydst++=(4226*t1+16594*bayer[width+1]+
  508. 1611*t0+524288)>>15;
  509. else
  510. *ydst++=(4226*t0+16594*bayer[width+1]+
  511. 1611*t1+524288)>>15;
  512. bayer++;
  513. }else{
  514. /*Writefirstpixel*/
  515. t0=bayer[0]+bayer[width*2];
  516. if(blue_line){
  517. *ydst++=(8453*bayer[width+1]+16594*bayer[width]+
  518. 1661*t0+524288)>>15;
  519. }else{
  520. *ydst++=(4226*t0+16594*bayer[width]+
  521. 3223*bayer[width+1]+524288)>>15;
  522. }
  523. }
  524. if(blue_line){
  525. for(;bayer<=bayer_end-2;bayer+=2){
  526. t0=bayer[0]+bayer[2]+bayer[width*2]+bayer[width*2+2];
  527. t1=bayer[1]+bayer[width]+bayer[width+2]+bayer[width*2+1];
  528. *ydst++=(8453*bayer[width+1]+4148*t1+
  529. 806*t0+524288)>>15;
  530. t0=bayer[2]+bayer[width*2+2];
  531. t1=bayer[width+1]+bayer[width+3];
  532. *ydst++=(4226*t1+16594*bayer[width+2]+
  533. 1611*t0+524288)>>15;
  534. }
  535. }else{
  536. for(;bayer<=bayer_end-2;bayer+=2){
  537. t0=bayer[0]+bayer[2]+bayer[width*2]+bayer[width*2+2];
  538. t1=bayer[1]+bayer[width]+bayer[width+2]+bayer[width*2+1];
  539. *ydst++=(2113*t0+4148*t1+
  540. 3223*bayer[width+1]+524288)>>15;
  541. t0=bayer[2]+bayer[width*2+2];
  542. t1=bayer[width+1]+bayer[width+3];
  543. *ydst++=(4226*t0+16594*bayer[width+2]+
  544. 1611*t1+524288)>>15;
  545. }
  546. }
  547. if(bayer<bayer_end){
  548. /*Writesecondtolastpixel*/
  549. t0=bayer[0]+bayer[2]+bayer[width*2]+bayer[width*2+2];
  550. t1=bayer[1]+bayer[width]+bayer[width+2]+bayer[width*2+1];
  551. if(blue_line)
  552. *ydst++=(8453*bayer[width+1]+4148*t1+
  553. 806*t0+524288)>>15;
  554. else
  555. *ydst++=(2113*t0+4148*t1+
  556. 3223*bayer[width+1]+524288)>>15;
  557. /*writelastpixel*/
  558. t0=bayer[2]+bayer[width*2+2];
  559. if(blue_line){
  560. *ydst++=(8453*bayer[width+1]+16594*bayer[width+2]+
  561. 1661*t0+524288)>>15;
  562. }else{
  563. *ydst++=(4226*t0+16594*bayer[width+2]+
  564. 3223*bayer[width+1]+524288)>>15;
  565. }
  566. bayer++;
  567. }else{
  568. /*writelastpixel*/
  569. t0=bayer[0]+bayer[width*2];
  570. t1=bayer[1]+bayer[width*2+1]+bayer[width];
  571. if(blue_line)
  572. *ydst++=(8453*bayer[width+1]+5516*t1+
  573. 1661*t0+524288)>>15;
  574. else
  575. *ydst++=(4226*t0+5516*t1+
  576. 3223*bayer[width+1]+524288)>>15;
  577. }
  578. /*skip2borderpixels*/
  579. bayer+=2;
  580. blue_line=!blue_line;
  581. start_with_green=!start_with_green;
  582. }
  583. /*renderthelastline*/
  584. v4lconvert_border_bayer_line_to_y(bayer+width,bayer,ydst,width,
  585. !start_with_green,!blue_line);
  586. }

##################################################################################

convert.c

##################################################################################

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #include<fcntl.h>
  5. #include<sys/stat.h>
  6. #include<linux/videodev2.h>
  7. #include"convert.h"
  8. char*g_src_file=NULL;
  9. char*g_dest_file=NULL;
  10. intg_in_width=352;
  11. intg_in_height=292;
  12. unsignedintg_src_fmt=V4L2_PIX_FMT_SGBRG8;
  13. //unsignedintg_dest_fmt=V4L2_PIX_FMT_RGB24;
  14. unsignedintg_dest_fmt=V4L2_PIX_FMT_YUV420;
  15. intprocess_cmdline(intargc,char**argv)
  16. {
  17. inti;
  18. char*tmp;
  19. for(i=1;i<argc;i++){
  20. if(strcmp(argv[i],"-s")==0){
  21. g_src_file=argv[++i];
  22. }
  23. elseif(strcmp(argv[i],"d")==0){
  24. g_dest_file=strdup(argv[++i]);
  25. }
  26. elseif(strcmp(argv[i],"-sf")==0){
  27. tmp=argv[++i];
  28. if(strlen(tmp)==4){
  29. g_src_fmt=v4l2_fourcc(tmp[0],tmp[1],tmp[2],tmp[3]);
  30. }
  31. }
  32. elseif(strcmp(argv[i],"-df")==0){
  33. tmp=argv[++i];
  34. if(strlen(tmp)==4){
  35. g_dest_fmt=v4l2_fourcc(tmp[0],tmp[1],tmp[2],tmp[3]);
  36. }
  37. }
  38. elseif(strcmp(argv[i],"iw")==0){
  39. g_in_width=atoi(argv[++i]);
  40. }
  41. elseif(strcmp(argv[i],"ih")==0){
  42. g_in_height=atoi(argv[++i]);
  43. }
  44. }
  45. if(g_src_file&&g_dest_file==NULL){
  46. g_dest_file=malloc(256);
  47. sprintf(g_dest_file,"%s.out",g_src_file);
  48. }
  49. if(g_in_width==0||g_in_height==0){
  50. }
  51. }
  52. intget_file_size(intfd)
  53. {
  54. intret;
  55. structstatsb;
  56. ret=fstat(fd,&sb);
  57. if(ret==-1){
  58. returnret;
  59. }
  60. returnsb.st_size;
  61. }
  62. intget_bits_per_pixel(unsignedintfmt)
  63. {
  64. intret;
  65. switch(fmt){
  66. caseV4L2_PIX_FMT_RGB24:
  67. ret=24;
  68. break;
  69. caseV4L2_PIX_FMT_SBGGR8:
  70. caseV4L2_PIX_FMT_SGBRG8:
  71. caseV4L2_PIX_FMT_SGRBG8:
  72. caseV4L2_PIX_FMT_SRGGB8:
  73. ret=8;
  74. break;
  75. caseV4L2_PIX_FMT_YUV420:
  76. ret=12;
  77. break;
  78. caseV4L2_PIX_FMT_YUYV:
  79. caseV4L2_PIX_FMT_UYVY:
  80. ret=16;
  81. break;
  82. default:
  83. ret=-1;
  84. break;
  85. }
  86. returnret;
  87. }
  88. voidconvert(void*src,void*dest,intwidth,intheight,unsignedintsrc_fmt,unsignedintdest_fmt)
  89. {
  90. switch(src_fmt){
  91. caseV4L2_PIX_FMT_SGBRG8:
  92. if(dest_fmt==V4L2_PIX_FMT_RGB24){
  93. v4lconvert_bayer_to_rgb24(src,dest,width,height,src_fmt);
  94. }
  95. elseif(dest_fmt==V4L2_PIX_FMT_YUV420){
  96. v4lconvert_bayer_to_yuv420(src,dest,width,height,src_fmt,0);
  97. }
  98. break;
  99. default:
  100. break;
  101. }
  102. }
  103. intmain(intargc,char*argv[])
  104. {
  105. intret=0;
  106. intfd_src=0;
  107. intfd_dest=0;
  108. intsrc_size=0;
  109. intdest_size=0;
  110. intpix_num;
  111. void*src=NULL;
  112. void*dest=NULL;
  113. process_cmdline(argc,argv);
  114. if(g_src_file==NULL||g_dest_file==NULL){
  115. ret=-1;
  116. gotobailout;
  117. }
  118. printf("inputfile(%s),outputfile(%s) ",g_src_file,g_dest_file);
  119. fd_src=open(g_src_file,O_RDONLY);
  120. if(fd_src==-1){
  121. ret=-2;
  122. gotobailout;
  123. }
  124. fd_dest=open(g_dest_file,O_RDWR|O_CREAT,0666);
  125. if(fd_dest==-1){
  126. ret=-3;
  127. gotobailout;
  128. }
  129. src_size=get_file_size(fd_src);
  130. if(src_size==-1){
  131. ret=-4;
  132. gotobailout;
  133. }
  134. pix_num=src_size/(get_bits_per_pixel(g_src_fmt)/8);
  135. //dest_size=pix_num*get_bytes_per_pixel(g_dest_fmt);
  136. ret=get_bits_per_pixel(g_dest_fmt);
  137. dest_size=pix_num*ret/8;
  138. printf("src_size(%d),dest_size(%d) ",src_size,dest_size);
  139. src=malloc(src_size);
  140. dest=malloc(dest_size);
  141. if(src==NULL||dest==NULL){
  142. ret=-5;
  143. gotobailout;
  144. }
  145. ret=read(fd_src,src,src_size);
  146. if(ret!=src_size){
  147. ret=-6;
  148. gotobailout;
  149. }
  150. convert(src,dest,g_in_width,g_in_height,g_src_fmt,g_dest_fmt);
  151. printf("writeoutfile,size=%d ",dest_size);
  152. ret=write(fd_dest,dest,dest_size);
  153. if(ret!=dest_size){
  154. ret=-1;
  155. gotobailout;
  156. }
  157. bailout:
  158. if(src)
  159. free(src);
  160. if(dest)
  161. free(dest);
  162. if(fd_src)
  163. close(fd_src);
  164. if(fd_dest)
  165. close(fd_dest);
  166. if(g_dest_file)
  167. free(g_dest_file);
  168. printf("ret(%d) ",ret);
  169. returnret;
  170. }

##################################################################################

covert.h

##################################################################################

  1. #ifndef__LIBV4LCONVERT_PRIV_H
  2. #define__LIBV4LCONVERT_PRIV_H
  3. #defineV4L2_PIX_FMT_SRGGB8v4l2_fourcc('R','G','G','B')
  4. voidv4lconvert_bayer_to_rgb24(constunsignedchar*bayer,
  5. unsignedchar*bgr,intwidth,intheight,unsignedintpixfmt);
  6. voidv4lconvert_bayer_to_bgr24(constunsignedchar*bayer,
  7. unsignedchar*bgr,intwidth,intheight,unsignedintpixfmt);
  8. voidv4lconvert_bayer_to_yuv420(constunsignedchar*bayer,unsignedchar*yuv,
  9. intwidth,intheight,unsignedintsrc_pixfmt,intyvu);
  10. #endif/*__LIBV4LCONVERT_PRIV_H*/

##################################################################################

Makefile

##################################################################################

  1. CONVERT:=convert
  2. CFLAGS:=-static
  3. CC=gcc
  4. $(CONVERT):convert.cbayer.c
  5. $(CC)-o$@$^$(CFLAGS)
  6. clean:
  7. rm-f*.o$(CONVERT)

##################################################################################

RGB32 RGB565转换为YUV444

另外为了在PC显示framebuffer中的数据,写了一个ARGB32或者RGB565到YUV444的转换工具。利用YUVtools显示YUV444图像。

其实可以不用这么麻烦,使用ddms截屏也行。

YUV444是 Y U V分量比为4:4:4,每个像素用24bits表示。

##################################################################################

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #include<fcntl.h>
  5. #include<sys/stat.h>
  6. #include<linux/videodev2.h>
  7. char*g_src_file=NULL;
  8. char*g_dest_file=NULL;
  9. intg_in_width=720;
  10. intg_in_height=480;
  11. /*V4L2_PIX_FMT_BGR32*/
  12. //unsignedintg_src_fmt=V4L2_PIX_FMT_RGB32;
  13. unsignedintg_src_fmt=V4L2_PIX_FMT_RGB565;
  14. /*V4L2_PIX_FMT_YUYVV4L2_PIX_FMT_YVYUV4L2_PIX_FMT_UYVYV4L2_PIX_FMT_VYUY*/
  15. unsignedintg_dest_fmt=V4L2_PIX_FMT_YUV444;
  16. staticunsignedcharget_R(unsignedchar*src,unsignedintfmt)
  17. {
  18. unsignedcharR;
  19. switch(fmt){
  20. caseV4L2_PIX_FMT_RGB32:
  21. caseV4L2_PIX_FMT_BGR32:
  22. caseV4L2_PIX_FMT_RGB24:
  23. R=*(src);
  24. break;
  25. caseV4L2_PIX_FMT_RGB565:
  26. R=(*(src)&0x1F)<<3;
  27. break;
  28. caseV4L2_PIX_FMT_SBGGR8:
  29. caseV4L2_PIX_FMT_SGBRG8:
  30. caseV4L2_PIX_FMT_SGRBG8:
  31. caseV4L2_PIX_FMT_YUV420:
  32. caseV4L2_PIX_FMT_YUV444:
  33. default:
  34. R=0;
  35. break;
  36. }
  37. returnR;
  38. }
  39. staticunsignedcharget_G(unsignedchar*src,unsignedintfmt)
  40. {
  41. unsignedcharG;
  42. switch(fmt){
  43. caseV4L2_PIX_FMT_RGB32:
  44. caseV4L2_PIX_FMT_BGR32:
  45. caseV4L2_PIX_FMT_RGB24:
  46. G=*(src+1);
  47. break;
  48. caseV4L2_PIX_FMT_RGB565:
  49. G=((*(src)&0xE0)>>3)|((*(src+1)&0x07)<<5);
  50. break;
  51. caseV4L2_PIX_FMT_SBGGR8:
  52. caseV4L2_PIX_FMT_SGBRG8:
  53. caseV4L2_PIX_FMT_SGRBG8:
  54. caseV4L2_PIX_FMT_YUV420:
  55. caseV4L2_PIX_FMT_YUV444:
  56. default:
  57. G=0;
  58. break;
  59. }
  60. returnG;
  61. }
  62. staticunsignedcharget_B(unsignedchar*src,unsignedintfmt)
  63. {
  64. unsignedcharB;
  65. switch(fmt){
  66. caseV4L2_PIX_FMT_RGB32:
  67. caseV4L2_PIX_FMT_BGR32:
  68. caseV4L2_PIX_FMT_RGB24:
  69. B=*(src+2);
  70. break;
  71. caseV4L2_PIX_FMT_RGB565:
  72. B=(*(src+1)&0xF8);
  73. break;
  74. caseV4L2_PIX_FMT_SBGGR8:
  75. caseV4L2_PIX_FMT_SGBRG8:
  76. caseV4L2_PIX_FMT_SGRBG8:
  77. caseV4L2_PIX_FMT_YUV420:
  78. caseV4L2_PIX_FMT_YUV444:
  79. default:
  80. B=0;
  81. break;
  82. }
  83. returnB;
  84. }
  85. rgb2yuv(char*rgb,char*yuv)
  86. {
  87. inti,j;
  88. unsignedcharR,G,B,*y,*u,*v,*alpha;
  89. doubleRR,GG,BB;
  90. unsignedchar*src,*dest;
  91. for(i=0;i<g_in_height;i++){
  92. for(j=0;j<g_in_width;j++){
  93. src=rgb+(i*g_in_width+j)*get_bpp(g_src_fmt)/8;
  94. dest=yuv+(i*g_in_width+j)*get_bpp(g_dest_fmt)/8;
  95. R=get_R(src,g_src_fmt);
  96. G=get_G(src,g_src_fmt);
  97. B=get_B(src,g_src_fmt);
  98. /*normalizeto16..235*/
  99. RR=219*R/255+16;
  100. GG=219*G/255+16;
  101. BB=219*B/255+16;
  102. y=dest;
  103. u=dest+1;
  104. v=dest+2;
  105. //alpha=dest+3;
  106. *y=(unsignedchar)(0.2991*RR+0.5849*GG+0.1159*BB+0.5);
  107. *u=(unsignedchar)(-0.1725*RR-0.3372*GG+0.5097*BB+128.5);
  108. *v=(unsignedchar)(0.5097*RR-0.4254*GG-0.0843*BB+128.5);
  109. //*alpha=255;
  110. }
  111. }
  112. }
  113. intprocess_cmdline(intargc,char**argv)
  114. {
  115. inti;
  116. char*tmp;
  117. for(i=1;i<argc;i++){
  118. if(strcmp(argv[i],"-s")==0){
  119. g_src_file=argv[++i];
  120. }
  121. elseif(strcmp(argv[i],"-d")==0){
  122. g_dest_file=strdup(argv[++i]);
  123. }
  124. elseif(strcmp(argv[i],"-sf")==0){
  125. tmp=argv[++i];
  126. if(strlen(tmp)==4){
  127. g_src_fmt=v4l2_fourcc(tmp[0],tmp[1],tmp[2],tmp[3]);
  128. }
  129. }
  130. elseif(strcmp(argv[i],"-df")==0){
  131. tmp=argv[++i];
  132. if(strlen(tmp)==4){
  133. g_dest_fmt=v4l2_fourcc(tmp[0],tmp[1],tmp[2],tmp[3]);
  134. }
  135. }
  136. elseif(strcmp(argv[i],"iw")==0){
  137. g_in_width=atoi(argv[++i]);
  138. }
  139. elseif(strcmp(argv[i],"ih")==0){
  140. g_in_height=atoi(argv[++i]);
  141. }
  142. }
  143. if(g_src_file&&g_dest_file==NULL){
  144. g_dest_file=malloc(256);
  145. sprintf(g_dest_file,"%s.out",g_src_file);
  146. }
  147. if(g_in_width==0||g_in_height==0){
  148. }
  149. }
  150. intget_bpp(unsignedintfmt)
  151. {
  152. intret;
  153. switch(fmt){
  154. caseV4L2_PIX_FMT_RGB32:
  155. caseV4L2_PIX_FMT_BGR32:
  156. ret=32;
  157. break;
  158. caseV4L2_PIX_FMT_RGB24:
  159. ret=24;
  160. break;
  161. caseV4L2_PIX_FMT_RGB565:
  162. ret=16;
  163. break;
  164. caseV4L2_PIX_FMT_SBGGR8:
  165. caseV4L2_PIX_FMT_SGBRG8:
  166. caseV4L2_PIX_FMT_SGRBG8:
  167. ret=8;
  168. break;
  169. caseV4L2_PIX_FMT_YUV420:
  170. ret=12;
  171. break;
  172. caseV4L2_PIX_FMT_YUYV:
  173. caseV4L2_PIX_FMT_UYVY:
  174. ret=16;
  175. break;
  176. caseV4L2_PIX_FMT_YUV444:
  177. ret=24;
  178. break;
  179. default:
  180. ret=-1;
  181. break;
  182. }
  183. returnret;
  184. }
  185. main(intargc,char*argv[])
  186. {
  187. intret;
  188. intsrc_fd,dest_fd;
  189. intsrc_size,dest_size;
  190. char*src_buf;
  191. char*dest_buf;
  192. process_cmdline(argc,argv);
  193. if(g_src_file==NULL||g_dest_file==NULL){
  194. ret=-1;
  195. gotobailout;
  196. }
  197. src_fd=open(g_src_file,O_RDONLY);
  198. if(src_fd==-1){
  199. ret=-2;
  200. gotobailout;
  201. }
  202. dest_fd=open(g_dest_file,O_RDWR|O_CREAT,0666);
  203. if(dest_fd==-1){
  204. ret=-3;
  205. gotobailout;
  206. }
  207. src_size=g_in_width*g_in_height*get_bpp(g_src_fmt)/8;
  208. dest_size=g_in_width*g_in_height*get_bpp(g_dest_fmt)/8;
  209. src_buf=malloc(src_size);
  210. dest_buf=malloc(dest_size);
  211. ret=read(src_fd,src_buf,src_size);
  212. if(ret!=src_size){
  213. printf("src_size=%d,ret=%d ",src_size,ret);
  214. ret=-4;
  215. gotobailout;
  216. }
  217. rgb2yuv(src_buf,dest_buf);
  218. printf("writeoutfile,size=%d ",dest_size);
  219. ret=write(dest_fd,dest_buf,dest_size);
  220. if(ret!=dest_size){
  221. ret=-5;
  222. gotobailout;
  223. }
  224. bailout:
  225. printf("ret(%d) ",ret);
  226. returnret;
  227. }

##################################################################################

免责声明:文章转载自《bayer, yuv, RGB转换方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇关于Java类Calendar做统计时 获取日期的一些常见操作IDEA及IDEA汉化包下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

[Python之路] 使用epoll实现高并发HTTP服务器

什么是epoll 我们在  Python多种方式实现并发的Web Server 的最后使用单进程+单线程+非阻塞+长连接实现了一个可并发处理客户端连接的服务器。他的原理可以用以下的图来描述: 解释: 1.HTTP服务器是我们使用 单进程+单线程+非阻塞+长连接实现 的web服务器。 2.在实现的时候,我们创建了一个存放已接受Socket连接的列表,该列表...

Node.js 文件系统

Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。 Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。 异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。 建议大家使用异...

颜色空间模型 与 Opencv中的HSV模型范围

颜色空间总结 RGB、HSV、YUV 什么是颜色 Wiki是这样说的:颜色或色彩是通过眼、脑和我们的生活经验所产生的一种对光的视觉效应。嗯,简单点说,颜色就是人对光的一种感觉,由大脑产生的一种感觉。感觉是一个很主观的东西,你怎么确定你看到的红色和我看到的是一样的呢?这个视频解释的很不错。我们需要先假设正常人对于同一种光产生的感觉基本是一致的,讨论才能继...

free命令常用参数详解及常用内存工具介绍

       free命令常用参数详解及常用内存工具介绍                        作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。    一.内存空间使用状态 1>."-b"参数(以字节为单位显示内存使用情况) [root@node101.yinzhengjie.org.cn ~]# free -b...

【646】灰度图array转为RGB三通道array

  两种方法可以实现: 通过 numpy 自己实现 通过 cv2.cvtColor 函数实现,灰度图转 RGB   所谓的灰度图转为三通道,就是三个通道都是一样的信息,相当于相同维度信息的重复,主要是通过 numpy.array 来实现,其实是可以通过类似广播的形式来实现。 1. 每一行赋值相同的内容 >>> a = np.zeros...

LaravelS

LaravelS LaravelS是一个胶水项目,用于快速集成Swoole到Laravel或Lumen,然后赋予它们更好的性能、更多可能性。Github 特性 内置Http/WebSocket服务器 多端口混合协议 协程 自定义进程 常驻内存 异步的事件监听 异步的任务队列 毫秒级定时任务 平滑Reload 修改代码后自动Reload 同时支持Lar...