opencv - NSData 到 cv::Mat 的转换

标签 opencv nsdata

我想创建一个 NSData-to-cv::Mat-conversion,而不是 UIImage-to-cv::Mat-conversion:

有效的代码:

// converts original image to cv::Mat
cv::Mat cv_src = [self.image CVMat];

测试代码(还不能用:(...有什么问题吗?)

// converts original image to NSData
NSData *data = UIImageJPEGRepresentation(self.image, 1.0);

// converts NSData to cv::Mat
cv::Mat cv_src_TESTTEST = cv::imdecode(cv::Mat(1,
                                      (int)[data length],
                                      CV_8UC1,
                                      (void*)data.bytes),
                              cv::IMREAD_COLOR);

// converts cv::Mat to a Test-image
UIImage *TestImage = [[UIImage alloc] UIImageFromCVMat:(cv_src_TESTTEST)];

// convert Test-image to cv::Mat
cv::Mat cv_src = [TestImage CVMat];

这段测试代码其实走了弯路,从原始图像(self.image)开始,然后转换如下:

  1. 从原始图像 (self.image) 创建 NSData
  2. 将此 NSData 转换为 cv::Mat
  3. 将 cv::Mat 转换回 UIImage
  4. 再次将 UIImage 转换为 cv::Mat

这个迂回只是为了检查与初始工作代码的相等性......我最终需要的只是转换 2(即 NSData 到 cv::Mat)。不幸的是,第一个代码片段中的“cv_src”与第二个代码片段相比并不相同,为什么?我的假设是“imdecode”在这里无法正常工作 - 非常感谢任何建议!

最佳答案

我尝试使用 NSData-Category(参见下面的代码...)。不确定是否全部正确。请给我一些评论? (...特别是最后一种方法“-(NSData *)NSDataFromCVMat:(cv::Mat)cvMat”(如果通过图像评论绕行更好或不好有什么建议吗??谢谢!

NSData+OpenCV.h

#import <Foundation/Foundation.h>

@interface NSData (NSData_OpenCV)

- (NSData *)NSDataFromCVMat:(cv::Mat)cvMat;

@property(nonatomic, readonly) cv::Mat CVMat;
@property(nonatomic, readonly) cv::Mat CVGrayscaleMat;

@end

NSData+OpenCV.mm

#import "NSData+OpenCV.h"

@implementation NSData (NSData_OpenCV)

// cv::Mat from NSMutableData
- (cv::Mat)CVMat {

UIImage *image = [UIImage imageWithData:self];

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

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), image.CGImage);
CGContextRelease(contextRef);

return cvMat;
}

- (cv::Mat)CVGrayscaleMat {

UIImage *image = [UIImage imageWithData:self];

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGFloat cols = image.size.width;
CGFloat rows = image.size.height;

cv::Mat cvMat = cv::Mat(rows, cols, CV_8UC1); // 8 bits per component, 1 channel

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
                                                kCGImageAlphaNone |
                                                kCGBitmapByteOrderDefault); // Bitmap info flags

CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);

return cvMat;
}

// NSData from cv::Mat
- (NSData *)NSDataFromCVMat:(cv::Mat)cvMat {

return [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];

/*
    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);

    // Creating CGImage from cv::Mat
    CGImageRef imageRef = CGImageCreate(cvMat.cols,                                 // width
                                        cvMat.rows,                                 // height
                                        8,                                          // bits per component
                                        8 * cvMat.elemSize(),                       // bits per pixel
                                        cvMat.step[0],                              // bytesPerRow
                                        colorSpace,                                 // colorspace
                                        kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
                                        provider,                                   // CGDataProviderRef
                                        NULL,                                       // decode
                                        false,                                      // should interpolate
                                        kCGRenderingIntentDefault                   // intent
                                        );


    // Getting UIImage from CGImage
    UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorSpace);

    return UIImageJPEGRepresentation(finalImage, 1.0);
 */

}

@end

关于opencv - NSData 到 cv::Mat 的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26848133/

相关文章:

opencv - Anaconda-手动添加内置程序包

python - 在 Python OpenCV 中查找 connectedComponents 的颜色

ios - UIImageJPEGRepresentation 和 UIImagePNGRepresentation 都很慢

ios - 在 iOS SDK 中使用短信/彩信发送附件

ios - NSData 未在 UIWebView lodadata 方法中正确加载

python - OpenCV 错误:参数 '%s' 需要 Ptr<cv::UMat>

python /OpenCV : Converting images taken from capture

opencv - 如何在OpenCV中增加Haar检测器的窗口大小

iphone - 如何将两个图像附加到 ios 中的 mfmailcomposer View Controller

ios - 在 NSString 中解码 Base-64 编码的 PNG