我试图将CGImageRef转换为OpenCV cv :: Mat。
4通道图像的一切正常,但对于灰度图像,它会崩溃,因为CGImageRef GetRowBytes函数返回的值大于mat.step [0]值(等于图像的宽度)。
例如,我有一个500像素宽的灰度CGImageRef,CGImageGetBytesPerRow函数返回512.
为什么要返回此值?我怎样才能正确创建我的cv :: Mat?
- (cv::Mat) CVGrayscaleMatWithCGImage:(CGImageRef)image
{
// NSLog(@"%zu", CGImageGetBytesPerRow(image)); -> return 512
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGFloat cols = CGImageGetWidth(image);
CGFloat rows = CGImageGetHeight(image);
cv::Mat cvMat = cv::Mat(rows, cols, CV_8UC1); // 8 bits per component, 1 channel
CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,
cols,
rows,
8,
cvMat.step[0], // Bytes per row -> return 500
colorSpace,
kCGImageAlphaNone |
kCGBitmapByteOrderDefault);
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);
return cvMat;
}
答案 0 :(得分:0)
我终于开始工作了。每行字节数必须是16的倍数。
以下是代码:
- (cv::Mat) CVGrayscaleMatWithCGImage:(CGImageRef)image
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGFloat cols = CGImageGetWidth(image);
CGFloat rows = CGImageGetHeight(image);
cv::Mat cvMat = cv::Mat(rows, cols, CV_8UC1); // 8 bits per component, 1 channel
unsigned long rowBytes = cvMat.step[0];
if (rowBytes % 16) {
rowBytes = ((rowBytes / 16) + 1) * 16;
}
CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,
cols,
rows,
8,
rowBytes,
colorSpace,
kCGImageAlphaNone |
kCGBitmapByteOrderDefault);
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);
return cvMat;
}