SPRESENSE에서 이미지 인식2

전회의 줄거리


지난번에는 카메라로 이미지를 캡처해서 uSD에 저장할 수 있었다.이번에는 Sony NNC를 사용하여 Spresense에서 이미지 인식을 진행합니다.

제작물(재등재)


스presense를 통해 아들 3명의 얼굴을 식별하는 것을 목표로 한다.

이른바 NNC


NNC는 소니가 개발한 심층/기계적 학습이 가능한 코드 없는 애플리케이션사이트 설명을 말한다.
구름판과 원시판이 있습니다.원본은 일본 내에서만 다운로드할 수 있고 무료로 사용할 수 있다.
NNC의 사용법에 대한 설명여기. 유튜브에도 공식적인 상세한 설명이 있다.

전체 국면을 굽어보다.


NNC는 응용 프로그램입니다.Spresense는 카메라가 있는 기판입니다.어떻게 연락이 됐는지 의문이 좀 있잖아요.대략적인 흐름을 내려다보기 전에 머신러닝의 흐름과 NNC가 무엇을 하는지 먼저 파악하세요.

최초의 기계 학습(교사 학습)의 절차


기계 학습에는 각양각색의 종류가 있지만, 이번에 진행된 것은 교사와 학습이다.교사가 있는 학습 절차는 다음과 같다.
  • 정답을 알 수 있는 질문(교사 데이터)을 컴퓨터에 대량으로 입력
  • 컴퓨터의 정답률이 높아지기 전에 반복적으로 해답
  • 컴퓨터가 문제 해결 방법을 습득(학습 모드)
    NNC는 위에서 설명한 학습 모드를 쉽게 생성할 수 있는 도구입니다.
  • 전체 프로세스


    교사, 학습 절차와 NNC의 역할에 대해 어느 정도 이해한 토대에서 전체적인 절차는 다음과 같다.
  • 스presense에서 아들 3명의 얼굴 사진을 대량으로 촬영(교사 데이터로 사용)
  • NNC를 입력하여 학습 모델 생성
  • 생성된 학습 모형을 UDD 카드에 저장하고 Spresense를 통해 읽기
  • Spresense+카메라는 이미 배운 모델에 따라 피사체가 누구인지 식별
  • 쉬울 것 같아!

    샘플 코드 설명


    Spresense의 견본 코드를 읽고 더 깊이 이해하세요.Arduino IDE 파일 > 스케치 예 > DNRT>numberrecognition에서 샘플 코드를 보십시오.이 샘플 코드가 읽는 pgm 파일 (픽셀마다 0-255의 그레이스케일로 표시된 그림) 은 그림이 4인지 9인지 판별합니다.Serial의 설정과 오류 대응 등을 제외한 코드는 다음과 같다.
    #include <SDHCI.h>
    #include <NetPBM.h>
    #include <DNNRT.h>
    
    DNNRT dnnrt;
    SDClass SD;
    
    void setup() {
      File nnbfile = SD.open("network.nnb");
      int ret = dnnrt.begin(nnbfile);
      // Image size for this network model is 28 x 28.
      File pgmfile("number4.pgm");
      NetPBM pgm(pgmfile);
      unsigned short width, height;
      pgm.size(&width, &height);
      DNNVariable input(width * height);
      float *buf = input.data();
      
      int i = 0;
      /*
       * Normalize pixel data into between 0.0 and 1.0.
       * PGM file is gray scale pixel map, so divide by 255.
       * This normalization depends on the network model.
       */
      for (int x = 0; x < height; x++) {
        for (int y = 0; y < width; y++) {
          buf[i] = float(pgm.getpixel(x, y)) / 255.0;
          i++;
        }
      }
    
      dnnrt.inputVariable(input, 0);
      dnnrt.forward();
      DNNVariable output = dnnrt.outputVariable(0);
    
      /*
       * Get index for maximum value.
       * In this example network model, this index represents a number,
       * so you can determine recognized number from this index.
       */
    
      int index = output.maxIndex();
      Serial.print("Image is ");
      Serial.print(index);
      Serial.println();
      Serial.print("value ");
      Serial.print(output[index]);
      Serial.println();
    
      dnnrt.end();
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
    

    샘플 코드에 대한 이해를 깊이 있게 하다


    각 부분을 아는 범위 내에서 간단히 설명하다.
    다음은 NNC에서 생성된 학습 모드를 읽을 수 있습니다.
    File nnbfile = SD.open("network.nnb");
    int ret = dnnrt.begin(nnbfile);
    
    읽기 소스 코드에서 이미지 데이터를 사용할 수 있습니다.
    // Image size for this network model is 28 x 28.
    File pgmfile("number4.pgm");
    NetPBM pgm(pgmfile);
    
    다음은 입력 데이터의 크기를 가져오고 버퍼를 정의합니다.
    unsigned short width, height;
    pgm.size(&width, &height);
    DNNVariable input(width * height);
    float *buf = input.data();
    
    다음에 입력한 데이터의 각 픽셀을 0~1의 범위 내에서 정규화하고 상기 생성된 버퍼 메모리에서 순서대로 값을 입력한다.
    int i = 0;
    for (int x = 0; x < height; x++) {
      for (int y = 0; y < width; y++) {
        buf[i] = float(pgm.getpixel(x, y)) / 255.0;
        i++;
      }
    }
    
    이미 학습한 모델을 사용하여 입력 데이터에서 출력 값을 구한다.
    dnnrt.inputVariable(input, 0);
    dnnrt.forward();
    DNNVariable output = dnnrt.outputVariable(0);
    
    결과를 출력하고 끝냅니다.출력 결과가 0에 가까울 때는 4, 출력 결과가 1에 가까울 때는 9로 입력합니다.
      int index = output.maxIndex();
      Serial.print("Image is ");
      Serial.print(index);
      Serial.println();
      Serial.print("value ");
      Serial.print(output[index]);
      Serial.println();
    
      dnnrt.end();
    
    지금 샘플 코드를 처음 봤지만 API로 이미지를 한 번에 식별할 수 있을 것 같지만 쉽지 않을 것 같아요.얼굴 이미지를 인식할 수 있을지 걱정이 되지만 열심히 하겠습니다.

    좋은 웹페이지 즐겨찾기