我正在使用 OpenCV 3。我已经使用 POD 在我的 Xcode 项目中安装了该框架。要将图像(由相机捕获)转换为黑白,我使用 自适应高斯阈值。下面是我用过的代码
@implementation MyClass
+(UIImage *)toBlackAndWhiteUIImage *)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 imageWithCVMatutput];
}
//Ref:Open CV documentation
+ (cv::Mat)cvMatFromUIImageUIImage *)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 *)imageWithCVMatconst 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°,逆时针方向并被拉伸(stretch)。请提出一些建议,我该如何解决。请看
Original Image
Processed Image
Best Answer-推荐答案 strong>
问题是由于 UIImage 的 UIImageOrientation 造成的。
背景:
当您以横向模式(右侧的 Home 按钮)握住 iPhone 拍照时,该照片具有“向上”方向(是的,这是默认设置)。因此,当您以纵向模式拍照时,方向为“右”。对于“右”方向照片(人像),它们实际上仍以横向模式保存。当您查看照片时,它看起来很好,因为“UIImage”会自动将其从横向模式旋转到纵向。 (向右旋转90度,宽->高,高->宽)
拉伸(stretch)问题是如何发生的?
对于具有“右”和“左”方向的照片,旋转后的 UIImage 数据将被转换为 OpenCV Mat 对象,这使得 'width' 和 'height' <强>交换。
解决方案:我们需要将原始的'width'和'height'赋予Mat ,它处于横向模式。 UIImage 的 CGImage 属性有原始'width'和'height'的图像数据,我们可以使用它。
“旋转 90°”问题是如何产生的?
OpenCV Mat 对象不保留方向信息,因此在我们将 UIImage 转换为 Mat 并将其转换回来后,方向丢失了。
解决方案:保持方向并将其应用于结果 UIImage 对象。
与问题相关的代码:
+(UIImage *)toBlackAndWhiteUIImage *)s {
//Create an image with original width and height
UIImage *imageUp = [UIImage imageWithCGImage:[s CGImage]];
//......
input = [MyClass cvMatFromUIImage:imageUp];
//......
UIImage *handledImage = [MyClass imageWithCVMatutput];
//Set orientation to the result image
UIImage *finalImage = [UIImage imageWithCGImage:[handledImage CGImage] scale:[s scale] orientation: s.imageOrientation];
return finalImage;
}
关于ios - 使用 Open CV iOS 自动旋转和拉伸(stretch)图像。怎么修?,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/36010735/
|