我正在尝试使用OpenCV 2.3.1将12位拜耳图像转换为8位RGB图像.这似乎应该使用cvCvtColor函数相当简单,但是当我用这段代码调用它时函数抛出一个异常:
int cvType = CV_MAKETYPE(CV_16U, 1);
cv::Mat bayerSource(height, width, cvType, sourceBuffer);
cv::Mat rgbDest(height, width, CV_8UC3);
cvCvtColor(&bayerSource, &rgbDest, CV_BayerBG2RGB);
Run Code Online (Sandbox Code Playgroud)
我以为我跑过sourceBuffer的末尾,因为输入数据是12位,我必须传入一个16位类型,因为OpenCV没有12位类型.所以我将宽度和高度除以2,但是cvCvtColor仍然抛出了一个没有任何有用信息的异常(错误消息是"Unknown exception").
几个月前发布的一个类似的问题从未得到解答,但由于我的问题更具体地涉及12位拜耳数据,我认为它足够独特,值得一个新问题.
提前致谢.
编辑:我必须遗漏一些东西,因为我甚至无法使用cvCvtColor函数来处理8位数据:
cv::Mat srcMat(100, 100, CV_8UC3);
const cv::Scalar val(255,0,0);
srcMat.setTo(val);
cv::Mat destMat(100, 100, CV_8UC3);
cvCvtColor(&srcMat, &destMat, CV_RGB2BGR);
Run Code Online (Sandbox Code Playgroud)
Gil*_*ish 14
我能够使用以下代码将我的数据转换为8位RGB:
// Copy the data into an OpenCV Mat structure
cv::Mat bayer16BitMat(height, width, CV_16UC1, inputBuffer);
// Convert the Bayer data from 16-bit to to 8-bit
cv::Mat bayer8BitMat = bayer16BitMat.clone();
// The 3rd parameter here scales the data by 1/16 so that it fits in 8 bits.
// Without it, convertTo() just seems to chop off the high order bits.
bayer8BitMat.convertTo(bayer8BitMat, CV_8UC1, 0.0625);
// Convert the Bayer data to 8-bit RGB
cv::Mat rgb8BitMat(height, width, CV_8UC3);
cv::cvtColor(bayer8Bit, rgb8BitMat, CV_BayerGR2RGB);
Run Code Online (Sandbox Code Playgroud)
我错误地认为我从相机获得的12位数据是紧密打包的,所以两个12位值包含在3个字节中.事实证明,每个值都包含在2个字节中,因此我不必进行任何解包以将我的数据转换为OpenCV支持的16位数组.
编辑:请参阅@ petr在转换为8位之前转换为RGB的改进答案,以避免在转换过程中丢失任何颜色信息.
Gillfish 的答案在技术上有效,但在转换期间它使用比输入(CV_16UC1)更小的数据结构(CV_8UC1)并丢失一些颜色信息。
我建议首先解码拜耳编码,但保持每通道 16 位(从 CV_16UC1 到 CV_16UC3),然后转换为 CV_8UC3。
修改后的 Gillfish 的代码(假设相机以 16 位拜耳编码给出图像):
// Copy the data into an OpenCV Mat structure
cv::Mat mat16uc1_bayer(height, width, CV_16UC1, inputBuffer);
// Decode the Bayer data to RGB but keep using 16 bits per channel
cv::Mat mat16uc3_rgb(width, height, CV_16UC3);
cv::cvtColor(mat16uc1_bayer, mat16uc3_rgb, cv::COLOR_BayerGR2RGB);
// Convert the 16-bit per channel RGB image to 8-bit per channel
cv::Mat mat8uc3_rgb(width, height, CV_8UC3);
mat16uc3_rgb.convertTo(mat8uc3_rgb, CV_8UC3, 1.0/256); //this could be perhaps done more effectively by cropping bits
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
29253 次 |
| 最近记录: |