正在加载今日诗词....
2 min read

OpenCV: 颜色空间转换 cvtColor()出错

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 , 也就是说代码中缺少 12的判断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,表示透明到不透明。

参考