求助YOLO跑识别的时候怎么让LCD显示灰度图像

Viewed 49

问题描述


求助,因为用了滤光片,画面都是红色的感觉不好看,怎么才能变成灰色呢

硬件板卡


K230mini

软件版本


v2.9.0

2 Answers

可以设置sensor的绑定通道配置灰度图

怎么弄的呀,我之前卡了好几个星期都弄不好,我在pipeline里面改了Sensor.YUV420SP 运行不了, 说是视频流只支持这个格式,然后我的yolo也是用的灰度识别的只不过是跑了一下3通道矩阵计算,也不是原始灰度图。求助大佬

我明天看一下

把下面的代码保存成Pipeline.py文件拷贝到CanMV/sdcard/libs目录下覆盖原有的Pipeline.py:

import os
import ujson
from media.sensor import *
from media.display import *
from media.media import *
from libs.Utils import ScopedTiming
import ulab.numpy as np
import image
import gc
import sys
import time
import _thread

# PipeLine类
class PipeLine:
    def __init__(self,rgb888p_size=[224,224],display_mode="hdmi",display_size=None,osd_layer_num=1,debug_mode=0):
        # sensor给AI的图像分辨率
        self.rgb888p_size=[ALIGN_UP(rgb888p_size[0],16),rgb888p_size[1]]
        # 视频输出VO图像分辨率
        if display_size is None:
            self.display_size=None
        else:
            self.display_size=[display_size[0],display_size[1]]
        # 视频显示模式,支持:"lcd"(default st7701), "hdmi"(default lt9611), "lt9611", "st7701", "hx8399", "nt35516", "nt35532", "gc9503", "aml020t", "jd9852", "ili9806", "virt";若选择"virt",可通过display_size自定义分辨率
        self.display_mode=display_mode
        # sensor对象
        self.sensor=None
        # osd显示Image对象
        self.osd_img=None
        self.cur_frame=None
        self.debug_mode=debug_mode
        self.osd_layer_num = osd_layer_num
        self.crop_param=[0,0,0,0]
        self.run=True

    # PipeLine初始化函数
    def create(self,sensor=None,sensor_id=None,hmirror=None,vflip=None,fps=60,to_ide=True,crop_vertical=False):
        with ScopedTiming("init PipeLine",self.debug_mode > 0):
            if self.display_mode=="nt35516":
                fps=30
            # 默认 FPS
            default_fps = 30
            # 支持指定 FPS 的板子类型
            fps_map = {
                "k230d_canmv_bpi_zero": default_fps,
                "k230_canmv_lckfb": default_fps,
                "k230d_canmv_atk_dnk230d": default_fps,
            }

            # 获取板子类型
            brd = os.uname()[-1]
            # 决定使用的 FPS
            board_fps = fps_map.get(brd, fps)
            # 初始化 sensor
            if sensor_id is not None:
                self.sensor = sensor if sensor is not None else Sensor(id=sensor_id, fps=board_fps)
            else:
                self.sensor = sensor if sensor is not None else Sensor(fps=board_fps)
            # 重置并设置镜像/翻转
            self.sensor.reset()
            if isinstance(hmirror, bool):
                self.sensor.set_hmirror(hmirror)
            if isinstance(vflip, bool):
                self.sensor.set_vflip(vflip)


            DISPLAY_MAP = {
                "hdmi":     Display.LT9611,
                "lt9611":   Display.LT9611,
                "lcd":      Display.ST7701,
                "st7701":   Display.ST7701,
                "hx8399":   Display.HX8399,
                "nt35516":  Display.NT35516,
                "nt35532":  Display.NT35532,
                "gc9503":   Display.GC9503,
                "aml020t":  Display.AML020T,
                "jd9852":   Display.JD9852,
                "ili9806":  Display.ILI9806,
                "virt":     Display.VIRT,
            }

            # Look up type, fallback to ST7701 if not found
            display_type = DISPLAY_MAP.get(self.display_mode, Display.ST7701)

            # Call init
            if self.display_size:
                Display.init(
                    display_type,
                    width=self.display_size[0],
                    height=self.display_size[1],
                    osd_num=self.osd_layer_num,
                    to_ide=to_ide
                )
            else:
                Display.init(
                    display_type,
                    osd_num=self.osd_layer_num,
                    to_ide=to_ide
                )
                # Update actual size after init
                self.display_size = [Display.width(), Display.height()]

            if crop_vertical:
                r=1080/self.display_size[1]
                crop_w=int(r*self.display_size[0])
                crop_h=1080
                crop_x=(1920-crop_w)//2
                crop_y=0
                self.crop_param=[crop_x,crop_y,crop_w,crop_h]
                # 通道0直接给到显示VO,格式为YUV420
                self.sensor.set_framesize(w = self.display_size[0], h = self.display_size[1],chn=CAM_CHN_ID_0,crop=(crop_x,crop_y,crop_w,crop_h))
                self.sensor.set_pixformat(Sensor.GRAYSCALE, chn=CAM_CHN_ID_0)
                # 通道2给到AI做算法处理,格式为RGB888
                self.sensor.set_framesize(w = self.rgb888p_size[0], h = self.rgb888p_size[1], chn=CAM_CHN_ID_2,crop=(crop_x,crop_y,crop_w,crop_h))
                self.sensor.set_pixformat(Sensor.RGBP888, chn=CAM_CHN_ID_2)
            else:
                # 通道0直接给到显示VO,格式为YUV420
                self.sensor.set_framesize(w = self.display_size[0], h = self.display_size[1],chn=CAM_CHN_ID_0)
                self.sensor.set_pixformat(Sensor.GRAYSCALE, chn=CAM_CHN_ID_0)
                # 通道2给到AI做算法处理,格式为RGB888
                self.sensor.set_framesize(w = self.rgb888p_size[0], h = self.rgb888p_size[1], chn=CAM_CHN_ID_2)
                self.sensor.set_pixformat(Sensor.RGBP888, chn=CAM_CHN_ID_2)

            # OSD图像初始化
            self.osd_img = image.Image(self.display_size[0], self.display_size[1], image.ARGB8888)

            #sensor_bind_info = self.sensor.bind_info(x = 0, y = 0, chn = CAM_CHN_ID_0)
            #Display.bind_layer(**sensor_bind_info, layer = Display.LAYER_VIDEO1)

            # 启动sensor
            self.sensor.run()
            
    def show_gray(self):
        while self.run:
            img=self.sensor.snapshot(chn=CAM_CHN_ID_0)
            Display.show_image(img)
        print("show gray stop")
        return
            
    def start_gray_display(self):
        _thread.start_new_thread(self.show_gray,())

    # 获取一帧图像数据,返回格式为ulab的array数据
    def get_frame(self):
        with ScopedTiming("get a frame",self.debug_mode > 0):
            self.cur_frame = self.sensor.snapshot(chn=CAM_CHN_ID_2)
            input_np=self.cur_frame.to_numpy_ref()
            return input_np

    # 在屏幕上显示osd_img
    def show_image(self,flag=None):
        with ScopedTiming("show result",self.debug_mode > 0):
            if flag is None:
                Display.show_image(self.osd_img, 0, 0, Display.LAYER_OSD3)
            else:
                Display.show_image(self.osd_img, 0, 0, Display.LAYER_OSD3,flag=flag)

    def get_display_size(self):
        return self.display_size
        
    def stop_gray_display(self):
        self.run=False
        time.sleep(1)
        
    # PipeLine销毁函数
    def destroy(self):
        with ScopedTiming("deinit PipeLine",self.debug_mode > 0):
            os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
            # stop sensor
            self.sensor.stop()
            # deinit lcd
            Display.deinit()

然后修改你的应用文件比如,人脸检测:

if __name__ == "__main__":
    # 添加显示模式,默认hdmi,可选hdmi/lcd/lt9611/st7701/hx8399/nt35516/nt35532/gc9503/aml020t/jd9852/ili9806/virt;其中hdmi默认对应lt9611,lcd默认对应st7701
    display_mode="lcd"
    # 显示分辨率,None表示使用当前显示屏默认分辨率;使用virt时可在这里手动设置,例如[800, 480]
    display_size=None
    # k230保持不变,k230d可调整为[640,360]
    rgb888p_size = [1280, 720]
    # 设置模型路径和其他参数
    kmodel_path = "/sdcard/examples/kmodel/face_detection_320.kmodel"
    # 其它参数
    confidence_threshold = 0.5
    nms_threshold = 0.2
    anchor_len = 4200
    det_dim = 4
    anchors_path = "/sdcard/examples/utils/prior_data_320.bin"
    anchors = np.fromfile(anchors_path, dtype=np.float)
    anchors = anchors.reshape((anchor_len, det_dim))

    # 初始化PipeLine,rgb888p_size为传给AI的图像分辨率,display_size为显示分辨率
    pl = PipeLine(rgb888p_size=rgb888p_size, display_mode=display_mode, display_size=display_size)
    # 创建PipeLine,可按需传入sensor_id选择摄像头,例如pl.create(sensor_id=2)
    pl.create()  # 创建PipeLine实例
    display_size=pl.get_display_size()
    # 初始化自定义人脸检测实例
    face_det = FaceDetectionApp(kmodel_path, model_input_size=[320, 320], anchors=anchors, confidence_threshold=confidence_threshold, nms_threshold=nms_threshold, rgb888p_size=rgb888p_size, display_size=display_size, debug_mode=0)
    face_det.config_preprocess()  # 配置预处理
    pl.start_gray_display()
    try:
        while True:
            with ScopedTiming("total",1):
                img = pl.get_frame()            # 获取当前帧数据
                res = face_det.run(img)         # 推理当前帧
                face_det.draw_result(pl, res)   # 绘制结果
                pl.show_image()                 # 显示结果
                gc.collect()
    except BaseException as e:
        import sys
        sys.print_exception(e)
        pl.stop_gray_display()
    finally:
        face_det.deinit()                       # 反初始化
        pl.destroy()                            # 销毁PipeLine实例

添加try-except-finally,调用pl.start_gray_display和pl.stop_gray_display两个函数

感谢大神

但是,大佬,我用灰度显示的时候,yolo能正常跑和刷新识别框,但是我有其他的程序他就会osd_img画布上面1/3是动的 下面2/3是不动的 是为什么呀?添加的代码是对计算像素能量的,可能运行时间多一些

时间多长?