《k230-AI_DEMO》物体辨认

刘俊凯  论坛元老 | 3 天前 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1802|帖子 1802|积分 5410

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
《k230-AI
  
  1. from libs.PipeLine import PipeLine, ScopedTiming
  2. from libs.AIBase import AIBase
  3. from libs.AI2D import Ai2d
  4. import os
  5. import ujson
  6. from media.media import *
  7. from time import *
  8. import nncase_runtime as nn
  9. import ulab.numpy as np
  10. import time
  11. import utime
  12. import image
  13. import random
  14. import gc
  15. import sys
  16. import aidemo
  17. from machine import PWM, FPIOA
  18. # 配置蜂鸣器IO口功能
  19. beep_io = FPIOA()
  20. beep_io.set_function(43, FPIOA.PWM1)
  21. # 初始化蜂鸣器PWM通道
  22. beep_pwm = PWM(1, 4000, 50, enable=False)  # 默认频率4kHz,占空比50%
  23.                           
  24. # 自定义YOLOv8检测类
  25. class ObjectDetectionApp(AIBase):
  26.     def __init__(self,kmodel_path,labels,model_input_size,max_boxes_num,confidence_threshold=0.5,nms_threshold=0.2,rgb888p_size=[224,224],display_size=[1920,1080],debug_mode=0):
  27.         super().__init__(kmodel_path,model_input_size,rgb888p_size,debug_mode)
  28.         self.kmodel_path=kmodel_path
  29.         self.labels=labels
  30.         # 模型输入分辨率
  31.         self.model_input_size=model_input_size
  32.         # 阈值设置
  33.         self.confidence_threshold=confidence_threshold
  34.         self.nms_threshold=nms_threshold
  35.         self.max_boxes_num=max_boxes_num
  36.         # sensor给到AI的图像分辨率
  37.         self.rgb888p_size=[ALIGN_UP(rgb888p_size[0],16),rgb888p_size[1]]
  38.         # 显示分辨率
  39.         self.display_size=[ALIGN_UP(display_size[0],16),display_size[1]]
  40.         self.debug_mode=debug_mode
  41.         # 检测框预置颜色值
  42.         self.color_four=[(255, 220, 20, 60), (255, 119, 11, 32), (255, 0, 0, 142), (255, 0, 0, 230),
  43.                          (255, 106, 0, 228), (255, 0, 60, 100), (255, 0, 80, 100), (255, 0, 0, 70),
  44.                          (255, 0, 0, 192), (255, 250, 170, 30), (255, 100, 170, 30), (255, 220, 220, 0),
  45.                          (255, 175, 116, 175), (255, 250, 0, 30), (255, 165, 42, 42), (255, 255, 77, 255),
  46.                          (255, 0, 226, 252), (255, 182, 182, 255), (255, 0, 82, 0), (255, 120, 166, 157)]
  47.         # 宽高缩放比例
  48.         self.x_factor = float(self.rgb888p_size[0])/self.model_input_size[0]
  49.         self.y_factor = float(self.rgb888p_size[1])/self.model_input_size[1]
  50.         # Ai2d实例,用于实现模型预处理
  51.         self.ai2d=Ai2d(debug_mode)
  52.         # 设置Ai2d的输入输出格式和类型
  53.         self.ai2d.set_ai2d_dtype(nn.ai2d_format.NCHW_FMT,nn.ai2d_format.NCHW_FMT,np.uint8, np.uint8)
  54.     # 配置预处理操作,这里使用了resize,Ai2d支持crop/shift/pad/resize/affine,具体代码请打开/sdcard/libs/AI2D.py查看
  55.     def config_preprocess(self,input_image_size=None):
  56.         with ScopedTiming("set preprocess config",self.debug_mode > 0):
  57.             # 初始化ai2d预处理配置,默认为sensor给到AI的尺寸,您可以通过设置input_image_size自行修改输入尺寸
  58.             ai2d_input_size=input_image_size if input_image_size else self.rgb888p_size
  59.             self.ai2d.resize(nn.interp_method.tf_bilinear, nn.interp_mode.half_pixel)
  60.             self.ai2d.build([1,3,ai2d_input_size[1],ai2d_input_size[0]],[1,3,self.model_input_size[1],self.model_input_size[0]])
  61.     # 自定义当前任务的后处理
  62.     def postprocess(self,results):
  63.         with ScopedTiming("postprocess",self.debug_mode > 0):
  64.             result=results[0]
  65.             result = result.reshape((result.shape[0] * result.shape[1], result.shape[2]))
  66.             output_data = result.transpose()
  67.             boxes_ori = output_data[:,0:4]
  68.             scores_ori = output_data[:,4:]
  69.             confs_ori = np.max(scores_ori,axis=-1)
  70.             inds_ori = np.argmax(scores_ori,axis=-1)
  71.             boxes,scores,inds = [],[],[]
  72.             for i in range(len(boxes_ori)):
  73.                 if confs_ori[i] > confidence_threshold:
  74.                     scores.append(confs_ori[i])
  75.                     inds.append(inds_ori[i])
  76.                     x = boxes_ori[i,0]
  77.                     y = boxes_ori[i,1]
  78.                     w = boxes_ori[i,2]
  79.                     h = boxes_ori[i,3]
  80.                     left = int((x - 0.5 * w) * self.x_factor)
  81.                     top = int((y - 0.5 * h) * self.y_factor)
  82.                     right = int((x + 0.5 * w) * self.x_factor)
  83.                     bottom = int((y + 0.5 * h) * self.y_factor)
  84.                     boxes.append([left,top,right,bottom])
  85.             if len(boxes)==0:
  86.                 return []
  87.             boxes = np.array(boxes)
  88.             scores = np.array(scores)
  89.             inds = np.array(inds)
  90.             # NMS过程
  91.             keep = self.nms(boxes,scores,nms_threshold)
  92.             dets = np.concatenate((boxes, scores.reshape((len(boxes),1)), inds.reshape((len(boxes),1))), axis=1)
  93.             dets_out = []
  94.             for keep_i in keep:
  95.                 dets_out.append(dets[keep_i])
  96.             dets_out = np.array(dets_out)
  97.             dets_out = dets_out[:self.max_boxes_num, :]
  98.             return dets_out
  99.     # 绘制结果
  100.     def draw_result(self,pl,dets):
  101.         with ScopedTiming("display_draw",self.debug_mode >0):
  102.             if dets:
  103.                 pl.osd_img.clear()
  104.                 for det in dets:
  105.                     x1, y1, x2, y2 = map(lambda x: int(round(x, 0)), det[:4])
  106.                     x= x1*self.display_size[0] // self.rgb888p_size[0]
  107.                     y= y1*self.display_size[1] // self.rgb888p_size[1]
  108.                     w = (x2 - x1) * self.display_size[0] // self.rgb888p_size[0]
  109.                     h = (y2 - y1) * self.display_size[1] // self.rgb888p_size[1]
  110.                     pl.osd_img.draw_rectangle(x,y, w, h, color=self.get_color(int(det[5])),thickness=4)
  111.                     l_in=int(det[5])
  112.                     l_in=self.labels[l_in]
  113.                     pl.osd_img.draw_string_advanced( x , y-50,32," " + self.labels[int(det[5])] + " " + str(round(det[4],2)) , color=self.get_color(int(det[5])))
  114.                     if l_in == "person":
  115.                         
  116.                                             
  117.                      # 使能PWM通道输出
  118.                         beep_pwm.enable(1)
  119.                                                    # 延时50ms
  120.                         time.sleep_ms(50)
  121.                                                    # 关闭PWM输出 防止蜂鸣器吵闹
  122.                         beep_pwm.enable(0)
  123.                        
  124.             else:
  125.                 pl.osd_img.clear()
  126.     # 多目标检测 非最大值抑制方法实现
  127.     def nms(self,boxes,scores,thresh):
  128.         """Pure Python NMS baseline."""
  129.         x1,y1,x2,y2 = boxes[:, 0],boxes[:, 1],boxes[:, 2],boxes[:, 3]
  130.         areas = (x2 - x1 + 1) * (y2 - y1 + 1)
  131.         order = np.argsort(scores,axis = 0)[::-1]
  132.         keep = []
  133.         while order.size > 0:
  134.             i = order[0]
  135.             keep.append(i)
  136.             new_x1,new_y1,new_x2,new_y2,new_areas = [],[],[],[],[]
  137.             for order_i in order:
  138.                 new_x1.append(x1[order_i])
  139.                 new_x2.append(x2[order_i])
  140.                 new_y1.append(y1[order_i])
  141.                 new_y2.append(y2[order_i])
  142.                 new_areas.append(areas[order_i])
  143.             new_x1 = np.array(new_x1)
  144.             new_x2 = np.array(new_x2)
  145.             new_y1 = np.array(new_y1)
  146.             new_y2 = np.array(new_y2)
  147.             xx1 = np.maximum(x1[i], new_x1)
  148.             yy1 = np.maximum(y1[i], new_y1)
  149.             xx2 = np.minimum(x2[i], new_x2)
  150.             yy2 = np.minimum(y2[i], new_y2)
  151.             w = np.maximum(0.0, xx2 - xx1 + 1)
  152.             h = np.maximum(0.0, yy2 - yy1 + 1)
  153.             inter = w * h
  154.             new_areas = np.array(new_areas)
  155.             ovr = inter / (areas[i] + new_areas - inter)
  156.             new_order = []
  157.             for ovr_i,ind in enumerate(ovr):
  158.                 if ind < thresh:
  159.                     new_order.append(order[ovr_i])
  160.             order = np.array(new_order,dtype=np.uint8)
  161.         return keep
  162.     # 根据当前类别索引获取框的颜色
  163.     def get_color(self, x):
  164.         idx=x%len(self.color_four)
  165.         return self.color_four[idx]
  166. if __name__=="__main__":
  167.     # 显示模式,默认"hdmi",可以选择"hdmi"和"lcd"
  168.     display_mode="lcd"
  169.     if display_mode=="hdmi":
  170.         display_size=[1920,1080]
  171.     else:
  172.         display_size=[800,480]
  173.     # 模型路径
  174.     kmodel_path="/sdcard/examples/kmodel/yolov8n_320.kmodel"
  175.     labels = ["person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"]
  176.     # 其它参数设置
  177.     confidence_threshold = 0.2
  178.     nms_threshold = 0.2
  179.     max_boxes_num = 50
  180.     rgb888p_size=[320,320]
  181.     # 初始化PipeLine
  182.     pl=PipeLine(rgb888p_size=rgb888p_size,display_size=display_size,display_mode=display_mode)
  183.     pl.create()
  184.     # 初始化自定义目标检测实例
  185.     ob_det=ObjectDetectionApp(kmodel_path,labels=labels,model_input_size=[320,320],max_boxes_num=max_boxes_num,confidence_threshold=confidence_threshold,nms_threshold=nms_threshold,rgb888p_size=rgb888p_size,display_size=display_size,debug_mode=0)
  186.     ob_det.config_preprocess()
  187.     clock = time.clock()
  188.     while True:
  189.         clock.tick()
  190.         img=pl.get_frame() # 获取当前帧数据
  191.         res=ob_det.run(img) # 推理当前帧
  192.         ob_det.draw_result(pl,res) # 绘制结果到PipeLine的osd图像
  193.         pl.show_image() # 显示当前的绘制结果
  194.         gc.collect()
  195.         print(clock.fps()) #打印帧率
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

刘俊凯

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表