eMoi-picのアイコン画像
eMoi-pic 2024年06月19日作成 (2024年06月19日更新)
セットアップや使用方法 セットアップや使用方法 閲覧数 188
eMoi-pic 2024年06月19日作成 (2024年06月19日更新) セットアップや使用方法 セットアップや使用方法 閲覧数 188

EMOI-PIC AI学習用画像データ撮影プログラム

EMOI-PIC AI学習用画像データ撮影プログラム

EMOI-PIC AI学習用画像データ撮影サンプルコード

AI学習には大量の画像データが必要ですので、そのデータ収集のためにSpresenseカメラをデジカメ化するサンプルプログラムです。プッシュボタンを押すと、Spresenseカメラが画像を1枚撮影し、2種類の画像ファイルをSDカードに保存します。

  • 確認用画像: 160×120画素のRGB各8ビットのBMP画像(IMG***.BMP、***は通し番号)
  • AI学習対象画像: 16×12画素のRGB各8ビットのBMP画像(DAT***.BMP、***は通し番号)
  • Spresenseカメラ取付方向: カメラ基板のSONYロゴの上下が通常の場合は、 CAMERA_UPSIDEDOWNはFALSEで、ロゴが上下逆の場合はTRUEにしてください
  • デジタルピンD15をシャッターボタンの入力にしていますが、Spresense拡張ボードのpinModeをプルアップモード(INPUT_PULLUP)に設定していますので、外部に抵抗とかは無用で単にスイッチをD15とGNDとに接続するだけす。

シャッターボタン

#include <stdio.h> #include <Camera.h> #include <Adafruit_ILI9341.h> #include <SDHCI.h> #define TFT_DC (9) #define TFT_CS (10) #define BUTTON_PIN 15 #define CAMERA_UPSIDEDOWN FALSE #define DISPLAY_WIDTH (320) #define DISPLAY_HEIGHT (240) #define DNN_WIDTH (16) #define DNN_HEIGHT (12) #define DNN_COLOR (24) Adafruit_ILI9341 display = Adafruit_ILI9341(TFT_CS, TFT_DC); SDClass theSD; uint16_t* image_buffer; uint16_t drawImageBuf[160*120]; int total_image_count = 0; void putStringOnLCD(String str, int line, int color) { int len = str.length(); display.fillRect(0, DISPLAY_HEIGHT/2+line*18+6, DISPLAY_WIDTH-1, DISPLAY_HEIGHT/2+(line+1)*18+5, ILI9341_BLACK); display.setTextSize(2); int sx = DISPLAY_WIDTH/2 - len/2*12; if (sx < 0) sx = 0; if (line < 0) sx = 0; else if (line > 5) sx = 5; display.setCursor(sx, DISPLAY_HEIGHT/2+line*18+8); display.setTextColor(color); display.println(str); } void writeBMPHeader(File &file, int w, int h, int bit) { uint8_t bmpHeader_1[18] = { 0x42, 0x4D, // "BM" シグネチャ 0x36, 0x00, 0x00, 0x00, // ファイルサイズ(未使用) 0x00, 0x00, 0x00, 0x00, // 予約済み 0x36, 0x00, 0x00, 0x00, // ピクセルデータのオフセット 0x28, 0x00, 0x00, 0x00, // ヘッダーサイズ }; uint8_t bmpHeader_2[3] = { 0x00, 0x00, 0x00 }; uint8_t bmpHeader_3[2] = { 0x01, 0x00 // プレーン数=1 }; uint8_t bmpHeader_4[24] = { 0x00, 0x00, 0x00, 0x00, // 圧縮(なし) 0x00, 0x00, 0x00, 0x00, // イメージサイズ(未使用) 0x13, 0x0B, 0x00, 0x00, // 水平解像度 0x13, 0x0B, 0x00, 0x00, // 垂直解像度 0x00, 0x00, 0x00, 0x00, // 色数(未使用) 0x00, 0x00, 0x00, 0x00 // 重要な色数(未使用) }; file.write(bmpHeader_1, 18); file.write(w); // 幅(160) file.write(bmpHeader_2, 3); // 0パディング×3 file.write(h); // 高(120) file.write(bmpHeader_2, 3); // 0パディング file.write(bmpHeader_3, 2); // プレーン数×3 file.write(bit); // ビット/ピクセル(24ビットRGBカラー) file.write(bmpHeader_2, 1); // 0パディング file.write(bmpHeader_4, 24); } void CamCB(CamImage img) { if (img.isAvailable()) { image_buffer = (uint16_t *)img.getImgBuff(); } } void setup() { CamErr err; pinMode(BUTTON_PIN, INPUT_PULLUP); // ボタン:プルアップ抵抗モードのためスイッチOFF時は1、ON時が0 display.begin(); display.setRotation(3); display.fillScreen(ILI9341_BLACK); while (!theSD.begin()) { putStringOnLCD("Insert SD card", 0, ILI9341_GREEN); } display.fillScreen(ILI9341_BLACK); err = theCamera.begin(1, CAM_VIDEO_FPS_5, CAM_IMGSIZE_QQVGA_H, CAM_IMGSIZE_QQVGA_V, CAM_IMAGE_PIX_FMT_RGB565); err = theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_AUTO); err = theCamera.startStreaming(true, CamCB); } void loop() { // 入力画像をディスプレイに描画 display.drawRGBBitmap(0, 0, image_buffer, CAM_IMGSIZE_QQVGA_H, CAM_IMGSIZE_QQVGA_V); // シャッターボタンの押下(LOW)確認 if(digitalRead(BUTTON_PIN)==HIGH) return; // 高精細BMP画像ファイル(RGB24ビット)のSDカード保存 char filename[16] = {0}; sprintf(filename, "IMG%03d.BMP", total_image_count); theSD.remove(filename); File bmpFile = theSD.open(filename, FILE_WRITE); writeBMPHeader(bmpFile, CAM_IMGSIZE_QQVGA_H, CAM_IMGSIZE_QQVGA_V, DNN_COLOR); // 160*120画素のRGB888のBMPヘッダーの書き込み // 画像データの書き込み uint16_t* imgbuf_RGB565 = (uint16_t*)image_buffer; if(CAMERA_UPSIDEDOWN == FALSE) { for (int y = CAM_IMGSIZE_QQVGA_V-1; y >= 0; y--) { for (int x = 0; x < CAM_IMGSIZE_QQVGA_H; x++) { int n = y*CAM_IMGSIZE_QQVGA_H + x; bmpFile.write((uint8_t)(imgbuf_RGB565[n] << 3) & 0x00f8); // 青 bmpFile.write((uint8_t)(imgbuf_RGB565[n] >> 3) & 0x00fc); // 緑 bmpFile.write((uint8_t)(imgbuf_RGB565[n] >> 8) & 0x00f8); // 赤 } } } else { for (int y = 0; y < CAM_IMGSIZE_QQVGA_V; y++) { for (int x = CAM_IMGSIZE_QQVGA_H-1; x >= 0 ; x--) { int n = y*CAM_IMGSIZE_QQVGA_H + x; bmpFile.write((uint8_t)(imgbuf_RGB565[n] << 3) & 0x00f8); // 青 bmpFile.write((uint8_t)(imgbuf_RGB565[n] >> 3) & 0x00fc); // 緑 bmpFile.write((uint8_t)(imgbuf_RGB565[n] >> 8) & 0x00f8); // 赤 } } } bmpFile.close(); // AI学習用BMP画像ファイル(RGB24ビット)のSDカード保存 sprintf(filename, "DAT%03d.BMP", total_image_count); theSD.remove(filename); bmpFile = theSD.open(filename, FILE_WRITE); writeBMPHeader(bmpFile, DNN_WIDTH, DNN_HEIGHT, DNN_COLOR); // 16*12画素のRGB888のBMPヘッダーの書き込み // 画像データの書き込み if(CAMERA_UPSIDEDOWN == FALSE) { for (int y = CAM_IMGSIZE_QQVGA_V-1; y >= 0; y-=10) { for (int x = 0; x < CAM_IMGSIZE_QQVGA_H; x+=10) { int n = y*CAM_IMGSIZE_QQVGA_H + x; bmpFile.write((uint8_t)(imgbuf_RGB565[n] << 3) & 0x00f8); // 青 CAM_IMGSIZE_QQVGA_H/DNN_WIDTH=10 bmpFile.write((uint8_t)(imgbuf_RGB565[n] >> 3) & 0x00fc); // 緑 CAM_IMGSIZE_QQVGA_V/DNN_HEIGHT=10 bmpFile.write((uint8_t)(imgbuf_RGB565[n] >> 8) & 0x00f8); // 赤 } } } else { for (int y = 0; y < CAM_IMGSIZE_QQVGA_V; y+=10) { for (int x = CAM_IMGSIZE_QQVGA_H-1; x >= 0 ; x-=10) { int n = y*CAM_IMGSIZE_QQVGA_H + x; bmpFile.write((uint8_t)(imgbuf_RGB565[n] << 3) & 0x00f8); // 青 CAM_IMGSIZE_QQVGA_H/DNN_WIDTH=10 bmpFile.write((uint8_t)(imgbuf_RGB565[n] >> 3) & 0x00fc); // 緑 CAM_IMGSIZE_QQVGA_V/DNN_HEIGHT=10 bmpFile.write((uint8_t)(imgbuf_RGB565[n] >> 8) & 0x00f8); // 赤 } } } bmpFile.close(); putStringOnLCD(filename, 4, ILI9341_WHITE); total_image_count++; delay(1000); }
eMoi-picのアイコン画像
EMOtional and Impressive Photos Investigator Challenge の紹介ページです。
ログインしてコメントを投稿する

投稿者の人気記事