IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> Opencv计算相机响应函数(Camera Response Function)与Radiance -> 正文阅读

[人工智能]Opencv计算相机响应函数(Camera Response Function)与Radiance

本文主要用于记录自己在学习CRF过程中遇到的一些问题。

两个论文截图

在这里插入图片描述
在这里插入图片描述

CRF模型

B = f ( V ( t ? L ) ) B=f(V( t\cdot L)) B=f(V(t?L)) 其中 B B B为相机灰度值brightness, L L L为环境中radiance, t t t为曝光时间, V V V为相机镜头参数, f f f为相机响应函数CRF

有些论文中认为相机镜头参数是线性的不考虑,但有些考虑了衰减即靠近图像边缘亮度会暗一些,但没有看到二者同时计算的,如果同时计算两个非线性的函数,我觉得可能会有不确定性,在这里还请教一下了解的朋友。

控制相机曝光

首先要确定其中曝光时长 t t t。由于采用的是V4L2的USB相机,调整过程中遇到了一些列问题。详细记录在这里:V4L相机使用记录

利用OpenCV获取HDR图像

首先了解如何用多张图合成HDR图像,主要参考:learnopencv网站

伪代码:

// load images & exposure time
images.push_back(src);
const vector<float> times = {1/30.0f, 0.25, 2.5, 15.0};

// 计算CRF
Mat responseDebevec;  // response if a CV_32FC3 value.
Ptr<CalibrateDebevec> calibrateDebevec = createCalibrateDebevec();
calibrateDebevec->process(images, responseDebevec, times);

// 采用Debevec方法计算HDR
Mat hdr;
Ptr<MergeDebevec> mergeDebevec = createMergeDebevec();
mergeDebevec->process(images, hdr, times, responseDebevec);
// map to ldr for draw/showing.
Mat ldr;
Ptr<Tonemap> tonemap = createTonemap(2.2f);		// Debevec算法需要经过一步色调映射
tonemap->process(hdr, ldr);

// 采用Mertens方法计算HDR(不需要已知曝光参数)
Ptr<MergeMertens> mergeMertens = createMergeMertens();		// Mertens算法不要
Mat mm_img;
mergeMertens->process(images, mm_img);

注意:所有数据格式采用float或32FC1/32FC3格式,这个坑了我半天。

计算CRF

上面出现的responseDebevec就是CRF。这里把尝试把它画出来:

const int width_scale = 3, height_scale = 20;
const int width = 255 * width_scale, height = 40 * height_scale;
Mat img = Mat::zeros(Size(width, height), CV_8UC3);
Point b_old = Point(0, height);
Point g_old = Point(0, height);
Point r_old = Point(0, height);
for (int i = 0; i < 255; ++i){
    Vec3f v3f = responseDebevec.at<Vec3f>(i, 0);
    float ib = v3f[0];
    float ig = v3f[1];
    float ir = v3f[2];
    Point b_new = Point(i * width_scale, height - ib * height_scale);
    Point g_new = Point(i * width_scale, height - ig * height_scale);
    Point r_new = Point(i * width_scale, height - ir * height_scale);
    line(img, b_old, b_new, Scalar(255, 0, 0));
    line(img, g_old, g_new, Scalar(0, 255, 0));
    line(img, r_old, r_new, Scalar(0, 0, 255));
    b_old = b_new;
    g_old = g_new;
    r_old = r_new;
}
imshow("crf", img);

在这里插入图片描述
但遇到了一个问题,就是我用相机拍摄不同图像时,计算出的CRF是不一样的。趋势可能接近,但数值相差很多。我也不知道为啥,猜测可能和opencv通过V4L设置曝光时间时存在问题?但大致上都符合exp指数形式,那就认为差不都吧。

通过CRF推算Irradiance

知道CRF、曝光后,可以通过图像灰度值推算对应场景的irradiance

由于我每次测得的CRF不一样,但基本符合指数形式,故采用: B = a ? e x p ( b ? L ? t ) + c B=a\cdot exp(b\cdot L \cdot t)+c B=a?exp(b?L?t)+c 方式推算。这个方程也是我自己瞎凑的,给定 B = 0 , L = 0 B=0, L=0 B=0,L=0 B = 255 , L = 1 B=255, L=1 B=255,L=1两个边界,假设 a = 1 a=1 a=1 ,计算反推:

inline double calInverseCRF(uchar intensity){
    // Model equation: a x exp(b x intensity) - 1 = irradiance;
    const float maxIrradiance = 1;       // normalized to 1.
    const float a = 1.0f;                // given a value;
    const float b = (log(maxIrradiance + 1) - log(a)) / 255;
    return a * exp(b * intensity) - 1;
}

Mat testImg;
cvtColor(images[1], testImg, COLOR_BGR2GRAY);
assert(testImg.type() == CV_8UC1);
imshow("test", testImg);
Mat irradiance = Mat::zeros(testImg.size(), CV_32FC1);
for(int i=0; i<testImg.rows; ++i){
    for(int j=0; j<testImg.cols; ++j){
        float value = testImg.at<uchar>(i, j);
        irradiance.at<float>(i, j) = calInverseCRF(value);
    }
}
const double exposureTime = times[1];                                                // not used now.
Mat intensity = irradiance / exposureTime;
normalize(intensity, intensity, 1.0, 0.0, NORM_MINMAX);
imshow("dst", intensity);

结果:
在这里插入图片描述

遇到的问题总结

  1. CRF是三通道的,我尝试转成灰度图算一个CRF,计算的总是错误。
  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-09-19 07:59:01  更:2021-09-19 08:01:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 14:38:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码