为什么会黑屏,怎么解决

Viewed 44

重现步骤

我的问题是为什么会黑屏以及如何解决,之前我写了一版图像处理的代码,摄像头可以正常运行,功能都可以实现,现在其余部分都未改变,只改了图像处理里面的代码就黑屏了,而且,我明明写了sensor.reset(),后面跟了一句if not sensor.reset():
print("摄像头初始化失败"),结果还真打印了,想知道这是为什么,以及黑屏的原因,现在能运行但是黑屏,终端一直在打印No target stripes detected,我的代码如下:
import time, os, sys
from machine import Timer, UART # 导入machine模块中的Timer类和UART类
from media.sensor import *
from media.display import *
from media.media import *

sensor_id = 2
sensor = None
BLACK_THRESHOLD = (0, 30, 15, 45, -128, 30) # LAB黑色阈值
YELLOW_THRESHOLD = (70, 90, 20, 50, 15, 50) # LAB黄色阈值
WHITE_THRESHOLD = (70, 100, 15, 30, 15, 30) # LAB白色阈值
MIN_STRIPE_HEIGHT = 20 # 最小有效条纹高度
MERGE_DISTANCE = 10 # 黑黄条纹合并距离阈值
hit_start_time = 0
hit_duration = 0
is_hit = False
red_spot_detected_in_white = False # 标记是否在白色区域内检测到红色斑
picture_width = 480
picture_height = 480
obstacle_near = False
green_detected = False

#BUFFER_NUM = 4
#BUFFER_SIZE = 640 * 480

显示模式选择:可以是 "VIRT"、"LCD" 或 "HDMI"

DISPLAY_MODE = "LCD"

根据模式设置显示宽高

if DISPLAY_MODE == "VIRT":
# 虚拟显示器模式
DISPLAY_WIDTH = ALIGN_UP(1920, 16)
DISPLAY_HEIGHT = 1080
elif DISPLAY_MODE == "LCD":
# 3.1寸屏幕模式
DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 480
elif DISPLAY_MODE == "HDMI":
# HDMI扩展板模式
DISPLAY_WIDTH = 1920
DISPLAY_HEIGHT = 1080
else:
raise ValueError("未知的 DISPLAY_MODE,请选择 'VIRT', 'LCD' 或 'HDMI'")

初始化串口通讯

uart = UART(1, 115200) # 使用UART1,波特率115200
def find_stripes(img):
"""检测并配对黑黄条纹(优化版)"""
# 检测基础色块
black_blobs = img.find_blobs([BLACK_THRESHOLD], pixels_threshold=30,
area_threshold=30, merge=True, margin=5)
yellow_blobs = img.find_blobs([YELLOW_THRESHOLD], pixels_threshold=30,
area_threshold=30, merge=True, margin=5)

# 黑黄配对逻辑(关键改进)
paired_stripes = []
for yb in yellow_blobs:
    # 查找相邻的黑色色块
    near_black = [b for b in black_blobs
                if abs(b.cx() - yb.cx()) < MERGE_DISTANCE
                and abs(b.cy() - yb.cy()) < yb.h()]
    if near_black:
        # 合并最近的黑色色块
        closest_black = min(near_black, key=lambda x: abs(x.cy() - yb.cy()))
        paired_stripes.append({
            'color': ['yellow', 'black'],
            'rect': [yb.rect(), closest_black.rect()],
            'cy': (yb.cy() + closest_black.cy())//2  # 计算条纹中心y坐标
        })
        black_blobs.remove(closest_black)  # 防止重复使用

# 按中心y坐标排序
paired_stripes.sort(key=lambda x: x['cy'])
return paired_stripes

def find_white_region(img, search_type):
"""智能检测白色区域"""
img_h = img.height()
roi = None

if search_type == "upper":  # 检测上半部分
    roi = (0, 0, img.width(), img_h//2)
elif search_type == "lower":  # 检测下半部分
    roi = (0, img_h//2, img.width(), img_h//2)
else:  # 全图检测
    roi = (0, 0, img.width(), img_h)

# 检测白色区域
white_blobs = img.find_blobs([WHITE_THRESHOLD], pixels_threshold=200,
                           area_threshold=200, merge=True, margin=10, roi=roi)

if white_blobs:
    return max(white_blobs, key=lambda b: b.w()*b.h())
return None

try:
# 构造一个具有默认配置的摄像头对象
sensor = Sensor(id=sensor_id, width=1920, height=1080)
# 重置摄像头sensor
sensor.reset()
if not sensor.reset():
print("摄像头初始化失败")

# 无需进行镜像和翻转
# 设置不要水平镜像
sensor.set_hmirror(False)
# 设置不要垂直翻转
sensor.set_vflip(False)

sensor.set_framesize(width=picture_width, height=picture_height, chn=CAM_CHN_ID_0)
# 设置通道0的输出像素格式为RGB565,要注意有些案例只支持GRAYSCALE格式
sensor.set_pixformat(Sensor.RGB565, chn=CAM_CHN_ID_0)

# 根据模式初始化显示器
if DISPLAY_MODE == "VIRT":
    Display.init(Display.VIRT, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, fps=60)
elif DISPLAY_MODE == "LCD":
    Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
elif DISPLAY_MODE == "HDMI":
    Display.init(Display.LT9611, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)

# 初始化媒体管理器
MediaManager.init()
# 启动传感器
sensor.run()

fps = time.clock()

while True:
    fps.tick()
    os.exitpoint()
    img = sensor.snapshot(chn=CAM_CHN_ID_0)

    # 检测条纹
    stripes = find_stripes(img)
    valid_stripes = [s for s in stripes if s['rect'][0][3] >= MIN_STRIPE_HEIGHT]

    # 核心逻辑判断
    if len(valid_stripes) == 2:
        # 两个条纹:检测中间区域
        top = min(s['cy'] for s in valid_stripes)
        bottom = max(s['cy'] for s in valid_stripes)
        white_blob = find_white_region(img, "full")
        search_top = top
        search_bottom = bottom
    elif len(valid_stripes) == 1:
        # 单个条纹:根据位置判断检测方向
        stripe = valid_stripes[0]
        if stripe['cy'] < img.height()/2:
            # 上侧条纹:检测下半部分
            white_blob = find_white_region(img, "lower")
            search_top = stripe['cy'] + stripe['rect'][0][3]//2
            search_bottom = img.height()
        else:
            # 下侧条纹:检测上半部分
            white_blob = find_white_region(img, "upper")
            search_top = 0
            search_bottom = stripe['cy'] - stripe['rect'][0][3]//2
    else:
        print("No target stripes detected")
        continue

    # 绘制结果
    if white_blob:
        # 绘制检测框
        img.draw_rectangle(white_blob.rect(), color=(255,0,0))
        # 计算中心点
        center_x = white_blob.cx()
        center_y = white_blob.cy()
        img.draw_cross(center_x, center_y, size=10, color=(0,0,255))
        print(f"Center: ({center_x}, {center_y})")

    # 显示画面
    Display.show_image(img, x=0, y=0, layer=Display.LAYER_OSD0)
    print(f"FPS: {fps.fps():.1f}")

except KeyboardInterrupt as e:
print("用户停止: ", e)
except BaseException as e:
print(f"异常: {e}")
finally:
# 停止传感器运行
if isinstance(sensor, Sensor):
sensor.stop()
# 反初始化显示模块
Display.deinit()
MediaManager.deinit()
uart.deinit() # 反初始化串口
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
time.sleep_ms(100)

期待结果和实际结果

软硬件版本信息

错误日志

尝试解决过程

补充材料

1 Answers

这么描述有点看不出来是什么原因。

  1. 先排查一下vicap 是不是还在正常运行, 命令行中cat /proc/umap/vicap,查看
    ISP-DEV Input-Frames Output0-Frames Output1-Frames Output2-Frames
    0 96966 96966 0 0
    input 和 output 帧是否增加

  2. 屏幕显示是否正常,你可以将要显示的图像dump 出来看看、看看要显示图像是否正确,