将UIImage转换为cv::Mat并从文件中读取cv::Mat会得到不同的结果



我使用以下代码将UIImage转换为cv::Mat:

-(cv::Mat)openCVMat{
    // Turn a UIImage into a cv::Mat
    // Draw the image into a bitmap context: the Mat's matrix

    CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage);
    CGFloat columns = self.size.width;
    CGFloat rows = self.size.height;
    cv::Mat m(rows, columns, CV_8UC4, cv::Scalar(0,0,0,0));      // (bits, 4 channels (RGBA)

    CGContextRef context = CGBitmapContextCreate(m.data,
                                                 columns,
                                                 rows,
                                                 8,
                                                 m.step[0],
                                                 colorSpace,
                                                 kCGImageAlphaNoneSkipLast|kCGBitmapByteOrderDefault);
    // Draw
    CGContextDrawImage(context, CGRectMake(0, 0, columns, rows), self.CGImage);

    // Cleanup
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);
    // Return
    return m;
}

它似乎工作得很好,但在一些图像上,如果我只是用imread:从文件中读取它,则生成的cv::Mat是不同的

NSURL *url = [[NSBundle mainBundle] URLForResource:@"blue"
                                         withExtension:@"png"];
cv::Mat fromFile = cv::imread([url.path cStringUsingEncoding:NSUTF8StringEncoding], CV_LOAD_IMAGE_UNCHANGED | CV_LOAD_IMAGE_COLOR);
cv::Mat withAlpha;
cv::cvtColor(fromFile, withAlpha, CV_BGRA2RGBA);

在这种情况下,生成的cv::Mat(带Alpha)略有不同,特别是在图像的角落。

例如,当将图像读取为UIImage,然后转换为cv::Mat时,最终像素为:[0,0110255]这是RGBA

而直接用imread读取后的最后一个像素是:[0,0255110]也是RGBA

为了让事情变得更好,并不是所有的图像都会发生这种情况。

你知道为什么会这样吗?

这是测试图像:blue.png

读取的格式与创建cv::Mat的格式不匹配。

我看到在从资源包加载图像时,您使用的是:

           CV_LOAD_IMAGE_UNCHANGED | CV_LOAD_IMAGE_COLOR. 

只需保持CV_LOAD_IMAGE_UNCHANGED并检查即可。这应该可以保证从PNG加载alpha通道。看看这是否有帮助。

最新更新