长曝光拍照功能

长曝光拍照,一般指曝光时间大于0.5s 的拍照,现在的 sensor 支持的长曝光时间都比较长了,比如 imx380 ,能支持到 64s。参考一般的手机一般会有 1s 2s 5s 10s 30s 等。

下面先说明下sensor 曝光时间。一般的单位是 多少行,所以设置下面的曝光时间是 linecount, 行数。

下面是高通平台的代码中关于曝光时间的计算:

这个宏定义了 1s 中有多少个像素,那么一个像素的时间就是 1/vt_pik_clk

#define SENSOR_GET_VT_PIK_CLK(out_info) \
(uint32_t)((out_info)->line_length_pclk * (out_info)->frame_length_lines \
* (out_info)->max_fps)

1行的曝光时间

Tline = line_length_pclk * 1 / vt_pik_clk

那么设置下来的 linecount 表示的时间就是:

Tline * linecount

那么如果设置下来的曝光时间是 5s, 那换算能 linecount

5s = Tline * linecount

linecount = 5s / Tline

但是这个 linecout 在 sensor 的 spec 中有规定的, 比如 imx380 最大就是 16位数(两个字节表示) 65535,  最大的 Tline 数 是 65535 - 22, 这个22 是sensor 定义的。

那么如果需要实现长曝光, 比如 5s ,用上面的公式计算出来(原创mojl)得到的 linecount 数就超过 65513 了,所以sensor 有了另外一个寄存器,是这样定义的:

0x3100   CIT_LSHIFT     //range 0 - 7  0: 表示非长曝光功能, 

exposure_time = coarse_integ_time << LSHIFT

这样同样的 linecount , 曝光时间就被放大到原来的 2,4,  8, 16, 32, 64, 128 倍。

这样我们就可以实现我们的长曝光功能了, 我们先设置一个 base 曝光时间,比如 0.5s, 其它的曝光时间是 这个 base 的倍数,然后结合上面的 LSHIFT 设置,就可以实现

任意大小的曝光时间了。举个例子:

比如 设置 2s 曝光时间, 那么 2s/0.5s = 4 , 这样 LSHIFT 正好设置能 2

那么 设置为 1.2s 怎么(原创mojl)计算呢, 1.2s / 0.5s = 2.4, 可以 通过 lshift = log2(2.4) 向上取整,然后在用原来的 linecount 除以 pow(2, lshift), 我设计了下面的代码 

base_linecount 对应 0.5s 时的 linecount,这个 0.5s 可以用换成其它值

div = (1.0 * current_linecount) / base_linecount;

lshift = (log2(div) + 0.9999);

current_linecount /= pow(2, lshift);

通过这几行代码,就把 长曝光对应的 很大的 linecount 值,分解成了一个合适的linecount 值 和 LSHIFT 的组合。在高通的代码中,我们只要把 current linecount 值临时修改掉,然后再把 0x3100 写成

刚才计算出来的 LSHIFT。 记得 要把 那个原始的 linecount 值提前保存(原创mojl)出来,设置完sensor 之后还要恢复回去,因为在 照片的曝光信息中计算曝光时间需要那个原始的linecount 才能算出来长曝光的值的。

猜你喜欢

转载自www.cnblogs.com/mojl-cnblogs/p/12553800.html