而不是UIImage-to-cv :: Mat-conversion,我想创建一个NSData-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)开始,然后转换如下:
这种绕行只是为了检查初始工作代码是否相等......我最终需要的只是转换2(即NSData到cv :: Mat)。不幸的是,从第一个代码剪切的“cv_src”与第二个相比,遗憾的是不一样,为什么?我的假设是“imdecode”在这里没有正确工作 - 非常感谢任何建议!
答案 0 :(得分:2)
我试过NSData-Category(参见下面的代码......)。不确定一切是否正确。请给我一些评论? (...尤其是最后一个方法“ - (NSData *)NSDataFromCVMat:(cv :: Mat)cvMat”(任何建议,如果通过图像评论绕道更好或没有?谢谢!
#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
#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
答案 1 :(得分:0)
cv::Mat 可以通过以下方式转换为 NSData:
[NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()];
并且要转换回使用以下初始值设定项,您必须提供图像的宽度(列)、高度(行)和类型
cv::Mat(int rows, int cols, int type, void *data, size_t step=AUTO_STEP)
cv::Mat cvMat = cv::Mat(1280, 720, CV_8UC4, (uchar*)data.bytes);