在OpenCV中使用色彩校正
本文将介绍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。
下面展示一组通过本文介绍的色彩校正模块校正前后示例图。通过示例可以看出,原图拍摄色彩较暗,色卡颜色未显示其本身颜色,地板颜色偏暗,毛巾颜色偏蓝;校正后的图片则很好地还原了色卡和物体本身的颜色。
参考文献
https://en.wikipedia.org/wiki/Color_correction
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中使用色彩校正相关推荐
- opencv 光线影响_在OpenCV中使用色彩校正
编者按:今年OpenCV收到了很多来自中国的贡献,比如DNN的ARM后端Tengine.基于深度学习的文本检测识别.对RISC-V的支持等新功能.在即将发布的4.5.1版本,华为开源能力中心的工程师又 ...
- OpenCV学习笔记(12)——OpenCV中的轮廓
什么是轮廓 找轮廓.绘制轮廓等 1.什么是轮廓 轮廓可看做将连续的点(连着边界)连在一起的曲线,具有相同的颜色和灰度.轮廓在形态分析和物体的检测和识别中很有用. 为了更加准确,要使用二值化图像.在寻找 ...
- OpenCV中的光流及视频特征点追踪
OpenCV中的光流及视频特征点追踪 1. 效果图 2. 原理 2.1 什么是光流?光流追踪的前提.原理 2.2 光流的应用 2.3 光流的2种方法 3. 源码 3.2 稀疏光流追踪 3.2 优化版稀 ...
- Python,OpenCV中的图像修复——cv2.inpaint()
Python,OpenCV中的图像修复--cv2.inpaint 1. 效果图 2. 原理 3. 源码 参考 image inpainting 图像修改 这篇博客将介绍如何通过OpenCV中图像修复的 ...
- 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, ...
- OpenCV中的SURF(Speeded-Up Robust Features 加速鲁棒特征)
OpenCV中的SURF(加速健壮功能) 1. 效果图 2. 原理 2.1 为什么SURF比SIFT快? 2.3 怎样获取SIFT与SURF? 3. 源码 参考 上一篇博客介绍了用于关键点检测和描述的 ...
- Python,OpenCV中的霍夫圆变换——cv2.HoughCircles()
Python,OpenCV中的霍夫圆变换 1. 效果图 2. 源码 参考 这篇博客将学习如何使用霍夫圆变换在图像中找到圆圈,OpenCV使用cv2.HoughCircles()实现霍夫圆变换. cir ...
- OpenCV中的霍夫线变换、概率霍夫线变换
OpenCV中的霍夫线变换.概率霍夫线变换 1. 效果图 2. 原理 2.1 什么是霍夫变换? 2.2 什么是概率霍夫变换? 3. 源码 3.1 霍夫变换 3.2 概率霍夫变换 参考 这篇博客将介绍P ...
- 如何在OpenCV中为InRange阈值选择颜色的最佳HSV值
如何在OpenCV中为InRange阈值选择颜色的最佳HSV值 1. 效果图 2. 源码 参考 之前的博客介绍了如何使用Python,OpenCV通过HSV颜色空间转换检测对象,并进行轨迹追踪.怎么选 ...
最新文章
- linux多进程网络实例,Linux下一个单进程并发服务器的实例 使用select
- python运行命令_Python中执行外部命令
- 数独题的生成与解决方法
- Spring boot集成Swagger3
- 必 备 习 题 集 (五)
- 一起谈.NET技术,asp.net页面中输出变量、Eval数据绑定等总结
- linux cuda 安装目录,Ubuntu16.04 CUDA和GPU的最简最全安装方案及常见问题解决方法,G...
- 斯坦福大学的 CS231n课程
- cad2019菜单栏怎么调出来_AutoCAD2019怎么把工具栏放左右两边两侧工具栏调出来
- Windows自带的远程协助工具(非远程桌面)
- android 极光推送测试,Android 极光推送基本步骤
- 直接获得TP-LINK路由器外网IP地址
- Java 首字母转大写,StringUtils.capitalize
- VHDL矩阵键盘扫描数码管显示
- IntelliJ IDEA使用教程(动图详解):实时代码模板的使用
- Jetson 学习笔记(五):pb转uff---pb转onnx转trt----pth转onnx转pb
- 【机器学习面经】实验室祖传机器学习重难点(第一弹)
- 使用BeanEditForm来创建用户表单
- 李青云老人的长寿秘诀【转】
- 姜思达和机器人_中国偏见地图曝光:百度大数据看穿了一切
热门文章
- 2015年12月学习计划
- 福田区有哪些公园好玩 你都去过吗
- [abc] Placing Rectangles
- 在线装机测试软件,完美装机大师工具V3.0专业版
- 我的世界java怎么自制皮肤_我的世界手机版皮肤怎么做 自己做皮肤教程
- Kubernetes Pod报错 filed to get sandbox image “k8s.gcr.io/pause:3.6“
- 相机对焦、标定等近期学习
- SylixOS学习二—— SylixOS认识和使用_SylixOS虚拟机使用
- 论文阅读笔记--Federated Continual Learning with Weighted Inter-client Transfer
- MAC突然连不上蓝牙