gpt4 book ai didi

ios - 在 iOS 上使用 openCV 的高动态范围成像产生乱码输出

转载 作者:搜寻专家 更新时间:2023-10-31 22:47:47 26 4
gpt4 key购买 nike

我正在尝试在 iOS 上使用 openCV 3 通过多次曝光生成 HDR 图像,最终将输出为 EXR 文件。我注意到在尝试创建 HDR 图像时出现乱码输出。认为尝试创建相机响应是一个错误,我从头开始并将 openCV 上的 HDR 成像教程 Material 改编到 iOS,但它产生了类似的结果。以下 C++ 代码返回乱码图像:

cv::Mat mergeToHDR (vector<Mat>& images, vector<float>& times)
{
imgs = images;
Mat response;
//Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec();
//calibrate->process(images, response, times);

Ptr<CalibrateRobertson> calibrate = createCalibrateRobertson();
calibrate->process(images, response, times);

// create HDR
Mat hdr;
Ptr<MergeDebevec> merge_debevec = createMergeDebevec();
merge_debevec->process(images, hdr, times, response);

// create LDR
Mat ldr;
Ptr<TonemapDurand> tonemap = createTonemapDurand(2.2f);
tonemap->process(hdr, ldr);

// create fusion
Mat fusion;
Ptr<MergeMertens> merge_mertens = createMergeMertens();
merge_mertens->process(images, fusion);

/*
Uncomment what kind of tonemapped image or hdr to return
Returning one of the images in the array produces ungarbled output
so we know the problem is unlikely with the openCV to UIImage conversion
*/

//give back one of the images from the image array
//return images[0];

//give back one of the hdr images
return fusion * 255;
//return ldr * 255;
//return hdr
}

图片是这样的:

Bad image output

我已经分析了图像,尝试了各种颜色空间转换,但数据似乎是垃圾。

openCV 框架是 openCV.org 网站上最新编译的 3.0.0 版本。 RC 和 alpha 产生相同的结果,并且不会构建当前版本(对于 iOS 或 OSX)。我在想我的下一步是尝试让框架从头开始编译,或者让示例在另一个平台下工作,看看问题是特定于平台还是与 openCV HDR 函数本身有关。但在我这样做之前,我想我会把这个问题抛到堆栈溢出上,看看是否有人遇到过同样的问题,或者我是否遗漏了一些非常明显的东西。

我已经将示例 xcode 项目上传到这里:

https://github.com/artandmath/openCVHDRSwiftExample

在 Github 上的 user foundry 的帮助下,让 openCV 与 swift 一起工作

最佳答案

感谢 foundry 为我指明了正确的方向。 UIImage+OpenCV 类扩展期望每个颜色 channel 8 位,但是 HDR 函数每个 channel 输出 32 位(这实际上是我想要的)。为了显示目的,在将图像矩阵转换回 UIImage 之前,将图像矩阵转换回每 channel 8 位可以解决此问题。

这是生成的图像:

The expected result!

这里是固定函数:

cv::Mat mergeToHDR (vector<Mat>& images, vector<float>& times)
{
imgs = images;
Mat response;
//Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec();
//calibrate->process(images, response, times);

Ptr<CalibrateRobertson> calibrate = createCalibrateRobertson();
calibrate->process(images, response, times);

// create HDR
Mat hdr;
Ptr<MergeDebevec> merge_debevec = createMergeDebevec();
merge_debevec->process(images, hdr, times, response);

// create LDR
Mat ldr;
Ptr<TonemapDurand> tonemap = createTonemapDurand(2.2f);
tonemap->process(hdr, ldr);

// create fusion
Mat fusion;
Ptr<MergeMertens> merge_mertens = createMergeMertens();
merge_mertens->process(images, fusion);

/*
Uncomment what kind of tonemapped image or hdr to return
Convert back to 8-bits per channel because that is what
the UIImage+OpenCV class extension is expecting
*/


// tone mapped
/*
Mat ldr8bit;
ldr = ldr * 255;
ldr.convertTo(ldr8bit, CV_8U);
return ldr8bit;
*/

// fusion
Mat fusion8bit;
fusion = fusion * 255;
fusion.convertTo(fusion8bit, CV_8U);
return fusion8bit;

// hdr
/*
Mat hdr8bit;
hdr = hdr * 255;
hdr.convertTo(hdr8bit, CV_8U);
return hdr8bit;
*/
}

或者,这里是基于 opencv.org iOS 部分中的 iOS 教程之一的 OpenCV+UIImage 类扩展中的 initWithCVMat 方法的修复:

http://docs.opencv.org/2.4/doc/tutorials/ios/image_manipulation/image_manipulation.html#opencviosimagemanipulation

使用 float 据创建新的 CGImageRef 时,需要明确告知它需要 float 据,并且需要反转来自 openCV 的图像数据的字节顺序。现在 iOS/Quartz 有了 float 数据!这是一个有点棘手的修复,因为该方法仍然只处理每个 channel 8 位或 32 位或 alpha,并且没有考虑可以从 Mat 传递到 UIImage 的每种图像。

- (id)initWithCVMat:(const cv::Mat&)cvMat
{
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()];
CGColorSpaceRef colorSpace;

size_t elemSize = cvMat.elemSize();
size_t elemSize1 = cvMat.elemSize1();

size_t channelCount = elemSize/elemSize1;
size_t bitsPerChannel = 8 * elemSize1;
size_t bitsPerPixel = bitsPerChannel * channelCount;

if (channelCount == 1) {
colorSpace = CGColorSpaceCreateDeviceGray();
} else {
colorSpace = CGColorSpaceCreateDeviceRGB();
}

// Tell CGIImageRef different bitmap info if handed 32-bit
uint32_t bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;

if (bitsPerChannel == 32 ){
bitmapInfo = kCGImageAlphaNoneSkipLast | kCGBitmapFloatComponents | kCGBitmapByteOrder32Little;
}

CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

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

// Getting UIImage from CGImage
self = [self initWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);

return self;
}

关于ios - 在 iOS 上使用 openCV 的高动态范围成像产生乱码输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34010524/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com