You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于棋盘格参考的OpenCV自动曝光调节方案咨询

基于棋盘格的相机曝光时间校准方案(适配标定流程)

核心逻辑

利用标定必备的棋盘格作为曝光参考,通过分析其黑白块的像素分布,自动调整曝光参数,确保棋盘格既不过曝(白色块饱和)也不欠曝(黑色块无细节),为后续相机标定提供清晰的特征图像。

曝光状态参考

  • 过曝(曝光时间过长):过曝的棋盘格图像
  • 欠曝(曝光时间过短):欠曝的棋盘格图像

分步实现方案

1. 定位棋盘格ROI

先通过棋盘格检测锁定有效区域,避免无关背景干扰分析:

import cv2
import numpy as np

# 替换为你的棋盘格内角点尺寸(比如8x6)
PATTERN_SIZE = (8, 6)

def get_chessboard_roi(frame):
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    ret, corners = cv2.findChessboardCorners(gray, PATTERN_SIZE, cv2.CALIB_CB_ADAPTIVE_THRESH)
    if not ret:
        return None
    # 计算棋盘格的边界框
    x_min, y_min = np.min(corners, axis=0).astype(int)[0]
    x_max, y_max = np.max(corners, axis=0).astype(int)[0]
    return gray[y_min:y_max, x_min:x_max]

2. 曝光状态判定

通过统计棋盘格黑白块的平均像素值和对比度,判断当前曝光是否合格:

def evaluate_exposure(chessboard_roi):
    h, w = chessboard_roi.shape
    block_h = h // PATTERN_SIZE[1]
    block_w = w // PATTERN_SIZE[0]
    
    white_avg = []
    black_avg = []
    # 遍历每个棋盘格块,按奇偶位置区分黑白
    for i in range(PATTERN_SIZE[1]):
        for j in range(PATTERN_SIZE[0]):
            block = chessboard_roi[i*block_h:(i+1)*block_h, j*block_w:(j+1)*block_w]
            avg_val = np.mean(block)
            if (i + j) % 2 == 0:
                white_avg.append(avg_val)
            else:
                black_avg.append(avg_val)
    
    avg_white = np.mean(white_avg)
    avg_black = np.mean(black_avg)
    contrast = avg_white - avg_black
    
    # 判定规则可根据实际场景调整
    if avg_white > 245 and contrast < 20:
        return "over_exposed"
    elif avg_black < 15 and contrast < 20:
        return "under_exposed"
    else:
        return "optimal"

3. 闭环调整曝光时间

根据判定结果逐步调整曝光参数,直到达到最优状态:

def adjust_exposure():
    cap = cv2.VideoCapture(0)
    # 关闭自动曝光,手动控制(不同相机取值可能不同,需测试)
    cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0.25)
    current_exposure = cap.get(cv2.CAP_PROP_EXPOSURE)
    
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        roi = get_chessboard_roi(frame)
        if roi is None:
            print("未检测到棋盘格,请调整位置")
            cv2.waitKey(500)
            continue
        
        status = evaluate_exposure(roi)
        if status == "optimal":
            print("曝光已适配标定需求,当前曝光时间:", current_exposure)
            break
        elif status == "over_exposed":
            # 逐步降低曝光时间,设置最小下限
            new_exposure = max(current_exposure * 0.8, 1)
            cap.set(cv2.CAP_PROP_EXPOSURE, new_exposure)
            current_exposure = new_exposure
        elif status == "under_exposed":
            # 逐步提升曝光时间
            new_exposure = current_exposure * 1.2
            cap.set(cv2.CAP_PROP_EXPOSURE, new_exposure)
            current_exposure = new_exposure
        
        cv2.waitKey(200)  # 等待相机完成参数调整
    
    cap.release()
    cv2.destroyAllWindows()

# 执行校准
adjust_exposure()

关键注意事项

  • 不同相机的曝光控制接口存在差异:如果OpenCV的CAP_PROP_EXPOSURE失效,需改用相机厂商SDK(如Basler Pylon、FLIR Spinnaker)
  • 判定阈值需根据实际光照环境微调,建议确保黑白块对比度>50
  • 校准过程中需保持棋盘格在视野中心,避免部分区域被遮挡

内容的提问来源于stack exchange,提问作者Jakob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:13:48