Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Open CV iOS自动旋转和拉伸图像。如何修复?_Ios_Xcode_Opencv - Fatal编程技术网

使用Open CV iOS自动旋转和拉伸图像。如何修复?

使用Open CV iOS自动旋转和拉伸图像。如何修复?,ios,xcode,opencv,Ios,Xcode,Opencv,我正在使用OpenCV 3。我已经使用POD在我的Xcode项目中安装了这个框架。为了将图像(由相机拍摄)转换成黑白,我使用了自适应高斯阈值。下面是我使用的代码 @implementation MyClass +(UIImage *)toBlackAndWhite:(UIImage *)s { cv::Mat input; cv::Mat output; input = [MyClass cvMatFromUIImage:s]; cv::cvtColor(input,

我正在使用OpenCV 3。我已经使用POD在我的Xcode项目中安装了这个框架。为了将图像(由相机拍摄)转换成黑白,我使用了自适应高斯阈值。下面是我使用的代码

@implementation MyClass

+(UIImage *)toBlackAndWhite:(UIImage *)s {    
        cv::Mat input;
cv::Mat output;
input = [MyClass cvMatFromUIImage:s];
cv::cvtColor(input, input, cv::COLOR_BGR2GRAY);
output = cv::Mat(input.cols, input.rows, IPL_DEPTH_8U, 1);
cv::adaptiveThreshold(input, output, 255,CV_ADAPTIVE_THRESH_GAUSSIAN_C,CV_THRESH_BINARY, 75, 25);
return [MyClass imageWithCVMat:output];    
}
//Ref:Open CV documentation
+ (cv::Mat)cvMatFromUIImage:(UIImage *)image
{
    CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
    CGFloat cols = image.size.width;
    CGFloat rows = image.size.height;

    cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha)

    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,                 // Pointer to  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), image.CGImage);
    CGContextRelease(contextRef);

    return cvMat;
}

//Ref:Open CV documentation
+ (UIImage *)imageWithCVMat:(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

    UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
    CGImageRelease(imageRef);
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorSpace);

    return image;
}


@end
问题:我得到的图像,逆时针旋转90°,并被拉伸。请提出一些建议,我怎样才能解决它。请看


问题是由于
UIImage
UIImageOrientation
造成的

背景:
当您以横向模式(右侧的Home按钮)握住iPhone,拍摄照片时,该照片具有“向上”方向(是的,这是默认设置)。所以当你在肖像模式下拍照时,方向是“正确的”。对于“右”方向的照片(纵向),它们实际上是以横向模式保存的。当您查看照片时,它看起来很好,因为“UIImage”会自动将其从横向模式旋转到纵向模式。(将其向右旋转90度,宽度->高度,高度->宽度)

拉伸问题是如何发生的?
对于具有“右”和“左”方向的照片,旋转的
UIImage
数据将转换为OpenCV
Mat
对象,从而使“宽度”和“高度”互换

解决方案:我们需要为处于横向模式的
垫提供原始的“宽度”和“高度”。
UIImage
CGImage
属性具有原始“宽度”和“高度”的图像数据,我们可以使用它

如何发生“旋转90°”问题?
OpenCV
Mat
对象不保留方向信息,因此在我们将
UIImage
转换为
Mat
并将其转换回后,方向将丢失。
解决方案:保持方向并将其应用于结果
UIImage
对象

与问题相关的代码:

+(UIImage *)toBlackAndWhite:(UIImage *)s {
     //Create an image with original width and height  
     UIImage *imageUp = [UIImage imageWithCGImage:[s CGImage]];
     //......
     input = [MyClass cvMatFromUIImage:imageUp];

     //......

     UIImage *handledImage = [MyClass imageWithCVMat:output];  
     //Set orientation to the result image
     UIImage *finalImage = [UIImage imageWithCGImage:[handledImage CGImage] scale:[s scale] orientation: s.imageOrientation];
     return finalImage;
}

你换了一排一排的。Mat构造函数是Mat::Mat(int行、int列、int类型)。此外,您使用BGR2GRAY将3个通道转换为1个通道,但cvMatFromUIImage返回4个通道Mat。@ZuOverture如何解决此问题?在我的情况下,方向是正确的,但图像正在拉伸。您应该使用OpenCV函数在Mat和UIImage之间进行转换,这个答案包括:我们需要给垫子提供原始的“宽度”和“高度”,这是在横向模式下。UIImage的CGImage属性具有原始“宽度”和“高度”的图像数据,我们可以使用它。如何获得原始尺寸?您的解决方案很有帮助,但我不知道如何获得原始宽度和高度在我的情况下,方向是正确的,但图像是正确的stretched@PoojaM.Bohora,从CGImage创建的图像具有原始大小。在上面的示例中,
imageUp.size
是原始大小。@PoojaM.Bohora,是的。您为OpenCV提供了正确大小的图像,然后OpenCV将适当地处理它。最后,将
imageOrientation
设置为结果图像,它可以在iPhone上正确显示。