(C++)本文介绍Baumer堡盟工业相机BGAPI SDK联合OpenCV进行Bayer图像转换
Bayer像素格式
Bayer像素格式广泛用于CCD和CMOS相机。采用Bayer格式,可以从一个单独的平面得到彩色图像,该平面上的R、G和B像素点(即特定分量的传感器)交错排列(如左图所示)。
对于单个像素,输出的RGB分量是由该像素周围具有相同颜色的1个、2个或4个相邻像素进行插值得到的。Bayer阵列可以通过向左和/或向上平移一个像素来进行修改。转换常数CV_Bayer C1C2 2BGR和CV_Bayer C1C2 2RGB中的C1和C2两个字母代表特定的阵列类型,分别是第二行、第二列和第三列的颜色分量。例如,阵列中有一个很常用的“BG”类型。
使用cvtColor的OpenCV颜色转换
彩色相机支持BayerBG8、BayerGB8、BayerGR8和BayerRG8等原始像素格式。
如需进一步进行图像处理,必须将这些格式转换为BGR8格式。
堡盟相机根据图像第一行的前两个像素给Bayer阵列命名。而OpenCV则根据图像第二行的第二和第三个像素给阵列命名,因此命名方式有所不同,对应关系如下:
堡盟相机的BayerGB对应OpenCV的BayerGR
堡盟相机的BayerRG对应OpenCV的BayerBG
堡盟相机的BayerGR对应OpenCV的BayerGB
堡盟相机的BayerBG对应OpenCV的BayerRG
pDevice->GetRemoteNode("PixelFormat")->SetString("BayerRG8"); BGAPI2::Buffer * pBufferFilled = pDataStream->GetFilledBuffer(1000); if (pBufferFilled->GetPixelFormat() == "BayerRG8") { cv::Mat* imOriginal = new cv::Mat((int)pBufferFilled->GetHeight(), (int)pBufferFilled->GetWidth(), CV_8UC1, (char *)pBufferFilled->GetMemPtr(); cv::Mat* imTransformBGR8 = new cv::Mat((int)pBufferFilled->GetHeight(), (int)pBufferFilled->GetWidth(), CV_8UC3); //Baumer: RGrgrg >> OpenCV: rgrgrg // gbgbgb gBGbgb cv::cvtColor(*imOriginal, *imTransformBGR8, CV_BayerBG2BGR); //to BGR delete imOriginal; pBufferFilled->QueueBuffer(); cv::imwrite("cv_BayerRG8_as_BGR8_image.png", *imTransformBGR8); delete imTransformBGR8; }
将Bayer格式转换为BGR16
BayerBG12、BayerGB12、BayerGR12和BayerRG12等其他原始像素格式在Bayer图像中使用更多位数。首先需要将这些原始数据从12位转换为16位。之后,可以通过cvtColor将16位Bayer格式转换为48位BGR16格式(每个颜色通道为16位)。
对于BayerBG10、BayerGB10、BayerGR10或BayerRG10等10位Bayer格式,在将其转换为16位Bayer格式时,比例因子应选取64.0而非16.0。
pDevice->GetRemoteNode("PixelFormat")->SetString("BayerGB12"); BGAPI2::Buffer * pBufferFilled = pDataStream->GetFilledBuffer(1000); if (pBufferFilled->GetPixelFormat() == "BayerGB12") { cv::Mat* imOriginal = new cv::Mat((int)pBufferFilled->GetHeight(), (int)pBufferFilled->GetWidth(), CV_16UC1, (char *)pBufferFilled->GetMemPtr(); cv::Mat* imConvert = new cv::Mat((int)pBufferFilled->GetHeight(), (int)pBufferFilled->GetWidth(), CV_16UC1); //convert with scaling of 16.0 to convert 12-Bit to 16-Bit imOriginal->convertTo(*imConvert, CV_16UC1, 16.0); delete imOriginal; pBufferFilled->QueueBuffer(); cv::Mat* imTransformBGR16 = new cv::Mat((int)pBufferFilled->GetHeight(), (int)pBufferFilled->GetWidth(), CV_16UC3); //Baumer: GBgbgb >> OpenCV: gbgbgb // rgrgrg rGRgrg cv::cvtColor(*imConvert, *imTransformBGR16, CV_BayerGR2BGR); //to BGR delete imConvert; cv::imwrite("cv_BayerGB12_as_BGR16_image.png", *imTransformBGR16); delete imTransformBGR16; }