本文将介绍CV领域一个重要应用 -- 色彩校正。该模块收录在 opencv_contrib/modules/mcc 模块中,由 PR #2671 贡献。

色彩校正简介

一般来说,由于拍摄设备、光线环境等客观因素,或者拍摄者喜好等主观因素影响,人们拍摄到的图片与真实物体的色彩会有一定的偏差。同一个事物在不同的环境下得到的图片颜色是不同的,这样就对接下来进行的图片处理、比较造成了一定影响。色彩校正技术就是为解决这个问题而提出的。

色彩校正(color calibration),通俗来说,就是使图片还原事物本身的颜色,也就是尽可能接近拍摄时人眼看所看到的事物。如今,色彩校正已经不仅在摄影中使用,而是在影视制作、游戏、医疗、建筑等各行各业中广泛使用。

需要注意的是,色彩校正与调色是不同的概念。前者是在图片中使事物的色彩重现,必须遵循一定的标准,不具有随意性,需要一些技术手段实现;后者则是人们对图片色彩的主观喜好而为,不需要遵循任何标准,具有随意性,是艺术性的实现。

从技术上来说,色彩校正[1]的目的是调整输入输出设备的颜色响应到已知状态。被校准的设备有时被称为校准源 ; 用作标准的色彩空间有时也称为校准目标。由于输入输出设备的制造工艺等,其通道响应存在非线性失真,为了校正该设备输出的图片,必须将其捕捉到的色彩与实际色彩进行校正。

色彩校正通常分成2个步骤:

  • 一是先将输入色彩空间线性化为与亮度成正比。这个过程是不适定问题[2],因此有许多不同的解决方案;

  • 二是做线性变换,把色彩空间变成绝对RGB色彩空间。所用的线性变换的矩阵称为色彩变换矩阵(color correction matrix,CCM),也称为CCM矩阵。CCM矩阵需要通过非线性优化来求解。

通常使用的校准色彩叫做色卡(colorchecker),最著名的是麦克白色卡(Macbeth ColorChecker)。色卡提供色彩校正中的参考色,所有的颜色都已经被标定。最流行的标准色卡是 Macbeth色卡,如下图所示。它包括4*6个色块,其中,最后一行的色块是灰色色块,可以用于灰度线性化或是白平衡。

Macbeth色卡

色彩校正的详细理论可查阅以下链接:

https://github.com/riskiest/color_calibration/tree/v4/doc/pdf/English/Algorithm

在OpenCV中使用色彩校正

在对 OpenCV 进行 building 时,运行以下命令来 build 所有 opencv_contrib 模块

cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules/

或者仅 build 色彩校正所在的 mcc 模块

cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules/mcc

若使用 cmake-gui(CMake的GUI版本)进行构建,需要检查确认包含 mcc 模块。

opencv_contrib/modules/mcc 模块主要包含两个部分,

  • 其一是 color checker detector 模型,具体说明可参考

    https://github.com/opencv/opencv_contrib/blob/master/modules/mcc/tutorials/basic_chart_detection/basic_chart_detection.markdown;

  • 其二为本文主要介绍的色彩校正模块。

色彩校正模块的核心类 -- ColorCorrectionModel:

声明:

opencv_contrib/modules/mcc/include/opencv2/mcc/ccm.hpp

定义:

opencv_contrib/modules/mcc/src/ccm.cpp

ColorCorrectionModel 的参数说明如下:

    src :检测到 ColorChecker 色块的颜色(颜色类型是RGB而不是BGR,颜色值在[0, 1]范围内);constcolor :内置色卡,包括Macbeth、Vinyl、DigitalSGMat colors :参考颜色值(颜色值在[0, 1]范围内);ref_cs :对应颜色值的色彩空间。如果颜色类型是RGB类型,则颜色格式是RGB而不是BGR;支持的色彩空间有:RGB色彩空间(如COLOR_SPACE_sRGB)、线性RGB色彩空间(如COLOR_SPACE_sRGBL)、非RGB色彩空间(如COLOR_SPACE_Lab_D50_2)等。

在本文中,以 samples/color_correction_model.cpp 的示例作为参考,提取关键步骤代码形成如下程序:

#include <opencv2/imgcodecs.hpp>
#include <opencv2/mcc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
using namespace mcc;
using namespace ccm;
int main(int argc, char *argv[])
{// [get_messages_of_image]:获取图像消息string filepath = "input.png"; // 输入图片路径Mat image = imread(filepath, IMREAD_COLOR);Mat imageCopy = image.clone();Ptr<CCheckerDetector> detector = CCheckerDetector::create();// [get_color_checker]:准备ColorChecker检测vector<Ptr<mcc::CChecker>> checkers = detector->getListColorChecker();for (Ptr<mcc::CChecker> checker : checkers){// [create]:创建CCheckerDetector对象,并使用getListColorChecker函数获取ColorChecker信息。Ptr<CCheckerDraw> cdraw = CCheckerDraw::create(checker);cdraw->draw(image);Mat chartsRGB = checker->getChartsRGB();Mat src = chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3);src /= 255.0;// [get_ccm_Matrix]:对于每个ColorChecker,都可以计算一个ccm矩阵以进行颜色校正。Model1是ColorCorrectionModel类的对象,可以根据需要来修改参数以获得最佳色彩校正效果。ColorCorrectionModel model1(src, COLORCHECKER_Vinyl);model1.run();Mat ccm = model1.getCCM();std::cout<<"ccm "<<ccm<<std::endl;double loss = model1.getLoss();std::cout<<"loss "<<loss<<std::endl;// [make_color_correction]:成员函数infer_image用于使用ccm矩阵进行校正校正。Mat img_;cvtColor(image, img_, COLOR_BGR2RGB);img_.convertTo(img_, CV_64F);const int inp_size = 255;const int out_size = 255;img_ = img_ / inp_size;Mat calibratedImage= model1.infer(img_);Mat out_ = calibratedImage * out_size;// [Save_calibrated_image]:保存已校准的图像。out_.convertTo(out_, CV_8UC3);Mat img_out = min(max(out_, 0), out_size);Mat out_img;cvtColor(img_out, out_img, COLOR_RGB2BGR);imwrite("output.png",out_img);}return 0;
}

运行上述代码所在文件,即可完成对于 input.png 图片的色彩校正,校正后的图片为 output.png。

下面展示一组通过本文介绍的色彩校正模块校正前后示例图。通过示例可以看出,原图拍摄色彩较暗,色卡颜色未显示其本身颜色,地板颜色偏暗,毛巾颜色偏蓝;校正后的图片则很好地还原了色卡和物体本身的颜色。

参考文献

  1. https://en.wikipedia.org/wiki/Color_correction

  2. Bianco, S., Bruna, A.R., Naccari, F., Schettini, R.: Color correction pipeline optimization for digital cameras. J. Electron. Imaging 22(2), 023014:1–023014:10 (2013)

在OpenCV中使用色彩校正相关推荐

  1. opencv 光线影响_在OpenCV中使用色彩校正

    编者按:今年OpenCV收到了很多来自中国的贡献,比如DNN的ARM后端Tengine.基于深度学习的文本检测识别.对RISC-V的支持等新功能.在即将发布的4.5.1版本,华为开源能力中心的工程师又 ...

  2. OpenCV学习笔记(12)——OpenCV中的轮廓

    什么是轮廓 找轮廓.绘制轮廓等 1.什么是轮廓 轮廓可看做将连续的点(连着边界)连在一起的曲线,具有相同的颜色和灰度.轮廓在形态分析和物体的检测和识别中很有用. 为了更加准确,要使用二值化图像.在寻找 ...

  3. OpenCV中的光流及视频特征点追踪

    OpenCV中的光流及视频特征点追踪 1. 效果图 2. 原理 2.1 什么是光流?光流追踪的前提.原理 2.2 光流的应用 2.3 光流的2种方法 3. 源码 3.2 稀疏光流追踪 3.2 优化版稀 ...

  4. Python,OpenCV中的图像修复——cv2.inpaint()

    Python,OpenCV中的图像修复--cv2.inpaint 1. 效果图 2. 原理 3. 源码 参考 image inpainting 图像修改 这篇博客将介绍如何通过OpenCV中图像修复的 ...

  5. Python,OpenCV中的K均值聚类——K-Means Cluster

    Python,OpenCV中的K均值聚类 1. 效果图 2. 原理 2.1 什么是K均值聚类? 2.2 K均值聚类过程 2.3 cv2.kmeans(z, 2, None, criteria, 10, ...

  6. OpenCV中的SURF(Speeded-Up Robust Features 加速鲁棒特征)

    OpenCV中的SURF(加速健壮功能) 1. 效果图 2. 原理 2.1 为什么SURF比SIFT快? 2.3 怎样获取SIFT与SURF? 3. 源码 参考 上一篇博客介绍了用于关键点检测和描述的 ...

  7. Python,OpenCV中的霍夫圆变换——cv2.HoughCircles()

    Python,OpenCV中的霍夫圆变换 1. 效果图 2. 源码 参考 这篇博客将学习如何使用霍夫圆变换在图像中找到圆圈,OpenCV使用cv2.HoughCircles()实现霍夫圆变换. cir ...

  8. OpenCV中的霍夫线变换、概率霍夫线变换

    OpenCV中的霍夫线变换.概率霍夫线变换 1. 效果图 2. 原理 2.1 什么是霍夫变换? 2.2 什么是概率霍夫变换? 3. 源码 3.1 霍夫变换 3.2 概率霍夫变换 参考 这篇博客将介绍P ...

  9. 如何在OpenCV中为InRange阈值选择颜色的最佳HSV值

    如何在OpenCV中为InRange阈值选择颜色的最佳HSV值 1. 效果图 2. 源码 参考 之前的博客介绍了如何使用Python,OpenCV通过HSV颜色空间转换检测对象,并进行轨迹追踪.怎么选 ...

最新文章

  1. linux多进程网络实例,Linux下一个单进程并发服务器的实例 使用select
  2. python运行命令_Python中执行外部命令
  3. 数独题的生成与解决方法
  4. Spring boot集成Swagger3
  5. 必 备 习 题 集 (五)
  6. 一起谈.NET技术,asp.net页面中输出变量、Eval数据绑定等总结
  7. linux cuda 安装目录,Ubuntu16.04 CUDA和GPU的最简最全安装方案及常见问题解决方法,G...
  8. 斯坦福大学的 CS231n课程
  9. cad2019菜单栏怎么调出来_AutoCAD2019怎么把工具栏放左右两边两侧工具栏调出来
  10. Windows自带的远程协助工具(非远程桌面)
  11. android 极光推送测试,Android 极光推送基本步骤
  12. 直接获得TP-LINK路由器外网IP地址
  13. Java 首字母转大写,StringUtils.capitalize
  14. VHDL矩阵键盘扫描数码管显示
  15. IntelliJ IDEA使用教程(动图详解):实时代码模板的使用
  16. Jetson 学习笔记(五):pb转uff---pb转onnx转trt----pth转onnx转pb
  17. 【机器学习面经】实验室祖传机器学习重难点(第一弹)
  18. 使用BeanEditForm来创建用户表单
  19. 李青云老人的长寿秘诀【转】
  20. 姜思达和机器人_中国偏见地图曝光:百度大数据看穿了一切

热门文章

  1. 2015年12月学习计划
  2. 福田区有哪些公园好玩 你都去过吗
  3. [abc] Placing Rectangles
  4. 在线装机测试软件,完美装机大师工具V3.0专业版
  5. 我的世界java怎么自制皮肤_我的世界手机版皮肤怎么做 自己做皮肤教程
  6. Kubernetes Pod报错 filed to get sandbox image “k8s.gcr.io/pause:3.6“
  7. 相机对焦、标定等近期学习
  8. SylixOS学习二—— SylixOS认识和使用_SylixOS虚拟机使用
  9. 论文阅读笔记--Federated Continual Learning with Weighted Inter-client Transfer
  10. MAC突然连不上蓝牙