简介
在本帖子内我们将整合上述帖子的代码, 使其BH1750读取的数据可以正确的通过算法转换成光圈, ISO, 和快门速度等, 并且显示在屏幕上.作为一名业余的摄影爱好者, 正好我也有一台相机.这样我正好对着我经常使用的这个相机拍摄时候设置的参数讲解. 这样就更方便理解ISO和光圈和快门速度的关系了.
ISO是相机的感光度设置, 通俗点来将, 就是ISO拍摄出来的照片会变得越亮, 但是对于暗部的细节会丢失.一般来讲如果镜头允许的话, 那么ISO越低约好.
光圈,则是用来控制景深的.比如说现在用不同的光圈来拍摄距离3米的一个问题, 当调整光圈的大小为1.8 的时候,在其他参数不变的情况下. 拍摄出来的图像的背景将会被虚化, 即像打了一层朦胧的滤镜. 如果光圈调整到小光圈, 比如说8 或者9 或者更高的话, 那么被摄物体的背景将会变得清晰. 光圈大小同时影响进光量, 光圈大的话, 那么进光量也就大, 在相同的ISO下, 快门速度将会变大(因为相机已经有足够的光用来曝光). 如果光圈小的话, 那么相机的进光量就会降低, 拍摄同一张图片的时候快门速度就需要降低.
快门速度则是相机快门开启的有效时间, 总的曝光量和曝光时间成正比. 也就是说, 在快门速度保持不变(和ISO)的情况下, 曝光的时间越长, 图片的亮度越亮. 曝光的时间越短, 图片越暗. 那么快门速度和曝光时间不变的情况下如果想只是提升图片的亮度的话, 可以尝试改变光圈和ISO (ISO会丢失细节)
当前的ISO设置为100
在程序自动的设置下(程序会根据设置的参数自动匹配快门速度和光圈大小),我们可以看到大光圈和小光圈所影响的快门速度.
上图为大光圈(镜头垃圾,最大光圈只能开到3.5) 时的快门速度为4秒, 也就是说快门在没有合上的时候需要4秒的时间去曝光. 而将光圈调整到最小的时候
我们可以看到光圈22, 需要的曝光时间为10秒
接下来我们看一下如何使用程序来读取BH1750的光照强度并且将其转换成光圈大小ISO和快门速度, 然后我们尝试将相机调整到手动模式根据上述参数拍一张照片,并且和自动模式拍摄的照片进行对比.
程序设计
花了点时间根据讲师提供的公式计算出了EV然后根据EV来计算快门速度. 我设置恒定设置了光圈的大小为3.5来方便进行实际照片的拍摄测试(再高的话镜头不支持)测试
import time import math import board import adafruit_bh1750 import digitalio import terminalio from adafruit_display_text import bitmap_label import displayio # 初始化 I2C 总线和光照传感器 i2c = board.I2C() # 使用板载的 SCL 和 SDA 引脚 sensor = adafruit_bh1750.BH1750(i2c) # 根据光照值 (Lux) 计算曝光值 (EV) def calculate_ev(lux): return 2 + math.log(lux / 10, 2) if lux > 0 else 0 # 根据 EV、光圈值和 ISO 计算快门速度 def calculate_shutter_speed(ev, aperture, iso): # 快门速度公式:Shutter speed = (aperture ^ 2) / (ISO * (2 ^ EV)) return (aperture ** 2) / (iso * (2 ** ev)) # 初始化 D13 和 D12 引脚的按键 button_up = digitalio.DigitalInOut(board.D13) button_up.direction = digitalio.Direction.INPUT button_up.pull = digitalio.Pull.UP # 启用上拉电阻 button_down = digitalio.DigitalInOut(board.D12) button_down.direction = digitalio.Direction.INPUT button_down.pull = digitalio.Pull.UP # 启用上拉电阻 # 初始化显示屏 group = displayio.Group() board.DISPLAY.root_group = group # 创建用于显示不同输出的文本区域 shutter_label = bitmap_label.Label(terminalio.FONT, text="", scale=2) shutter_label.x = 10 shutter_label.y = 10 group.append(shutter_label) aperture_label = bitmap_label.Label(terminalio.FONT, text="", scale=2) aperture_label.x = 10 aperture_label.y = 40 group.append(aperture_label) iso_label = bitmap_label.Label(terminalio.FONT, text="", scale=2) iso_label.x = 10 iso_label.y = 70 group.append(iso_label) # 初始设置 aperture = 3.5 # 固定光圈值 iso = 100 # 初始 ISO 值 # 主循环 while True: lux = sensor.lux # 从传感器读取光照值(单位:Lux) ev = calculate_ev(lux) # 根据光照值计算曝光值(EV) # 使用按键调整 ISO 值 if not button_up.value: # D13 按键被按下 iso = min(iso * 2, 6400) # ISO 值加倍,最大值为 6400 time.sleep(0.2) # 防止按键抖动的延时 elif not button_down.value: # D12 按键被按下 iso = max(iso // 2, 100) # ISO 值减半,最小值为 100 time.sleep(0.2) # 防止按键抖动的延时 # 根据固定光圈计算快门速度 shutter_speed = calculate_shutter_speed(ev, aperture, iso) # 更新显示内容 shutter_label.text = f"快门: 1/{int(1 / shutter_speed)}秒" if shutter_speed > 0 else "快门: --" aperture_label.text = f"光圈: f/{aperture:.1f}" # 始终为固定光圈值 iso_label.text = f"ISO: {iso}" # 打印调试信息(可选) print(f"光照值: {lux:.2f} | EV: {ev:.2f} | 光圈: f/{aperture:.1f} | ISO: {iso}") print("-" * 50) |
我们将BH1750传感器对着窗外来测试一下环境光. 目前开发版上测试目前的快门速度为1/523 s, 光圈是固定的3.5 计算, 然后ISO是100.
我用相机分别拍了两张图片来进行对比.
第一张图片是用的测光表参数: 快门速度 1/ 500 , 3.5 光圈. ISO 100
第二张图片(下图, 自动模式): 快门速度 1 /60 , 光圈4.0 , ISO 100
可以发现测光表测出来的窗外的细节非常好, 但是室内的偏暗. 而相机自动模式拍摄出来的室内比较贴近实际的室内光环境, 但是窗外远处的乌云细节比较缺失(两处对焦都是锁定的远处大楼,切使用中心测光)
基础任务成果视频展示
https://www.bilibili.com/video/BV1jcB1YsEje/