how to convert from cvMat to UIImage in objective-c?

后端 未结 8 1397
渐次进展
渐次进展 2020-12-08 07:12

I\'m using the OpenCV framework with XCode and want to convert from cvMat or IplImage to UIImage, how to do that? Thanks.

8条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-08 08:01

    Here is the correct method to convert a cv::Mat to a UIImage.

    Every other implementation I've seen — including OpenCV's documentation — is incorrect: they do not correctly convert from OpenCV's BGR to iOS's RGB, and they do not consider the alpha channel (if one exists). See comments above bitmapInfo = ….

    +(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat {
        NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
    
        CGColorSpaceRef colorSpace;
        CGBitmapInfo bitmapInfo;
    
        if (cvMat.elemSize() == 1) {
            colorSpace = CGColorSpaceCreateDeviceGray();
            bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
        } else {
            colorSpace = CGColorSpaceCreateDeviceRGB();
            // OpenCV defaults to either BGR or ABGR. In CoreGraphics land,
            // this means using the "32Little" byte order, and potentially
            // skipping the first pixel. These may need to be adjusted if the
            // input matrix uses a different pixel format.
            bitmapInfo = kCGBitmapByteOrder32Little | (
                cvMat.elemSize() == 3? kCGImageAlphaNone : kCGImageAlphaNoneSkipFirst
            );
        }
    
        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
            bitmapInfo,                 // 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; 
    }
    

提交回复
热议问题