首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何消除色差或调整白平衡?

如何消除色差或调整白平衡?
EN

Stack Overflow用户
提问于 2017-08-21 06:01:28
回答 1查看 1.5K关注 0票数 1

摘要:

我一直在纠正图像上的白平衡和色彩投射,特别是在iPhone 7上测试时。到目前为止,iPhone 6上一切运行正常,但在闪光灯打开的情况下,iPhone 7上的摄像头有时会在任何图像中产生紫色、黄色或蓝色色调。我正在开发的应用程序在很大程度上依赖于使用OpenCV的颜色检测,所以我正在尝试不同的方法来校正颜色偏斜。我遇到的场景是这样的:用户有一张纸和纸上的一些项目要通过颜色来识别,但当iPhone 7在靠近纸的地方使用时,整个图像上的闪光灯就会呈现色调。该纸张用于更容易地将图像与背景分开,以及在白平衡中使用,以了解图像的哪一部分应该是白色的,以潜在地解决白平衡/颜色偏色问题。

详细信息:

我可以使用OpenCV的背景调整方法来纠正颜色中的细微色调:

代码语言:javascript
复制
- (void)adjustBackground:(Mat &)inputROI image:(Mat &)imageInBG{

    Scalar meanCol = mean(inputROI);

    // original
    Mat labOrig, labFloat, ROIfloat;
    std::vector<Mat>planes(3);
    inputROI.convertTo(ROIfloat, CV_32FC3, 1.0/255.0f);
    cvtColor(ROIfloat,labFloat,CV_BGR2Lab);
    split(labFloat,planes);


    double l_v,a_v,b_v;
    rgb2lab(meanCol(2), meanCol(1), meanCol(0), l_v, a_v, b_v);

    add(planes[1], -a_v, planes[1]);
    add(planes[2], -b_v, planes[2]);

    merge(planes,labFloat);
    cvtColor(labFloat, ROIfloat, CV_Lab2BGR);
    ROIfloat.convertTo(inputROI , CV_8UC3, 255.0f);

    planes.clear();
    labOrig.release();
    labFloat.release();
    ROIfloat.release();
}

其中rgb2lab做的正是它所暗示的,将rgb转换为lab颜色空间。为了获得更好的精度,我还将图像转换为浮点数。这能够纠正较小的颜色投射,但如果图像颜色较深,它仍然会导致颜色略微着色,而使用OpenCV进行颜色检测仍然会导致检测到过多的色调颜色。

我接下来尝试的更多的是直接调整相机设置,我觉得这是一种更好的方法来解决最初的问题,而不是事后进行某种颜色校正。我找到了一些修改相机温度和色调值的文档,但这只会导致用户不得不手动调整滑块来获得所需的白平衡图像:

代码语言:javascript
复制
Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
if (captureDeviceClass != nil) {
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    if ([device isWhiteBalanceModeSupported: AVCaptureWhiteBalanceModeLocked]){
        if ([device lockForConfiguration:nil]){
            AVCaptureWhiteBalanceTemperatureAndTintValues temperatureAndTint = {
            .temperature = tempVal,
            .tint = tintVal,
            };

        AVCaptureWhiteBalanceGains wbGains = [device deviceWhiteBalanceGainsForTemperatureAndTintValues:temperatureAndTint];

        if((NSLocationInRange(wbGains.redGain, NSMakeRange(1, (device.maxWhiteBalanceGain - 1.0))))&&(NSLocationInRange(wbGains.greenGain, NSMakeRange(1, (device.maxWhiteBalanceGain - 1.0))))&&(NSLocationInRange(wbGains.blueGain, NSMakeRange(1, (device.maxWhiteBalanceGain - 1.0)))))
        {
            NSLog(@"Good values");
            [device deviceWhiteBalanceGainsForTemperatureAndTintValues:temperatureAndTint];

            [device setWhiteBalanceModeLockedWithDeviceWhiteBalanceGains:[device deviceWhiteBalanceGainsForTemperatureAndTintValues:temperatureAndTint] completionHandler:^(CMTime syncTime) {

            }];
            [device unlockForConfiguration];
        }
        else{
            NSLog(@"Bad values");
        }
    }
}

其中tempVal和tintVal是来自滑块的输入。

有没有办法关闭iPhone相机上的自动调整,或者在OpenCV中有更好的方法来调整更极端的颜色投射?

编辑:

这里有一些例子。忽略中间的图表,我尝试使用直方图。一个图像显示整个图像上的蓝色色调,另一个图像显示我的偏色校正在中间的ROI中工作,但它改变了图像上的颜色太多(我需要电阻上的色带尽可能准确)。

http://i.imgur.com/jlc4MDa.jpghttp://i.imgur.com/PG81pAl.jpg

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-04 03:50:55

对于任何人来说,这可能会有所帮助,我找到了一个合适的解决方案来调整颜色偏色。事实证明,我最初调整OpenCV的方式非常接近,我只需要调整我想要的颜色范围,使其与调整后得到的颜色相似。我也不再使用我找到的rgb2lab函数,而是直接将mat本身从bgr (表示精度的浮点数)转换为lab。这似乎更接近真正的白平衡或色彩校正的图像,但它可能只是我提出的调整后的色彩范围,真正使其更好。

其余的基本相同,只要找到A和B通道的平均值,将垫子分成实验室平面,将它们调整到“中心”即可。下面是使用浮动实验室垫并在A和B中获取偏移量的代码:

代码语言:javascript
复制
Mat labFloat, ROIfloat;
std::vector<Mat>lab_planes(3);
input.convertTo(ROIfloat, CV_32FC3, 1.0/255.0f);
cvtColor(ROIfloat,labFloat,CV_BGR2Lab);
split(labFloat,lab_planes);

Scalar meanVals = mean(labFloat);

// valA is the mean of the A channel (offset to add/subtract)
// valB is the mean of the B channel (offset to add/subtract)
double valA = meanVals(1);
double valB = meanVals(2);

编辑:我只想补充一下,我也只开始了对我需要的专色区域的偏色校正,而不是整个图像。图像的不同区域根据光线等有不同的投射,因此一次只使用小区域进行校正是有意义的。这被证明是更准确的,并提供了更好的结果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45787176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档