【发布时间】:2013-09-06 13:49:27
【问题描述】:
我正在开发一个应用程序并使用 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”属性并尝试更改它但没有成功。我还尝试查看是否是在转换时转置矩阵的问题,并尝试更改但没有成功,这也不合逻辑,因为它不会转动每张图片。
我不明白为什么它适用于某些照片而另一些则无效(所有用手机相机拍摄的照片都不起作用)。
如果有人能阐明这件事,我将不胜感激。
【问题讨论】:
-
我的建议是在用图像数据填充 tmpMat 后直接检查它。使用 imshow() 查看它对于普通和手机摄像头图像是否具有相同的方向。还可以使用 tmpMat.type() 检查矩阵的枚举类型是否存在差异。如果这没有透露任何信息,我的猜测是手机存储图像数据的方式可能是列优先而不是行优先
标签: ios objective-c opencv