3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SpresenseAdvent Calendar 2024

Day 6

SpresenseでCameraを使って色を判断してみた!

Posted at

初めに

Spresenseを使って、「赤丸とか緑丸とかを判断したい」んだけど、と相談されたので、
ソニーの太田さんの本にあるSementic segmentationを使って認識させようと思ったんだけど、

もっと手軽にやって欲しいとのことなので、簡単に中心部の色だけを判断するコードを書いてみました。

用意するもの

SpresenseはMainボードとカメラボードのみです!

SPRESENSEメインボード[CXD5602PWBMAIN1]

SPRESENSE HDRカメラボード[CXD5602PWBCAM2W]

小さく作れます!

ブログ(元ネタ)

この記事は、以下のブログにあるものです。

ソースコード

Spresense Arduino の Camera Sampleを使って作ってみます。
基本、CamCBを使って、常時、小さい画像を取り込みながら、
真ん中部分の色が、赤、黄色、緑の範囲に入っているか?を見るというサンプルになります。

なので、loopでは、秒に1回結果を表示するだけ。

  switch(current_color){
    case DETECT_RED:
    Serial.println("Detect Red!");
    break;
    case DETECT_YELLOW:
    Serial.println("Detect Yellow!");
    break;
    case DETECT_GREEN:
    Serial.println("Detect Green!");
    break;
    case DETECT_NONE:
    default:
    break;
  }
  sleep(1);

CamCBでは、320x240で撮りこまれた画像を、真ん中の96x96だけ切り出し1/8にする。

#define OFFSET_X  (112)
#define OFFSET_Y  (72)
#define CLIP_WIDTH  (96)
#define CLIP_HEIGHT  (96)
#define DETECT_WIDTH  (12)
#define DETECT_HEIGHT  (12)

  if (!img.isAvailable()) return;

  // HWでの画像の切り出しと縮小
  CamImage small; 
  CamErr camErr = img.clipAndResizeImageByHW(small
            ,OFFSET_X ,OFFSET_Y 
            ,OFFSET_X+CLIP_WIDTH-1 ,OFFSET_Y+CLIP_HEIGHT-1 
            ,DETECT_WIDTH ,DETECT_HEIGHT);

RGBに変換して、色を検出。

  // 画像をYUVからRGB565に変換
  small.convertPixFormat(CAM_IMAGE_PIX_FMT_RGB565); 
  uint16_t* sbuf = (uint16_t*)small.getImgBuff();

  int detect_red = 0;
  int detect_yellow = 0;
  int detect_green = 0;

  for(int i=0;i<DETECT_WIDTH;i=i+2){
    for(int j=0;j<DETECT_HEIGHT;j=j+2){
      int k = i*DETECT_HEIGHT+j;
      int red = (sbuf[k] >> 11) & 0x1F;
      int green = (sbuf[k] >> 5) & 0x3F;
      int blue = sbuf[k]  & 0x1F;
//      printf("sbuf[%d]=%04x,r=%02x,g=%02x,b=%02x\n",k,sbuf[k],red,green,blue);
      if(detectRed(red,green,blue)) detect_red++;
      if(detectYellow(red,green,blue)) detect_yellow++;
      if(detectGreen(red,green,blue)) detect_green++;
    }
  }

それぞれの色の範囲は、detectRed/detectYellow/detectGreenの中で調整。
全画素を見ずに、1つおきに見ることで処理を軽くして、閾値以上の色が見つかれば表示をしました。

本体のコードはこちらにあります。

Spresenseは、クリップと縮小、フォーマット変換が簡単にできるので、
この手のコードは楽に書けますよ!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?