【问题标题】:iOS OpenCV cvtColor unknown array type erroriOS OpenCV cvtColor 未知数组类型错误
【发布时间】:2015-05-18 12:45:55
【问题描述】:

我从 iOS 上的 OpenCV 开始,我想要实现的第一件事是将彩色图像转换为灰色图像。

我的第一次尝试成功了

我正在获取带有“CV_8UC1”选项的 Mat,然后将其转换回图像。

代码如下:

UIImage *image = [UIImage imageNamed:kImageName];

image = [UIImage greyedImage:image];

[imageView setImage:image];

+ (UIImage*)greyedImage:(UIImage*)image
{
    return [UIImage imageFromMat:[image toGrayMat]];
}


+ (UIImage*)imageFromMat:(cv::Mat)cvMat
{
    NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
CGColorSpaceRef colorSpace;

if (cvMat.elemSize() == 1) {
    colorSpace = CGColorSpaceCreateDeviceGray();
} else {
    colorSpace = CGColorSpaceCreateDeviceRGB();
}

CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

// Creating CGImage from cv::Mat
CGImageRef imageRef = CGImageCreate(cvMat.cols,                                 //width
                                    cvMat.rows,                                 //height
                                    8,                                          //bits per component
                                    8 * cvMat.elemSize(),                       //bits per pixel
                                    cvMat.step[0],                            //bytesPerRow
                                    colorSpace,                                 //colorspace
                                    kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
                                    provider,                                   //CGDataProviderRef
                                    NULL,                                       //decode
                                    false,                                      //should interpolate
                                    kCGRenderingIntentDefault                   //intent
                                    );


// Getting UIImage from CGImage
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);

return finalImage;

}

- (cv::Mat)toGrayMat
{
    cv::Mat tmp = [self toMatWithChannelOption:CV_8UC1];

    //cvCvtColor(&tmp, &tmp, CV_BGR2GRAY);

    return tmp;
}

- (cv::Mat)toMatWithChannelOption:(int)channelOption
{
    CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage);
    CGFloat cols = self.size.width;
    CGFloat rows = self.size.height;

    cv::Mat cvMat(rows, cols, channelOption); // 8 bits per component, 4 channels (color channels + alpha)

    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,                 // Pointer to  data
                                                    cols,                       // Width of bitmap
                                                    rows,                       // Height of bitmap
                                                    8,                          // Bits per component
                                                    cvMat.step[0],              // Bytes per row
                                                    colorSpace,                 // Colorspace
                                                    kCGImageAlphaNoneSkipLast |
                                                    kCGBitmapByteOrderDefault); // Bitmap info flags

    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), self.CGImage);
    CGContextRelease(contextRef);

    return cvMat;

}

但它导致了这个错误

"CGBitmapContextCreate:不支持的参数组合:8个整数位/分量;32位/像素;3分量颜色空间;kCGImageAlphaNoneSkipLast;610字节/行。 5 月 18 日 15:32:23 MacBook-Air.local 测试 [12677]:CGContextDrawImage:无效上下文 0x0。这是一个严重的错误。此应用程序或它使用的库正在使用无效的上下文,从而导致系统稳定性和可靠性的整体下降。此通知是出于礼貌:请解决此问题。这将成为即将到来的更新中的致命错误。”

之后我尝试像这样使用 cvtColor:

- (cv::Mat)toGrayMat
{
    cv::Mat tmp = [self toMatWithChannelOption:CV_8UC4];

    cvCvtColor(&tmp, &tmp, CV_BGRA2GRAY);

    return tmp;
}

但知道我明白了

“函数 cvarrToMat 中的未知数组类型”.. 它告诉我传递给 cvtColor 的参数不正确。

请提出可能的原因。

附言我在很多问题中观察到其他人将该函数称为“cvtColor”,而我只能将其编写为 cvCvtColor,否则 Xcode 会更正它并强制我将“&”放在 mat 函数属性之前。

我的导入:“opencv2/imgproc/imgproc_c.h” iOS:8+

【问题讨论】:

    标签: c++ ios objective-c opencv


    【解决方案1】:

    使用cvCvtColorCV_BGRA2GRAY 作为参数将彩色图像转换为灰度图像。其中每一个都是不同类型的Mat。彩色图像有 4 个通道(例如 CV_8UC4),灰度有一个通道(例如 CV_8UC1)。因此,为输入和输出声明单独的参数。示例如下。

    #include "opencv2/opencv.hpp"
    cv::Mat gray;
    cv::Mat tmp = [self toMatWithChannelOption:CV_8UC4];
    cv::cvtColor( tmp, gray, CV_BGRA2GRAY );
    

    注意 a) 避免使用 cvCvtColor,因为它是已弃用的 C API (1) 的一部分。而是使用cvtColor。 b) 避免使用标题imgproc_c.h。它仅出于兼容性原因而提供。而是使用imgproc.hpp 或简单地使用opencv.hpp

    【讨论】:

    • 谢谢你的详细解释,真的很困惑导入什么,什么数据类型..如何使用它..希望OpenCV官方教程有更详细的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-07
    • 1970-01-01
    • 2020-09-27
    • 2017-08-19
    • 2017-03-02
    • 2012-01-05
    相关资源
    最近更新 更多