从Matrix转换时旋转的图像

时间:2013-09-06 13:49:27

标签: ios objective-c opencv

我正在开发一款应用并使用 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”属性,并尝试更改它但没有成功。我也试过看看是否存在矩阵转换为转换的问题并试图改变而没有成功,它也不合逻辑,因为它不会转换每张图片。

我不明白为什么它适用于某些图片而不是其他图片(所有使用手机相机拍摄的照片都不起作用)。

如果有人能够了解此事,我将不胜感激。

2 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:1)

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

此外,ios.h中有两种方法可以将UIImage转换为cvMat,反之亦然,您可以只包括。 highgui / ios.h。然后添加旋转方法,你就可以了。