OpenCV: 颜色空间转换 cvtColor()出错
先看iOS
代码
+ (UIImage *)convertImage:(UIImage *)image{
Mat input, result;
UIImageToMat(image, input);
// 转换通道
if (input.channels() == 4) {
cv::cvtColor(input, input, CV_BGRA2GRAY);
} else {
cv::cvtColor(input, input, CV_BGR2GRAY);
}
// ... 省略处理input 得到 result
result = sdk.scan(input);
UIImage *output = MatToUIImage(result);
return output;
}
上面的代码在转换颜色通道的时候,出现问题. 调用int cv::Mat::channels()得到的数值,可能是 1-4
, 也就是说代码中缺少 1 和 2的判断if
分支.
具体的崩溃原因是:
// 单通道的图片, 再次调用该处理方法就会崩溃
cv::cvtColor(input, input, CV_BGR2GRAY)
那么修改后的代码
// 转换单通道
if (input.channels() == 4) {
cv::cvtColor(input, input, CV_BGRA2GRAY);
} else if (input.channels() == 3) {
cv::cvtColor(input, input, CV_BGR2GRAY);
} else if(input.channels() == 2) {
cv::cvtColor(input,input,CV_BGR5652GRAY);
} else if(input.channels() == 1) {// 单通道的图片直接就不需要处理
return image;
} else { // 负数,说明图有问题 直接返回
return image;
}
有关颜色通道
- 1通道的是灰度图。
- 2通道的图像是RGB555和RGB565。2通道图在程序处理中会用到,如傅里叶变换,可能会用到,一个通道为实数,一个通道为虚数,主要是编程方便。RGB555是16位的,2个字节,5+6+5,第一字节的前5位是R,后三位+第二字节是G,第二字节后5位是B,可见对原图像进行压缩了。
- 3通道的是彩色图像,比如RGB图像。
- 4通道的图像是RGBA,是RGB加上一个A通道,也叫alpha通道,表示透明度。PNG图像是一种典型的4通道图像。alpha通道可以赋值0到1,或者0到255,表示透明到不透明。