问题描述
求助,因为用了滤光片,画面都是红色的感觉不好看,怎么才能变成灰色呢
硬件板卡
K230mini
软件版本
v2.9.0
可以设置sensor的绑定通道配置灰度图
把下面的代码保存成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两个函数