【问题标题】:OpenCV iOS - Unsupported Parameter CombinationOpenCV iOS - 不支持的参数组合
【发布时间】:2015-11-09 20:58:56
【问题描述】:

我正在使用 OpenCV 来测试图像操作。但是使用以下方法会导致错误,我无法向自己解释。

- (cv::Mat)cvMatGrayFromUIImage:(UIImage *)image
{
    CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
    CGFloat cols = image.size.width;
    CGFloat rows = image.size.height;

    cv::Mat cvMat = cv::Mat(rows, cols, CV_8UC1); // 8 bits per component, 1 channel

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

    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
    CGContextRelease(contextRef);
    CGColorSpaceRelease(colorSpace);

    return cvMat;
}

当我运行这个方法时,我会在 xcode 控制台中得到以下输出

Aug 17 11:14:24  OpenCVDemo[1250] <Error>: CGBitmapContextCreate: unsupported parameter combination: set CGBITMAP_CONTEXT_LOG_ERRORS environmental variable to see the details
Aug 17 11:14:24  OpenCVDemo[1250] <Error>: CGContextDrawImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

例如这里有一个方法,它工作正常。

- (cv::Mat)cvMat3ChannelFromUIImage:(UIImage *)image
{

    CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
    CGFloat cols = image.size.width;
    CGFloat rows = image.size.height;

    cv::Mat rgba(rows, cols, CV_8UC4, cvScalar(1,2,3,4)); // 8 bits per component, 4 channels

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

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

    cv::Mat bgr( rgba.rows, rgba.cols, CV_8UC3 );
    cv::Mat alpha( rgba.rows, rgba.cols, CV_8UC1 );

    cv::Mat out[] = { bgr, alpha };
    // rgba[0] -> bgr[2], rgba[1] -> bgr[1],
    // rgba[2] -> bgr[0], rgba[3] -> alpha[0]
    int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
    mixChannels( &rgba, 1, out, 2, from_to, 4 );

    return bgr;
}

我希望有人能解释一下为什么灰色方法不起作用。

【问题讨论】:

    标签: c++ ios objective-c xcode opencv


    【解决方案1】:

    //矩阵转换

    + (cv::Mat)cvMatFromUIImage:(UIImage *)image
    {
    CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
    CGFloat cols,rows;
    if  (image.imageOrientation == UIImageOrientationLeft
         || image.imageOrientation == UIImageOrientationRight) {
        cols = image.size.height;
        rows = image.size.width;
    }
    else{
        cols = image.size.width;
        rows = image.size.height;
    
    }
    
    
    cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels
    
    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,                 // Pointer to backing data
                                                    cols,                       // Width of bitmap
                                                    rows,                       // Height of bitmap
                                                    8,                          // Bits per component
                                                    cvMat.step[0],              // Bytes per row
                                                    colorSpace,                 // Colorspace
                                                    kCGImageAlphaNoneSkipLast |
                                                    kCGBitmapByteOrderDefault);
    
    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
    CGContextRelease(contextRef);
    
    
    cv::Mat cvMatTest;
    cv::transpose(cvMat, cvMatTest);
    
    if  (image.imageOrientation == UIImageOrientationLeft
         || image.imageOrientation == UIImageOrientationRight) {
    
    }
    else{
        return cvMat;
    
    }
    cvMat.release();
    
    cv::flip(cvMatTest, cvMatTest, 1);
    
    
    return cvMatTest;
    }
    

    //灰度转换

    + (cv::Mat)cvMatGrayFromUIImage:(UIImage *)image
    {
    cv::Mat cvMat = [self cvMatFromUIImage:image];
    cv::Mat grayMat;
    if ( cvMat.channels() == 1 ) {
        grayMat = cvMat;
    }
    else {
        grayMat = cv :: Mat( cvMat.rows,cvMat.cols, CV_8UC1 );
        cv::cvtColor( cvMat, grayMat, CV_BGR2GRAY );
    }
    return grayMat;
    }
    

    //调用上述方法

    cv::Mat grayImage = [self cvMatGrayFromUIImage:"your image"];

    【讨论】:

    • 当 OP 要求解释时,我投了反对票,但您只提供了可能正确的代码,这对理解问题没有帮助。
    【解决方案2】:
    - (cv::Mat)cvMat3ChannelFromUIImage:(UIImage *)image
    {
    
        UIImage *theImage = [UIImage imageWithData:UIImagePNGRepresentation(image)];
        CGColorSpaceRef colorSpace = CGImageGetColorSpace(theImage.CGImage);
        CGFloat cols = theImage.size.width;
        CGFloat rows = theImage.size.height;
    
        cv::Mat rgba(rows, cols, CV_8UC4, cvScalar(1,2,3,4)); // 8 bits per component, 4 channels
    
        CGContextRef contextRef = CGBitmapContextCreate(rgba.data,                 // Pointer to backing data
                                                        cols,                      // Width of bitmap
                                                        rows,                     // Height of bitmap
                                                        8,                          // Bits per component
                                                        rgba.step[0],              // Bytes per row
                                                        colorSpace,                 // Colorspace
                                                        kCGImageAlphaNoneSkipLast |
                                                        kCGBitmapByteOrderDefault); // Bitmap info flags
    
        CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), theImage.CGImage);
        CGContextRelease(contextRef);
    
        cv::Mat bgr( rgba.rows, rgba.cols, CV_8UC3 );
        cv::Mat alpha( rgba.rows, rgba.cols, CV_8UC1 );
    
        cv::Mat out[] = { bgr, alpha };
        // rgba[0] -> bgr[2], rgba[1] -> bgr[1],
        // rgba[2] -> bgr[0], rgba[3] -> alpha[0]
        int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
        mixChannels( &rgba, 1, out, 2, from_to, 4 );
    
        return bgr;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多