3

我正在开发一个应用程序并使用opencv库。

我遇到的问题只发生在某些图像上(通常是用手机的相机制作的),我指出这只是一个转换问题。当我将(有问题的)图像转换为 cv::Mat 对象然后返回时,它只会旋转 90 度。

这是导致问题的调用:

cv::Mat tmpMat = [sentImage CVMat];

UIImage * tmpImage = [[UIImage alloc] initWithCVMat:tmpMat];

[imageHolder setImage: tmpImage];

这里是从图像到矩阵的转换的函数,反之亦然。

-(cv::Mat)CVMat
{

CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage);
CGFloat cols = self.size.width;
CGFloat rows = self.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); // Bitmap info flags

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

return cvMat;
}


- (id)initWithCVMat:(const 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);

CGImageRef imageRef = CGImageCreate(cvMat.cols,                                     // Width
                                    cvMat.rows,                                     // Height
                                    8,                                              // Bits per component
                                    8 * cvMat.elemSize(),                           // Bits per pixel
                                    cvMat.step[0],                                  // Bytes per row
                                    colorSpace,                                     // Colorspace
                                    kCGImageAlphaNone | kCGBitmapByteOrderDefault,  // Bitmap info flags
                                    provider,                                       // CGDataProviderRef
                                    NULL,                                           // Decode
                                    false,                                          // Should interpolate
                                    kCGRenderingIntentDefault);                     // Intent

self = [self initWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);

return self;
}

现在我在我的 imageHolder (一个UIImageView)中使用“Aspect Fill”属性并尝试更改它但没有成功。我还尝试查看是否是在转换时转置矩阵的问题,并尝试更改但没有成功,这也不合逻辑,因为它不会转动每张图片。

我不明白为什么它适用于某些照片,而另一些则不能(所有用手机相机拍摄的照片都不起作用)。

如果有人能阐明这件事,我将不胜感激。

4

2 回答 2

6

iPhone 相机以相同的分辨率(相同的行数和列数)保存以不同方向(纵向/横向)拍摄的相机图像。不同之处在于 JPEG 包含一个标志(准确地说,Exif.Image.Orientation标志)来告诉显示软件需要如何旋转图像才能正确显示。

我的猜测是,OpenCV 在转换时会丢失该信息(存储在UIImage属性中imageOrientation),因此当图像转换回时,UIImage 该信息被设置为默认值(UIImageOrientationUp),解释了为什么某些图像似乎被旋转了。

于 2013-09-08T12:28:39.007 回答
1

我遇到了同样的问题。这解决了从 UIImage 转换为 cvMat 时图像旋转的问题。在底部添加方法,在关闭选择器控制器后调用它。这是位于此处的“第二个答案”:Rotating a CGImage

此外,ios.h 中有两种方法用于 UIImage 到 cvMat,反之亦然,您可以只包含它们。highgui/ios.h。然后添加旋转方法,您就可以开始了。

于 2013-12-04T12:39:59.913 回答