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
相关产品推荐
相关产品推荐

