🇳 🇴 🇻 🇮 🇨 🇪 · 2022年12月04日 · 北京市昌平区

聆思CSK6 视觉AI开发套件试用】CSK6视觉套件与Jetson Nano套件的上手初体验比较

产品介绍

Jetson Nano 可为运行现代 AI 算法提供 472 GFLOPS 的计算性能。它能并行运行多个神经网络并同时处理多个高分辨率的传感器,颇为适合在 NVR 和智能网关领域的应用程序。Jetson Nano 可为运行现代 AI 算法提供 472 GFLOPS 的计算性能。它能并行运行多个神经网络并同时处理多个高分辨率的传感器,颇为适合在 NVR 和智能网关领域的应用程序。

CSK6 是聆思科技新一代的 AI 芯片 SoC 产品系列,采用多核异构架构,集成了安谋科技STAR-MC1 处理器,HiFi4 DSP,以及聆思全新设计的 AI 神经网络处理内核 NPU,算力达到 128 GOPS。多核异构的设计使芯片能以较低功耗满足音频及图像视频的 AI 应用需求。CSK6 是聆思科技新一代的 AI 芯片 SoC 产品系列,采用多核异构架构,集成了 ARM Star MCU,HiFi4 DSP,以及聆思全新设计的 AI 神经网络处理内核 NPU,算力达到 128 GOPS。多核异构的设计使芯片能以较低功耗满足音频及图像视频的 AI 应用需求。CSK6 是聆思科技新一代的 AI 芯片 SoC 产品系列,采用多核异构架构,集成了 ARM Star MCU,HiFi4 DSP,以及聆思全新设计的 AI 神经网络处理内核 NPU,算力达到 128 GOPS。多核异构的设计使芯片能以较低功耗满足音频及图像视频的 AI 应用需求。

硬件IO接口CSK6多达33个可灵活配置的GPIO,还未来得及体验,Jetson Nano 40pin共有 18 根与开发套件底板电子电力直连的脚位,这是不能重新定义的固定功能,比CSK6少了11个。

CSK6S很友好的提供视觉SDK示例 app_algo_hsd_sample_for_csk6头肩识别 和视觉SDK示例 app_algo_fd_sample_for_csk6 人脸识别供大家入门。

开发入门对比

本次开发的环境是在ubuntu20.04的环境下进行的,在开发的过程非常的顺利,不得不说这是我用的最丝滑的开发板之一。上手非常的快,官网的教程也写的非常棒,跟着文档一步步去实现正常都能实现效果。

先发一个在jetson nano上的口罩识别,
100da0521121671a9219c275123bd6c.jpg
帧率大于25分辨率是1920*1080,使用tensorrt加速的yolov5-6.1

CSK6环境搭建一键操作,搭建完如

lisa info zep

Operating System - #59~20.04.1-Ubuntu SMP Thu Oct 20 15:10:22 UTC 2022, version 5.15.0-53-generic x64 

@listenai/lisa - 2.4.5

Account - 未登录或登录已过期

Node.js environment 
  Node.js - v16.14.0
  npm - 8.3.1
  yarn - 1.22.19

Global environment
  git - git version 2.25.1 

Plugin info 
  zep - 1.6.8 (latest: 1.6.8)

Plugin environment 
  env - csk6
  west - West version: v0.14.0
  venv - Python 3.9.7
  cmake - cmake version 3.21.4
  dtc - Version: DTC 1.6.0
  gperf - GNU gperf 3.1
  mklfs - v1.0.0 (3640bfb)
  ninja - 1.10.2
  protoc - libprotoc 3.19.1
  xz - xz (XZ Utils) 5.2.5
  cskburn - v1.18.1 (265)
  zephyr-sdk-0.14.2 - arm-zephyr-eabi-gcc (Zephyr SDK 0.14.2) 10.3.0
  gcc-arm-none-eabi-10.3 - arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10) 10.3.1 20210824 (release)
  jlink-venus - V7.58
  ZEPHYR_BASE - /home/ljx/.listenai/csk-sdk/zephyr (版本: v1.1.1-alpha.2, commit: 3e15ca75)
  PLUGIN_HOME - /home/ljx/.listenai/lisa-zephyr
  VIRTUAL_ENV - /home/ljx/.listenai/lisa-zephyr/venv
  ZEPHYR_TOOLCHAIN_VARIANT - zephyr
  ZEPHYR_SDK_INSTALL_DIR - /home/ljx/.listenai/lisa-zephyr/packages/node_modules/@binary/zephyr-sdk-0.14.2/binary
  GNUARMEMB_TOOLCHAIN_PATH - /home/ljx/.listenai/lisa-zephyr/packages/node_modules/@binary/gcc-arm-none-eabi-10.3/binary

烧录过程中出现无法烧录的状态,usb改一下权限就好了,没发现其他问题,上手比nano容易,Jetson经常出现各种无法烧录的问题。

cat vim /etc/udev/rules.d/50-usbcan.rules
cat: vim: No such file or directory
SUBSYSTEMS=="usb", 
ATTRS{idVendor}=="0d28", 
ATTRS{idProduct}=="0204", 
GROUP="users", 
MODE="0666"
ls /dev/bus/usb/ -IR
sudo chmod 666 /dev/bus/usb/* 
sudo udevadm control --reload

未命名1670116451.png

应该是没有加速引擎的加持精度还可以,官方很贴心的在头肩识别的基础上增加了人脸识别还有功能按键保存,对比如下,后期有时间可以根据源码添加自己的扩展功能。

/app_algo_fd_sample_for_csk6$ ls ../app_algo_hsd_sample_for_csk6/src/
bitmap.c  bitmap.h  camera_monitor.c  main.c
ljx@ubuntu:~/app_algo_fd_sample_for_csk6$ cd src/
ljx@ubuntu:~/app_algo_fd_sample_for_csk6/src$ ls
bitmap.c  bitmap.h  button.c  button.h  camera_monitor.c  main.c  multi_button.c  multi_button.h  storage.c  storage.h

main.c对比

ljx@ubuntu:~/app_algo_hsd_sample_for_csk6/src$ diff main.c ../../app_algo_fd_sample_for_csk6/src/main.c 
8a9
> #include <licak/modules/fd/fd.h>
12a14
> #include <zephyr/multi_heap/shared_multi_heap.h>
14c16
< #define LOG_LEVEL 4
---
> // #define LOG_LEVEL 4
23a26,28
> #include "storage.h"
> #include "button.h"
> 
27,30d31
< // 240p
< // #define IMAGE_HEIGHT 240
< // #define IMAGE_WIDTH 320
< // 480p
38c39
< #include "input_640x480.h"
---
> #include "image_640x480.h"
42a44,46
> #define WEBUSB_IMAGE_DOWNSAMPLING (2)
> #define WEBUSB_IMAGE_SCALE (1.0f / WEBUSB_IMAGE_DOWNSAMPLING)
> 
44,47c48
<   hsd_head_shoulder_detect result;
<   head_shoulder_detect hsd;
<   uint32_t data_len;
<   hsd_event event;
---
>   char text[256];
50c51,61
< const struct device *video;
---
> typedef struct {
>     float feature[FD_MAX_FEATURE_DIMS];
>     float feature_nvs[FD_MAX_FEATURE_DIMS];
>     bool get_new_feature;
>     fd_t *fd;
>     bool is_usb_cfg;
>     const struct device *video;
>     struct video_format fmt;
>     char result_txt[512];
>     struct k_msgq msg;
> } face_register_t;
52c63
< bool is_usb_cfg;
---
> face_register_t fr;
54d64
< struct k_msgq msg;
56c66,69
< int64_t time;
---
> #ifdef CONFIG_WEBUSB
> void webusb_send_pic(struct video_buffer *vbuf, fd_face_recog_result_t *result)
> {
>     float scale;
58,62c71,73
< void on_receive_hsd_result(hsd_t *hsd, hsd_event event, void *data,
<     void *user_data) {
<   if (event == HSD_EVENT_HEAD_SHOULDER) {
<     hsd_head_shoulder_detect *result = (hsd_head_shoulder_detect *)data;
<     LOG_INF("head shoulder cnt: %d", result->track_count);
---
>     if(!fr.is_usb_cfg){
>         return;
>     }
64,67c75,89
< #ifdef CONFIG_WEBUSB
<     msg_data_t msg_data = {
<       .data_len = result->len,
<       .event = event,
---
> #if MOCK_DATA
>     scale = 1;
>     img_info_t img_info = {
>         .width = IMAGE_WIDTH,
>         .height = IMAGE_HEIGHT,
>         .format = FORMAT_BGR888,
>         .scale = scale
>     };
> #else
>     scale = WEBUSB_IMAGE_SCALE;
>     img_info_t img_info = {
>         .width = IMAGE_WIDTH,
>         .height = IMAGE_HEIGHT,
>         .format = FORMAT_VYUY_422,
>         .scale = WEBUSB_IMAGE_SCALE
68a91
> #endif
70c93
<     memcpy(&msg_data.result, result, sizeof(msg_data.result));
---
>     send_image_info(img_info);
72,76c95,139
<     k_msgq_put(&msg, &msg_data, K_NO_WAIT);
< #endif
<   } else if (event == HSD_EVENT_GESTURE_RECOGNIZE) {
<     head_shoulder_detect *result = (head_shoulder_detect *)data;
<     LOG_INF("gesture result id: %d ,state: %d", result->id, result->gesture_state);
---
>     //PC只显示一个
>     if(result->detect_cnt > 0){
>         face_t face = {
>             .x = result->detect_data[0].detect_rect.x,
>             .y = result->detect_data[0].detect_rect.y,
>             .w = result->detect_data[0].detect_rect.w,
>             .h = result->detect_data[0].detect_rect.h,
>             .detect_score = result->detect_data[0].detect_score,
>             .feature_dim = result->detect_data[0].feature_dim,
>             .id = 1
>         };
>         sprintf((char *)fr.result_txt, "head_yaw: %3.0f\r\nhead_pitch: %3.0f\r\nhead_roll: %3.0f\r\nhead_pose_status: %d\r\nanti_spoofing_score: %3.2f\r\nanti_spoofing_status: %d",
>                                         result->detect_data[0].head_yaw,
>                                         result->detect_data[0].head_pitch,
>                                         result->detect_data[0].head_roll,
>                                         result->detect_data[0].head_pose_status,
>                                         result->detect_data[0].anti_spoofing_score,
>                                         result->detect_data[0].anti_spoofing_status);
> 
>         send_face(face, (char *)fr.result_txt);  
>     }    
> 
>     if(scale != 1){
>         uint32_t dst_width = IMAGE_WIDTH * scale;
>         uint32_t dst_height = IMAGE_HEIGHT * scale;
>         uint32_t data_len = dst_width * dst_height * 2;
>         uint8_t *out = (uint8_t *)csk_malloc(data_len);
> 
>         if (out == NULL) {
>             LOG_ERR("Failed to alloc image buffer");
>             return;
>         }
> 
>         if(img_info.format == FORMAT_BGR888){
>             img_scale(vbuf->buffer, out, IMAGE_WIDTH, IMAGE_HEIGHT, scale);
>         }else{
>             yuv_scale(vbuf->buffer, out, IMAGE_WIDTH, IMAGE_HEIGHT, scale);
>         }
>         
>         send_bitmap(out, data_len);
> 
>         csk_free(out);    
>     }else{
>         send_bitmap(vbuf->buffer, vbuf->size);
>     }
78,79c141,145
< #ifdef CONFIG_WEBUSB
<     msg_data_t msg_data = { .event = event };
---
>     msg_data_t msg_data;
>     int ret = k_msgq_get(&fr.msg, &msg_data, K_NO_WAIT);
>     if (ret == 0) {
>         send_message(msg_data.text);
>     }
81c147
<     memcpy(&msg_data.hsd, result, sizeof(msg_data.hsd));
---
> }
83,85c149,172
<     k_msgq_put(&msg, &msg_data, K_NO_WAIT);
< #endif
<   }
---
> void webusb_status_callback(struct usb_cfg_data *cfg, enum usb_dc_status_code status, const uint8_t *param) {
>     /* Check the USB status and do needed action if required */
>     switch (status) {
>         case USB_DC_ERROR:
>             LOG_DBG("USB device error");
>             break;
>         case USB_DC_RESET:
>             LOG_DBG("USB device reset detected");
>             break;
>         case USB_DC_CONNECTED:
>             LOG_DBG("USB device connected");
>             break;
>         case USB_DC_CONFIGURED:
>             LOG_DBG("USB device configured");
>             fr.is_usb_cfg = true;
>             break;
>         case USB_DC_DISCONNECTED:
>             LOG_DBG("USB device disconnected");
>             fr.is_usb_cfg = false;
>             break;
>         default:
>             LOG_DBG("USB unknown state");
>             break;
>     }
88,155c175,182
< #ifdef CONFIG_WEBUSB
< void handle_shoulder_data(msg_data_t msg_data) {
<   if (!is_usb_cfg) {
<     LOG_WRN("USB hasn't been configured yet");
<     return;
<   }
< 
<   float scale = 0.25f;
< 
<   img_info_t img_info = {
<     .width = msg_data.result.width,
<     .height = msg_data.result.height,
<     .format = FORMAT_BGR888,
<     .scale = scale
<   };
< 
<   send_image_info(img_info);
< 
<   if (msg_data.result.track_count > 0) {
<     uint32_t send_len = sizeof(shoulder_t) * msg_data.result.track_count;
<     uint8_t *send = k_malloc(send_len);
< 
<     int index = 0;
< 
<     for (int i = 0; i < msg_data.result.track_count; i++) {
<       head_shoulder_detect item = msg_data.result.result[i];
< 
<       shoulder_t shoulder = {
<         .x = item.rect.x,
<         .y = item.rect.y,
<         .w = item.rect.w,
<         .h = item.rect.h,
<         .score = item.score,
<         .iou_score = item.iou_score,
<         .detect_loss_cnt = item.detect_loss_cnt,
<         .id = item.id,
<         .loss_cnt_thres = item.loss_cnt_thres,
<         .update = item.update
<       };
< 
<       uint8_t *temp = (uint8_t *)(&shoulder);
< 
<       for (int j = 0; j < sizeof(shoulder); j++) {
<         send[index] = temp[j];
<         index += 1;
<       }
<     }
< 
<     send_shoulder(send, send_len);
< 
<     k_free(send);
<   }
< 
<   uint32_t dst_width = msg_data.result.width * scale;
<   uint32_t dst_height = msg_data.result.height * scale;
<   uint32_t data_len = dst_width * dst_height * 3;
<   uint8_t *out = (uint8_t *)csk_malloc(data_len);
< 
<   if (out == NULL) {
<     LOG_ERR("Failed to alloc image buffer");
<     return;
<   }
< 
<   img_scale(msg_data.result.data, out, msg_data.result.width, msg_data.result.height, scale);
< 
<   if (send_bitmap(out, data_len) < 0) {
<     LOG_WRN("send_bitmap FAILED.");
<   }
---
> void webusb_send_message(char *txt){
>     uint32_t len = strlen(txt);
>     msg_data_t *msg = csk_malloc(sizeof(msg_data_t));
>     if(msg == NULL){
>         LOG_ERR("[%s] failed to allocate memory", __FUNCTION__);
>     }
>     
>     memset((void *)msg->text, 0, sizeof(msg_data_t));
157,158c184
<   csk_free(out);
< }
---
>     memcpy((void *)msg->text, (void *)txt, len);
160,183c186,189
< void webusb_status_callback(struct usb_cfg_data *cfg, enum usb_dc_status_code status, const uint8_t *param) {
<   /* Check the USB status and do needed action if required */
<   switch (status) {
<   case USB_DC_ERROR:
<     LOG_DBG("USB device error");
<     break;
<   case USB_DC_RESET:
<     LOG_DBG("USB device reset detected");
<     break;
<   case USB_DC_CONNECTED:
<     LOG_DBG("USB device connected");
<     break;
<   case USB_DC_CONFIGURED:
<     LOG_DBG("USB device configured");
<     is_usb_cfg = true;
<     break;
<   case USB_DC_DISCONNECTED:
<     LOG_DBG("USB device disconnected");
<     is_usb_cfg = false;
<     break;
<   default:
<     LOG_DBG("USB unknown state");
<     break;
<   }
---
>     k_msgq_put(&fr.msg, msg, K_NO_WAIT); 
> 
>     csk_free(msg);
>  
185d190
< #endif
187,189c192,193
< void main(void) {
< #ifdef CONFIG_WEBUSB
<   register_webusb_status_cb(webusb_status_callback);
---
> void button_callback(uint32_t event){
>     int ret = 0;
191,194c195,259
<   if (0 != webusb_enable()) {
<     LOG_ERR("Failed to enable USB");
<     return;
<   }
---
>     switch(event){
>         case BUTTON_SINGLE_CLICK:
>             if(fr.get_new_feature){
>                 uint16_t cnt = 0;
>                 uint8_t done = 0;
>                 fr.get_new_feature = false;
>                 
>                 fd_cmd_compare_feature_data_t data;
>                 fd_cmd_compare_feature_result_t result;
>                 data.feature_dim = FD_MAX_FEATURE_DIMS;
>                 data.feature_src = fr.feature_nvs;
>                 data.feature_dst = fr.feature;
> 
>                 storage_get_data_cnt(&cnt);
>                 for(uint32_t i = 0; i < cnt; i++){
>                     storage_read_data(i, (void *)fr.feature_nvs, sizeof(fr.feature));
>                     ret = fd_control(fr.fd, FD_CMD_COMPARE_FEATURE, &data, &result);
>                     if(ret != 0){
>                         LOG_ERR("feature_compare faild %d", ret);
>                     }
> 
>                     LOG_INF("feature_compare score = %f", result.score);
>                     if(result.score > 0.95){
>                         done = 1;
>                     }
>                 }
>                 if(done){
>                     webusb_send_message("face_calc_similar: success");
> 
>                 }else{
>                     webusb_send_message("face_calc_similar: fail");
>                 } 
>             }else{
>                 webusb_send_message("face_calc_similar: fail");
>                 LOG_INF("not detected face feature");
>             }      
>             break;
>         case BUTTON_LONG_PRESS:
>             if(fr.get_new_feature){
>                 uint16_t cnt = 0;
>                 fr.get_new_feature = false;
>                 char *txt = csk_malloc(64);
>                 
>                 storage_write((void *)fr.feature, sizeof(fr.feature));
> 
>                 storage_get_data_cnt(&cnt);
>                 sprintf(txt, "face_recognize: success, count:%d", cnt);
>                 webusb_send_message(txt);
>                 csk_free(txt);
> 
>                 LOG_INF("face feature save success");
>             }else{
>                 webusb_send_message("face_recognize: fail");
> 
>                 LOG_INF("not detected face feature");
>             }  
>             break;
>         case BUTTON_DOUBLE_CLICK:
>             storage_clear_data();
>             webusb_send_message("clear_face _data: success, count: 0");
>             break;
>         default:
>             break;
>     }
> }
197,232c262,279
<   if (0 != licak_init()) {
<     printk("LICAK init failed,exit.\n");
<     return;
<   }
< 
<   video = device_get_binding(VIDEO_DEV);
< 
<   if (video == NULL) {
<     LOG_ERR(
<         "Video device %s not found, "
<         "fallback to software generator.",
<         VIDEO_DEV);
< 
<     return;
<   }
< 
<   struct video_format fmt;
<   fmt.pixelformat = VIDEO_PIX_FMT_VYUY;
<   fmt.width = IMAGE_WIDTH;
<   fmt.height = IMAGE_HEIGHT;
<   fmt.pitch = fmt.width * 2;
<   if (video_set_format(video, VIDEO_EP_OUT, &fmt)) {
<     LOG_ERR("Unable to set video format");
<     return;
<   }
< 
<   hsd_t *hsd = hsd_create(HSD_FLAG_HEAD_SHOULDER | HSD_FLAG_GESTURE_RECOGNIZE);
< 
<   if (hsd == NULL) {
<     LOG_ERR("Create HSD instance failed.");
<     return;
<   }
< 
<   hsd_event_register(hsd, HSD_EVENT_HEAD_SHOULDER, on_receive_hsd_result, NULL);
<   hsd_event_register(hsd, HSD_EVENT_GESTURE_RECOGNIZE, on_receive_hsd_result,
<       NULL);
---
> int sample_face_detect(fd_t *fd, struct video_buffer *vbuf, struct video_format *fmt)
> {
>     fd_face_recog_result_t result;
>     pic_buffer_t pic_buf;
> 
>     pic_buf.buffer = vbuf->buffer;
>     pic_buf.size = vbuf->size;
> 
>     memset((void *)&result, 0, sizeof(fd_face_recog_result_t));
>     memcpy((void *)&pic_buf.format, (void *)fmt, sizeof(struct video_format));
> 
>     uint8_t *buf = k_malloc(MAX_DETECT_RESULT * sizeof(fd_face_recog_data_t));
>     if(!buf){
>         LOG_ERR("no memory for fd_face_recog_data");
>         return -1;
>     }
>     result.detect_data = (fd_face_recog_data_t *)buf;
>     fd_exec(fd, &pic_buf, &result);
234c281,300
<   printk("- Device name: %s\n", VIDEO_DEV);
---
>     for(uint8_t i = 0; i < result.detect_cnt; i++) {
>         if(result.detect_data[i].anti_spoofing_status){
>             LOG_DBG("x = %d\t y=%d\t w=%d\t h=%d\t score=%f", 
>                 result.detect_data[i].detect_rect.x,
>                 result.detect_data[i].detect_rect.y,
>                 result.detect_data[i].detect_rect.w,
>                 result.detect_data[i].detect_rect.h,
>                 result.detect_data[i].detect_score);
>             LOG_DBG("anti_spoofing_score:%f head_pose_status:%d", result.detect_data[i].anti_spoofing_score, result.detect_data[i].head_pose_status);
>             LOG_DBG("head_yaw = %f, head_pitch = %f, head_roll = %f", 
>                     result.detect_data[i].head_yaw,
>                     result.detect_data[i].head_pitch,
>                     result.detect_data[i].head_roll);
>         }
>     }
> 
>     if(result.detect_cnt != 0 && result.detect_data[0].feature_dim == FD_MAX_FEATURE_DIMS){
>         memcpy((void *)fr.feature, (void *)result.detect_data[0].feature, result.detect_data[0].feature_dim * sizeof(float));
>         fr.get_new_feature = true;
>     }
237,239c303
<   static char buffer[sizeof(msg_data_t) * MSGQ_NUMBER];
<   msg_data_t msg_data;
<   k_msgq_init(&msg, buffer, sizeof(msg_data_t), MSGQ_NUMBER);
---
>     webusb_send_pic(vbuf, &result);
242c306
<   // hsd_set_params(hsd, HSD_PARAM_HEAD_SHOULDER_DETECT_THRES, 0.55f);
---
>     k_free(buf);
244,246c308,309
<   // float value;
<   // hsd_get_params(hsd, HSD_PARAM_HEAD_SHOULDER_DETECT_THRES, &value);
<   // LOG_INF("GET_PARAMS: %d %f", HSD_PARAM_HEAD_SHOULDER_DETECT_THRES, value);
---
>     return 0;
> }
248,250d310
< #if MOCK_DATA
<   struct video_buffer *vbuf = video_buffer_alloc(IMAGE_SIZE);
<   memcpy(vbuf->buffer, head_640x480, vbuf->size * sizeof(char));
252,254c312,328
<   fmt.height = 480;
<   fmt.width = 640;
<   fmt.pixelformat = VIDEO_PIX_FMT_BGR24;
---
> int video_init(void){
>     const struct device *video;
>     int ret = 0;
> 
>     fr.fmt.pixelformat = VIDEO_PIX_FMT_VYUY;
>     fr.fmt.width = IMAGE_WIDTH;
>     fr.fmt.height = IMAGE_HEIGHT;
>     fr.fmt.pitch = fr.fmt.width * 2;
> 
>     video = device_get_binding(VIDEO_DEV);
>     if (video == NULL) {
>           LOG_ERR("Video device %s not found",VIDEO_DEV);
>         ret = -1;
>         goto error;
>     }
> 
>     LOG_INF("- Device name: %s\n", VIDEO_DEV);
256,257c330,334
<   while (1) {
<     hsd_exec(hsd, vbuf, fmt);
---
>     if (video_set_format(video, VIDEO_EP_OUT, &fr.fmt)) {
>         LOG_ERR("Unable to set video format");
>         ret = -1;
>         goto error;
>     }
259c336,346
<     k_sleep(K_MSEC(400));
---
>     struct video_buffer *buffers[2];
>     int bsize = fr.fmt.pitch * fr.fmt.height;
>     /* Alloc video buffers and enqueue for capture */
>     for (int i = 0; i < ARRAY_SIZE(buffers); i++) {
>         LOG_INF("Alloc video buffer: %d", bsize);
>         buffers[i] = video_buffer_alloc(bsize);
>         if (buffers[i] == NULL) {
>             LOG_ERR("Unable to alloc video buffer");
>             ret = -1;
>             goto error;
>         }
261,265c348
< #ifdef CONFIG_WEBUSB
<     int ret = k_msgq_get(&msg, &msg_data, K_MSEC(500));
<     if (ret != 0) {
<       LOG_WRN("Get video buffer timeout.");
<       continue;
---
>           video_enqueue(video, VIDEO_EP_OUT, buffers[i]);
267,270d349
< #endif
<   }
< #else
<   hsd_start(hsd, video);
272,295c351,362
<   while (1) {
< #ifdef CONFIG_WEBUSB
<     int ret = k_msgq_get(&msg, &msg_data, K_FOREVER);
<     if (ret != 0) {
<       LOG_WRN("Get video buffer timeout.");
<       continue;
<     }
< 
<     switch (msg_data.event) {
<     case HSD_EVENT_HEAD_SHOULDER:
<       handle_shoulder_data(msg_data);
<       break;
<     case HSD_EVENT_GESTURE_RECOGNIZE:
<       if (is_usb_cfg && msg_data.hsd.gesture_state >= 0 && msg_data.hsd.gesture_state <= 5) {
<         gesture_t gesture = {
<           .x = msg_data.hsd.rect.x,
<           .y = msg_data.hsd.rect.y,
<           .w = msg_data.hsd.rect.w,
<           .h = msg_data.hsd.rect.h,
<           .gesture = msg_data.hsd.gesture_state,
<           .score = msg_data.hsd.gesture_scores[msg_data.hsd.gesture_state],
<           .status = msg_data.hsd.gesture_status[msg_data.hsd.gesture_state],
<           .id = msg_data.hsd.id
<         };
---
>     /* Start video capture */
>     if (video_stream_start(video)) {
>       LOG_ERR("Unable to start capture (interface)");
>         ret = -1;
>         goto error;
>     }
> 
>     fr.video = video;
> 
> error:
>     return ret;
> }
297c364,373
<         uint8_t *send = (uint8_t *)(&gesture);
---
> int alago_init(void){
>     int ret = 0;
>     fd_config_t cfg;
>     fd_t *fd;
> 
>     if (0 != licak_init()) {
>         LOG_ERR("LICAK init failed,exit.\n");
>         ret = -1;
>         goto error;
>     }
299,303c375,381
<         send_gesture(send, sizeof(gesture));
<       }
<       break;
<     default:
<       break;
---
>     
>     cfg.algo = FD_ALGO_FACE_RECOGNIZE;
>     fd = fd_create((void *)&cfg);
>     if(fd  == NULL) {
>         LOG_ERR("fd create failed");
>         ret = -1;
>         goto error;
304a383,430
> 
>     fr.fd = fd;
> 
>     float value = 0.4;
>     fd_set_params(fd, FD_PARAM_FACE_DETECT_THRES, &value);  
> 
>     value = 0.4;
>     fd_set_params(fd, FD_PARAM_FACE_DETECT_PROBTHRES, &value);
> 
>     value = 30.0;
>     fd_set_params(fd, FD_PARAM_FACE_ALIGN_YAWTHRES, &value);
> 
>     value = 30.0;
>     fd_set_params(fd, FD_PARAM_FACE_ALIGN_PITCHTHRES, &value);
> 
>     value = 30.0;
>     fd_set_params(fd, FD_PARAM_FACE_ALIGN_ROLLTHRES, &value); 
> 
>     value = 0.7;
>     fd_set_params(fd, FD_PARAM_ANTI_SPOOFING_THRES, &value);   
> 
> error:
>     return ret;
> }
> 
> void main(void){
>     struct video_buffer *vbuf;
> 
> #ifdef CONFIG_WEBUSB
>     static char buffer[sizeof(msg_data_t) * MSGQ_NUMBER];
>     k_msgq_init(&fr.msg, buffer, sizeof(msg_data_t), MSGQ_NUMBER);
> 
>     register_webusb_status_cb(webusb_status_callback);
>     if (0 != webusb_enable()) {
>         LOG_ERR("Failed to enable USB");
>         return;
>     }
> 
>     storage_init();
> 
>     register_button_event(button_callback);
>     button_proc(button_callback);
> #endif
> 
> #if !MOCK_DATA
>     if(video_init()){
>         return;
>     }
306c432,438
<     k_msleep(10);
---
>     vbuf = video_buffer_alloc(IMAGE_SIZE);
>     if(!vbuf){
>         LOG_ERR("Failed to alloc video buffer");
>         return;
>     }
>     vbuf->size = sizeof(image_640x480_resource)/sizeof(image_640x480_resource[0]);
>     memcpy(vbuf->buffer, image_640x480_resource, vbuf->size);
308d439
<   }
310c441,454
<   hsd_stop(hsd);
---
>     if(alago_init()){
>         return;
>     }
> 
>     uint32_t last = k_uptime_get_32();
>     uint32_t time = k_uptime_get_32();
> 
>     while(1){
> #if MOCK_DATA
>         struct video_format fmt;
>         fmt.width = IMAGE_WIDTH;
>         fmt.height = IMAGE_HEIGHT;
>         fmt.pitch = fmt.width * 2;
>         fmt.pixelformat = VIDEO_PIX_FMT_RGB24;
312c456,465
<   hsd_destroy(hsd);
---
>         sample_face_detect(fr.fd, vbuf, &fmt);
> #else
>         if (video_dequeue(fr.video, VIDEO_EP_OUT, &vbuf, K_FOREVER)) {
>             LOG_ERR("Unable to dequeue video buf");
>             break;
>         }
> 
>         sample_face_detect(fr.fd, vbuf, &fr.fmt);
> 
>         video_enqueue(fr.video, VIDEO_EP_OUT, vbuf);
315c468,471
<   LOG_DBG("AP EXEC END\n");
---
>         last = time;
>         time = k_uptime_get_32();
>         LOG_DBG("FPS: %.2f", 1000.0 / (time - last));
>     }

7b8709331d2653a89a929b3abd1b5e3.jpg
头肩识别

CSK6的价格对于Jetson Nano来说不到六分之一,虽然在生态上支持的算法框架还远不够,学习来说肯定是比nano要香,同样在设备树文件和源码也是开源的状态下分类简单,一目了然。

推荐阅读
关注数
5175
内容数
100
聆思科技官方专栏,专注AIOT芯片,持续分享有趣的解决方案。商务合作微信:listenai-csk 技术交流QQ群:825206462
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息