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

Streamlit调用OpenCV函数后显示空白图像的解决方法

故障原因

三个核心问题导致输出空白mask:

  • 颜色空间转换参数错误:用PIL读取的图片默认是RGB通道顺序,代码里调用cv2.cvtColor时传了cv2.COLOR_BGR2HSV参数,该参数仅适用于OpenCV默认读取的BGR格式图片,直接处理RGB图会得到完全错误的HSV值,生成的mask自然全黑无内容。
  • 阈值默认值无效:所有HSV上下限输入框的默认值都设为1,上下限区间几乎重合,根本覆盖不到任何有效颜色像素,就算用户没改值直接点检测,也只会得到全黑mask。
  • 表单逻辑冲突:把HSV下限、上限输入拆成了两个独立侧边栏表单,外加一个外层独立检测按钮,Streamlit每次交互都会重跑页面脚本,点任意按钮都会触发未提交表单的值重置回默认值,根本拿不到用户实际输入的阈值参数。
修复步骤
  • 修正颜色空间转换参数,PIL读取的RGB图转HSV改用cv2.COLOR_RGB2HSV
  • 把6个HSV阈值输入、检测触发按钮合并到同一个表单中,避免交互时值被重置
  • 将输入框默认值替换为黄色对应的有效HSV范围,方便功能验证
  • 显示单通道mask时指定灰度图模式,避免显示异常
修复后可运行代码
import cv2
import numpy as np
import streamlit as st
from PIL import Image

def detect_color(img,low_val_list: list[int], upper_val_list: list[int]):  
    lower_val = np.array(low_val_list)
    upper_val = np.array(upper_val_list)
    # 修正通道转换参数:PIL读入是RGB格式,用RGB2HSV
    hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
    mask = cv2.inRange(hsv,lower_val,upper_val)
    # 指定单通道灰度模式显示mask
    st.image(mask, channels="GRAY", caption="颜色检测掩膜结果")
    return mask

def detection():
    get_img = st.file_uploader('Upload An Image',type=['png','jpg','jpeg','webm'])
    select_det = st.sidebar.selectbox('Select Detection Category',
                                      ['Color Detection',
                                      'Eye Pupil Detection',
                                      'Edge Detection',
                                      'Car Detection'])
    if select_det == "Color Detection":
        if get_img is not None:
            st.image(get_img, caption="上传原图")
            original_image = Image.open(get_img)
            original_image = np.array(original_image)

            # 所有阈值输入和提交按钮合并到同一个表单
            with st.sidebar.form('hsv_threshold_form'):
                st.write("HSV下限阈值")
                # 默认值设为黄色对应HSV范围(适配输入框0-255取值范围)
                lower0 = int(st.number_input('H通道下限',min_value=0,max_value=255,value=40,step=1))
                lower1 = int(st.number_input('S通道下限',min_value=0,max_value=255,value=100,step=1))
                lower2 = int(st.number_input('V通道下限',min_value=0,max_value=255,value=100,step=1))
                
                st.write("HSV上限阈值")
                upper0 = int(st.number_input('H通道上限',min_value=0,max_value=255,value=60,step=1))
                upper1 = int(st.number_input('S通道上限',min_value=0,max_value=255,value=255,step=1))
                upper2 = int(st.number_input('V通道上限',min_value=0,max_value=255,value=255,step=1))

                # 统一提交按钮
                submit = st.form_submit_button('开始检测')
            
            low_val = [lower0,lower1,lower2]
            upper_val = [upper0,upper1,upper2]
            if submit:
                st.subheader(f"当前使用下限HSV值:{low_val}")
                st.subheader(f"当前使用上限HSV值:{upper_val}")
                detect_color(original_image,low_val,upper_val)

if __name__ == "__main__":
    detection()

注:OpenCV原生HSV的H通道取值范围是0-179,如果你后续要适配OpenCV原生HSV范围,把H通道输入框的max_value改成179,对应黄色H范围改成20-30即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:36:27