ios - 将 UIImage 转换为 cv::Mat

标签 ios objective-c opencv

我有一个 UIImage,它是从 iPhone 相机捕获的图片,现在我希望将 UIImage 转换为 cv::Mat (OpenCV)。我正在使用以下代码行来完成此操作:

-(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;
}

此代码适用于横向模式下的 UIImage,但当我对纵向模式下拍摄的图像使用相同的代码时,图像会向右旋转 90 度。

我是 iOS 和 Objective C 的新手,因此我无法弄清楚哪里出了问题。

谁能告诉我代码有什么问题,或者我是否遗漏了什么。

最佳答案

这是因为 UIImage 实际上不是纵向的。使用 iPhone 相机拍摄的所有照片都是原始位图状态下的风景,例如 3264 宽 x 2488 高。 “肖像”照片按图像中设置的方向 EXIF 标志显示,例如,照片库应用程序根据此标志和相机的查看方向旋转图像。

该标志还会影响 UIImage 报告其宽度和高度属性的方式,将它们从标记为纵向的图像的位图值中调换。

cv::Mat 不会理会这些。这意味着 (i) 在转换为 cv::Mat 时,肖像图像将转置其 size.widthsize.height 值, (ii) 当从 cv::Mat 翻译回来时,你将丢失方向标志。

UIImagecv::Mat 时,处理此问题的最简单方法是,如果图像被标记为纵向,则交换宽度和高度值:

if  (self.imageOrientation == UIImageOrientationLeft
      || self.imageOrientation == UIImageOrientationRight) {
         cols = self.size.height;
         rows = self.size.width;
    }

cv::Mat 转换回 UIImage 时,您需要恢复方向标志。假设您的 cv::Mat -> UIImage 代码包含以下内容:

self = [self initWithCGImage:imageRef];

您可以改用此方法,并按照原来的方式重新设置方向。

self = [self initWithCGImage:imageRef scale:1 orientation:orientation];

关于ios - 将 UIImage 转换为 cv::Mat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14332687/

相关文章:

ios - 不平静地使用 RestKit

python - 为什么OpenCV不使用Python的CV2给这个矩形一个颜色

ios - 如何通过 XCode 6 中的 Interface Builder 更改 UINavigationBar 的背景图像

iphone - iOS :Get UIImage Orientation inside a UIImageview with exif data?

android - 在 phonegap 中播放本地声音

iphone: 在 UIWebView 中弹出按钮

ios - C 代码可以编译成任何架构的静态库吗?

ios - 基于内容的动态 UITableView 单元格高度

android - 在 JNI/Android 中初始化 C++ 对象一次

c++ - ROS 中的 VISP - 无法显示相机提要