코딩뚠뚠

[머신러닝 공부] Tiny ML -15 / 인체감지 어플리케이션-3 본문

공부/ML&DL

[머신러닝 공부] Tiny ML -15 / 인체감지 어플리케이션-3

로디네로 2022. 3. 22. 00:48
반응형

 

 

Chapter15. 인체감지 어플리케이션

 

"

카메라로 인체를 감지해보자 (CNN)

"

 

목차 : 

  • 개요 -> Tiny ML -13
  • 만들고자하는 -> Tiny ML -13
  • 어플리케이션 아키텍처 -> Tiny ML -13
  • 코드 기본흐름 -> Tiny ML -14
  • 핵심 함수 분석 -> Tiny ML -14
  • 마이크로컨트롤러 배포 

 

 

이전장 링크

 

[머신러닝 공부] Tiny ML -14 / 인체감지 어플리케이션-2

Chapter14. 인체감지 어플리케이션 " 카메라로 인체를 감지해보자 (CNN) " 목차 : 개요 -> 이전장 만들고자하는 -> 이전장 어플리케이션 아키텍처 -> 이전장 코드 기본흐름 핵심 함수 분석 마이크로컨

dbstndi6316.tistory.com


참고 repo

 

GitHub - tensorflow/tensorflow: An Open Source Machine Learning Framework for Everyone

An Open Source Machine Learning Framework for Everyone - GitHub - tensorflow/tensorflow: An Open Source Machine Learning Framework for Everyone

github.com

 


 

카메라모듈 도착과 설명 : 

 

드디어 이전 포스팅 이후 구매했던 카메라가 도착해서 포스팅을 이어나갈 수 있게 됐다

 

 

Sparkfun Edge 와 호환이 되는 HM01B0 하이맥스 카메라 이다.

 

MCU와 결합해보면?

 

이렇게 몇주만에 세팅을 완료했다!

 


 

Sparkfun Edge 보드는 저전력 소비에 최적화되어있는데, 카메라를 사용하면서 저전력이 아니게 되면 의미가 없어진다.

 

이 카메라는 하이맥스 HM01B0 브레이크 아웃 카메라 모듈로, 

 

320x320 픽셀이미지를 30FPS로 캡쳐할 때 2mW 미만의 매우 적은 양의 전력을 소모한다.

 


 

이미지 얻기 :

 

우선 카메라를 초기화 해야 한다.

 

초기화 후에는 카메라에서 프레임을 읽어올 수 있다. 

(프레임은 카메라가 현재 볼수있는 이미지를 나타내는 바이트배열 이다.)

 

이미지 추출기 - sparkfun_edge/image_provider.cc 

GetImage() 함수 : 카메라 모듈에서 이미지 데이터 캡쳐

TfLiteStatus GetImage(tflite::ErrorReporter* error_reporter, int frame_width,
                      int frame_height, int channels, uint8_t* frame) {
  if (!g_is_camera_initialized) {
    TfLiteStatus init_status = InitCamera(error_reporter);
    if (init_status != kTfLiteOk) {
      am_hal_gpio_output_set(AM_BSP_GPIO_LED_RED);
      return init_status;
    }

▷ InitCamera가 kTfLiteOk 상태 이외의 값을 반환하면 RED LED를 켜서 문제를 나타낸다.

 

    for (int i = 0; i < kFramesToInitialize; ++i) {
      hm01b0_blocking_read_oneframe_scaled(&s_HM01B0Cfg, frame, frame_width,
                                           frame_height, channels);
    }
    g_is_camera_initialized = true;
  }

  hm01b0_blocking_read_oneframe_scaled(&s_HM01B0Cfg, frame, frame_width,

hm01b0_blocking_read_oneframe_scaled() 함수를 사용해 여러 프레임을 캡쳐한다.

▷ 캡쳐된 데이터는 카메라 모듈의 자동노출기능을 위해서만 사용된다.

 


 

감지응답기 구현 - sparkfun_edge/detection_responder.cc

RespondToDetection() 함수

추론 실행 : 파란색 LED

사람 감지 : 초록색 LED

사람 없음 : 노란색 LED

void RespondToDetection(tflite::ErrorReporter* error_reporter,
                        uint8_t person_score, uint8_t no_person_score) {
  static bool is_initialized = false;
  if (!is_initialized) {
    // Setup LED's as outputs.  Leave red LED alone since that's an error
    // indicator for sparkfun_edge in image_provider.
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_BLUE, g_AM_HAL_GPIO_OUTPUT_12);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_GREEN, g_AM_HAL_GPIO_OUTPUT_12);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_YELLOW, g_AM_HAL_GPIO_OUTPUT_12);
    is_initialized = true;
  }

▷ 출력으로 LED를 설정한다.

빨간색 LED는 오류를 나타내므로 남겨둔다.

 

  // Toggle the blue LED every time an inference is performed.
  static int count = 0;
  if (++count & 1) {
    am_hal_gpio_output_set(AM_BSP_GPIO_LED_BLUE);
  } else {
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
  }

▷ 추론 시 마다 파란색 LED를 토글하게끔 하기

 

  am_hal_gpio_output_clear(AM_BSP_GPIO_LED_YELLOW);
  am_hal_gpio_output_clear(AM_BSP_GPIO_LED_GREEN);
  if (person_score > no_person_score) {
    am_hal_gpio_output_set(AM_BSP_GPIO_LED_GREEN);
  } else {
    am_hal_gpio_output_set(AM_BSP_GPIO_LED_YELLOW);
  }

  error_reporter->Report("Person score: %d No person score: %d", person_score,
                         no_person_score);
}

초록색 LED와 노란색 LED 설정을 마친다.

ErrorReporter 인스턴스를 사용해 점수를 기록한다.

 

 


 

 

예제 실행하기

 

텐서플로 저장소를 복제한다.

최신버전에는 존재하지 않기때문에.. 찾아본 결과 10 Dec 2019 로 History를 맞춰보니 시점이 일치했다. 안된다면 질문주세요

git clone https://github.com/tensorflow/tensorflow.git
cd tensorflow

바이너리 빌드

make -f tensorflow/lite/micro/tools/make/Makefile\
TARGET=sparkfun_edge person_detection_bin

위 내용을 수행하는데 계속 에러가 나서 봤더니 다운로드가 제대로 안된거였다.

arm-none-eabi-gcc 가 없다는 에러가 날 경우에는 tensorflow/lite/micro/tools/make/downloads 폴더를 지우고 위 명령을 다시해보길 바란다.


바이너리 서명

cp tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.0.0/tools/ \
apollo3_scripts/keys_info0.py tensorflow/lite/micro/tools/make/downloads/ \
AmbiqSuite-Rel2.0.0/tools/apollo3_scripts/keys_info.py
python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.0.0/tools/ \
apollo3_scripts/create_cust_image_blob.py --bin tensorflow/lite/micro/tools/ \
make/gen/sparkfun_edge_cortex-m4/bin/person_detection.bin --load-address 0xC000 \
--magic-num 0xCB -o main_nonsecure_ota --version 0x0


최종 버전 생성

python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.0.0/ \
tools/apollo3_scripts/create_cust_wireupdate_blob.py --load-address 0x20000 \
--bin main_nonsecure_ota.bin -i 6 -o main_nonsecure_wire --options 0x1

▷ main_nonsecure_wire.bin 파일이 생성되었고 이걸 장치에 플래시해볼것이다.

 


장치와 연결 확인

ls /dev/tty*

장치 이름과 BAUD_RATE를 설정해주고 접근 권한을 부여해준다.

export DEVICENAME=/dev/ttyUSB0
export BAUD_RATE=921600
sudo chmod 666 /dev/ttyUSB0

보드 14번 버튼을 누른 채로 RST버튼을 눌렀다 떼어 RESET을 실행해준다.

14버튼을 유지한채로 아래 명령어를 실행해준다.

python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.0.0/ \
ools/apollo3_scripts/uart_wired_update.py -b ${BAUD_RATE} ${DEVICENAME} \
-r 1 -f main_nonsecure_wire.bin -i 6

 


 

결과

 

1. 파란색 LED가 점멸하고 노란색 LED가 점등되어 사람이 없다는것을 알린다.

- 역시 초저전력 임베디드에서 모델을 돌리는건 정확도가 떨어지는 편인것 같다.

 

2. 초록색 LED가 점등된 것으로 사람을 인식했다는것을 알수있다.

- 카메라 포커싱이 잘된건지 이목구비가 더 뚜렷한 사람을 알아본건지는 미지수

 

 

 

카메라를 비즈니스 모델에 이용하는 경우는 매우 많다.

 

카메라와 TinyML을 이용해서 어떤 가치를 창출해낼 수 있을까 고민해보는 것도 좋을 것 같다.

 

(우선 모델 경량화부터좀..)

 

 

반응형