Bayer8转RGB并用OpenCV显示

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/oHanTanYanYing/article/details/81945479

最近做项目用到工业摄像头,其输出最小的数据流是Bayer8,因为带宽有限,只好选用之。

在获得数据后,解析成了比较要命的问题,因为ffmpeg等比较简单的工具没有该格式对其他格式的装换,因此只能自行实现。在这里万分感谢下面这个博客

https://blog.csdn.net/leng_que/article/details/5961436

本人基本上是按照该博客修改出了自己能用的版本(直接照抄会有些变量未定义的问题),下面也分享出来吧。

BayerToRGB.h


 
 
  1. //原作者:Vojtech Pavlik
  2. //2010-10-23 23:25:16 冷却 整理、封装以及测试
  3. #pragma once
  4. typedef unsigned char uint8_t;
  5. typedef unsigned short uint16_t;
  6. #define u8 uint8_t
  7. #define R(x,y) m_pRGB24[2 + 3 * ((x) + m_ulWidth * (y))]
  8. #define G(x,y) m_pRGB24[1 + 3 * ((x) + m_ulWidth * (y))]
  9. #define B(x,y) m_pRGB24[0 + 3 * ((x) + m_ulWidth * (y))]
  10. #define Bay(x,y) m_pBay[(x) + m_ulWidth * (y)]
  11. class BayerToRGB
  12. {
  13. public:
  14. BayerToRGB();
  15. public:
  16. //函数名称:Bayer8ToRgb24
  17. //描述:将8位Bayer原始数据转换为24位RGB格式数据
  18. //注意:该函数不可重入
  19. /*
  20. * 要求的Bayer数据排列格式如下(GBRG):
  21. *
  22. * G B G B G B G B...
  23. * R G R G R G R G...
  24. * G B G B G B G B...
  25. * R G R G R G R G...
  26. * G B G B G B G B...
  27. * R G R G R G R G...
  28. * G B G B G B G B...
  29. * R G R G R G R G...
  30. * ..................
  31. * ..................
  32. */
  33. static int Bayer8ToRgb24(unsigned char* pbBayer, int dwWidth, int dwHeight, unsigned char* pbRgb, int iRgbBufLen);
  34. protected:
  35. int ExecBayer8ToRgb24(unsigned char* pbBayer, int dwWidth, int dwHeight, unsigned char* pbRgb, int iRgbBufLen);
  36. private:
  37. unsigned long m_ulWidth;
  38. unsigned long m_ulHeight;
  39. u8 *m_pBay;
  40. u8 *m_pRGB24;
  41. private:
  42. void bayer_copy(int x, int y);
  43. void bayer_bilinear(int x, int y);
  44. void bayer_to_rgb24();
  45. };

BayerToRGB.cpp


 
 
  1. #include "stdafx.h"
  2. #include "BayerToRGB.h"
  3. #pragma warning(disable: 4244)
  4. #pragma warning(disable: 4018)
  5. BayerToRGB::BayerToRGB()
  6. {
  7. m_ulWidth = 0;
  8. m_ulHeight = 0;
  9. m_pBay = NULL;
  10. m_pRGB24 = NULL;
  11. }
  12. int BayerToRGB::Bayer8ToRgb24( unsigned char * pbBayer, int dwWidth, int dwHeight, unsigned char* pbRgb, int iRgbBufLen)
  13. {
  14. BayerToRGB cPixelFormatConvert;
  15. return cPixelFormatConvert.ExecBayer8ToRgb24(pbBayer, dwWidth, dwHeight, pbRgb, iRgbBufLen);
  16. return 0;
  17. }
  18. int BayerToRGB::ExecBayer8ToRgb24( unsigned char * pbBayer, int dwWidth, int dwHeight, unsigned char* pbRgb, int iRgbBufLen)
  19. {
  20. if ( NULL == pbBayer || NULL == pbRgb)
  21. {
  22. return 0;
  23. }
  24. if (dwWidth <= 0 || dwHeight <= 0 || iRgbBufLen <= 0)
  25. {
  26. return 0;
  27. }
  28. if (iRgbBufLen != dwWidth * dwHeight * 3)
  29. {
  30. return 0;
  31. }
  32. m_pBay = pbBayer;
  33. m_pRGB24 = pbRgb;
  34. m_ulWidth = dwWidth;
  35. m_ulHeight = dwHeight;
  36. bayer_to_rgb24();
  37. return 1;
  38. }
  39. void BayerToRGB::bayer_copy( int x, int y)
  40. {
  41. G(x + 0, y + 0) = Bay(x + 0, y + 0);
  42. G(x + 1, y + 1) = Bay(x + 1, y + 1);
  43. G(x + 0, y + 1) = G(x + 1, y + 0) = (( unsigned long)Bay(x + 0, y + 0) + ( unsigned long)Bay(x + 1, y + 1)) / 2;
  44. R(x + 0, y + 0) = R(x + 1, y + 0) = R(x + 1, y + 1) = R(x + 0, y + 1) = Bay(x + 0, y + 1);
  45. B(x + 1, y + 1) = B(x + 0, y + 0) = B(x + 0, y + 1) = B(x + 1, y + 0) = Bay(x + 1, y + 0);
  46. }
  47. void BayerToRGB::bayer_bilinear( int x, int y)
  48. {
  49. R(x + 0, y + 0) = (( unsigned long)Bay(x + 0, y + 1) + ( unsigned long)Bay(x + 0, y - 1)) / 2;
  50. G(x + 0, y + 0) = Bay(x + 0, y + 0);
  51. B(x + 0, y + 0) = (( unsigned long)Bay(x - 1, y + 0) + ( unsigned long)Bay(x + 1, y + 0)) / 2;
  52. R(x + 0, y + 1) = Bay(x + 0, y + 1);
  53. G(x + 0, y + 1) = (( unsigned long)Bay(x + 0, y + 0) + ( unsigned long)Bay(x + 0, y + 2) + ( unsigned long)Bay(x - 1, y + 1) + ( unsigned long)Bay(x + 1, y + 1)) / 4;
  54. B(x + 0, y + 1) = (( unsigned long)Bay(x + 1, y + 0) + ( unsigned long)Bay(x - 1, y + 0) + ( unsigned long)Bay(x + 1, y + 2) + ( unsigned long)Bay(x - 1, y + 2)) / 4;
  55. R(x + 1, y + 0) = (( unsigned long)Bay(x + 0, y + 1) + ( unsigned long)Bay(x + 2, y + 1) + ( unsigned long)Bay(x + 0, y - 1) + ( unsigned long)Bay(x + 2, y - 1)) / 4;
  56. G(x + 1, y + 0) = (( unsigned long)Bay(x + 0, y + 0) + ( unsigned long)Bay(x + 2, y + 0) + ( unsigned long)Bay(x + 1, y - 1) + ( unsigned long)Bay(x + 1, y + 1)) / 4;
  57. B(x + 1, y + 0) = Bay(x + 1, y + 0);
  58. R(x + 1, y + 1) = (( unsigned long)Bay(x + 0, y + 1) + ( unsigned long)Bay(x + 2, y + 1)) / 2;
  59. G(x + 1, y + 1) = Bay(x + 1, y + 1);
  60. B(x + 1, y + 1) = (( unsigned long)Bay(x + 1, y + 0) + ( unsigned long)Bay(x + 1, y + 2)) / 2;
  61. }
  62. void BayerToRGB::bayer_to_rgb24()
  63. {
  64. int i, j;
  65. for (i = 0; i < m_ulWidth; i += 2)
  66. {
  67. for (j = 0; j < m_ulHeight; j += 2)
  68. {
  69. if (i == 0 || j == 0 || i == m_ulWidth - 2 || j == m_ulHeight - 2)
  70. {
  71. bayer_copy(i, j);
  72. }
  73. else
  74. {
  75. bayer_bilinear(i, j);
  76. }
  77. }
  78. }
  79. }

使用(需要注意本人从摄像头获取到的数据第一行是RGRG,所以做了相应的修改,也就是扔掉了第一行。。。):


 
 
  1. #include "ffmpegDecode.hpp"
  2. #include <opencv2/core/core.hpp>//OpenCV包含头文件
  3. #include <opencv2/highgui/highgui.hpp>
  4. #include <opencv2/opencv.hpp>
  5. #include <iostream>
  6. #include "BayerToRGB.h"
  7. #define IMGLEN 691200
  8. using namespace std;
  9. using namespace cv;
  10. char imgdata[IMGLEN];
  11. void main()
  12. {
  13. FILE *PF;
  14. fopen_s(&PF, "1.save", "rb");
  15. fread(imgdata, 1, IMGLEN, PF);
  16. fclose(PF);
  17. Mat img(720, 960, CV_8UC3,Scalar(0,0,0));
  18. //bayer8 转 RGB
  19. /* 要求的Bayer数据排列格式如下(注意排列的不同):
  20. * R G R G R G R G...
  21. * G B G B G B G B...
  22. * R G R G R G R G...
  23. * G B G B G B G B...
  24. * R G R G R G R G...
  25. * G B G B G B G B...
  26. * R G R G R G R G...
  27. */
  28. double t = ( double)cvGetTickCount();
  29. BayerToRGB::Bayer8ToRgb24((uchar*)(&imgdata[ 960]), 960, 719, img.data, img.step* 719);
  30. cout << "花费时间" << (( double)cvGetTickCount() - t) / (( double)cvGetTickFrequency() * 1000) << "ms" << endl;
  31. imshow( "", img);
  32. waitKey();
  33. img.release();
  34. }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值