摘要:
我一直在纠正图像上的白平衡和色彩投射,特别是在iPhone 7上测试时。到目前为止,iPhone 6上一切运行正常,但在闪光灯打开的情况下,iPhone 7上的摄像头有时会在任何图像中产生紫色、黄色或蓝色色调。我正在开发的应用程序在很大程度上依赖于使用OpenCV的颜色检测,所以我正在尝试不同的方法来校正颜色偏斜。我遇到的场景是这样的:用户有一张纸和纸上的一些项目要通过颜色来识别,但当iPhone 7在靠近纸的地方使用时,整个图像上的闪光灯就会呈现色调。该纸张用于更容易地将图像与背景分开,以及在白平衡中使用,以了解图像的哪一部分应该是白色的,以潜在地解决白平衡/颜色偏色问题。
详细信息:
我可以使用OpenCV的背景调整方法来纠正颜色中的细微色调:
- (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进行颜色检测仍然会导致检测到过多的色调颜色。
我接下来尝试的更多的是直接调整相机设置,我觉得这是一种更好的方法来解决最初的问题,而不是事后进行某种颜色校正。我找到了一些修改相机温度和色调值的文档,但这只会导致用户不得不手动调整滑块来获得所需的白平衡图像:
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.jpg和http://i.imgur.com/PG81pAl.jpg
发布于 2017-10-04 03:50:55
对于任何人来说,这可能会有所帮助,我找到了一个合适的解决方案来调整颜色偏色。事实证明,我最初调整OpenCV的方式非常接近,我只需要调整我想要的颜色范围,使其与调整后得到的颜色相似。我也不再使用我找到的rgb2lab函数,而是直接将mat本身从bgr (表示精度的浮点数)转换为lab。这似乎更接近真正的白平衡或色彩校正的图像,但它可能只是我提出的调整后的色彩范围,真正使其更好。
其余的基本相同,只要找到A和B通道的平均值,将垫子分成实验室平面,将它们调整到“中心”即可。下面是使用浮动实验室垫并在A和B中获取偏移量的代码:
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);编辑:我只想补充一下,我也只开始了对我需要的专色区域的偏色校正,而不是整个图像。图像的不同区域根据光线等有不同的投射,因此一次只使用小区域进行校正是有意义的。这被证明是更准确的,并提供了更好的结果。
https://stackoverflow.com/questions/45787176
复制相似问题