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

如何通过Flutter的camera库获取相机画面主色调,判断镜头是否被遮挡?

利用CameraImage检测相机镜头遮挡

要解决镜头遮挡导致画面全黑的问题,你可以通过分析CameraImage的像素亮度来判断——当画面平均亮度低于设定阈值时,即可判定镜头被遮挡。以下是具体实现步骤:

核心思路

  • 在startImageStream的每帧回调中,提取图像的像素数据
  • 将像素转换为灰度值,计算画面的平均亮度
  • 对比平均亮度与预设阈值,判断是否遮挡

代码实现

新增计算图像平均亮度的工具函数,同时修改你的initController方法加入遮挡检测逻辑:

import 'dart:typed_data';
import 'package:camera/camera.dart';

// 计算CameraImage的平均亮度(灰度值的平均值)
double calculateAverageBrightness(CameraImage image) {
  Uint8List bytes;
  if (image.format.group == ImageFormatGroup.yuv420) {
    // Android平台通常为YUV420格式,直接取Y通道(亮度通道)
    bytes = image.planes[0].bytes;
  } else if (image.format.group == ImageFormatGroup.bgra8888) {
    // iOS平台可能为BGRA8888格式,转换为灰度值
    bytes = image.planes[0].bytes;
    List<int> grayscale = [];
    for (int i = 0; i < bytes.length; i += 4) {
      // 灰度计算公式:0.299*R + 0.587*G + 0.114*B
      int b = bytes[i];
      int g = bytes[i+1];
      int r = bytes[i+2];
      int gray = (0.299 * r + 0.587 * g + 0.114 * b).round();
      grayscale.add(gray);
    }
    bytes = Uint8List.fromList(grayscale);
  } else {
    // 其他格式默认取第一个平面的字节
    bytes = image.planes[0].bytes;
  }

  // 采样部分像素计算平均亮度,平衡性能与准确性
  int sum = 0;
  int sampleCount = 0;
  for (int i = 0; i < bytes.length; i += 10) {
    sum += bytes[i];
    sampleCount++;
  }
  return sampleCount > 0 ? sum / sampleCount : 0;
}

Future<void> initController() async {
  try {
    List cameras = await availableCameras();
    controller = CameraController(cameras.first, ResolutionPreset.low);
    await controller!.initialize();
    Future.delayed(const Duration(milliseconds: 100)).then((onValue) {
      controller!.setFlashMode(FlashMode.torch);
    });

    // 亮度阈值,可根据场景调整(0-255区间,全黑为0)
    const brightnessThreshold = 10.0;

    controller!.startImageStream((CameraImage img) {
      image = img;
      // 计算当前帧平均亮度
      double avgBrightness = calculateAverageBrightness(img);
      // 判断镜头是否被遮挡
      bool isCovered = avgBrightness < brightnessThreshold;
      if (isCovered) {
        // 这里添加遮挡后的处理逻辑,比如提示用户移开遮挡物
        print("相机镜头被遮挡!");
      }
    });
  } on Exception catch (e) {
    print(e);
  }
}

关键说明

  • 多平台兼容:针对Android的YUV420和iOS的BGRA8888格式做了适配,保证跨平台正常计算亮度
  • 性能优化:通过间隔采样像素降低计算量,避免高帧率下的性能损耗
  • 阈值灵活调整:如果开启了闪光灯,可适当提高brightnessThreshold,因为闪光灯下轻微遮挡的画面亮度不会太低
  • 异常处理优化:优化了异常捕获的打印方式,直接输出具体异常信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:40:59