@MN_nat

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

ESP32Camのesp_camera.hの使い方

解決したいこと

ESP32Camでカラーのオブジェクトを見分け、オレンジ、青、黄色の色を特定しその中心座標のx座標値とy座標値と大きさを出力するようにしたいと考えております。
が、ESP32Camが手元に無く試せません。

以下のソースコードで問題点がありますでしょうか。

#include "esp_camera.h"
#include <Arduino.h>

// カメラピン設定
#define CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM    32
#define RESET_GPIO_NUM   -1
#define XCLK_GPIO_NUM    0
#define SIOD_GPIO_NUM    26
#define SIOC_GPIO_NUM    27
#define Y9_GPIO_NUM      35
#define Y8_GPIO_NUM      34
#define Y7_GPIO_NUM      39
#define Y6_GPIO_NUM      36
#define Y5_GPIO_NUM      21
#define Y4_GPIO_NUM      19
#define Y3_GPIO_NUM      18
#define Y2_GPIO_NUM      5
#define VSYNC_GPIO_NUM   25
#define HREF_GPIO_NUM    23
#define PCLK_GPIO_NUM    22

// オレンジ、青、黄色の色の範囲
const int orange_lower_h = 5;
const int orange_upper_h = 15;
const int orange_lower_s = 50;
const int orange_upper_s = 255;
const int orange_lower_v = 50;
const int orange_upper_v = 255;

const int blue_lower_h = 100;
const int blue_upper_h = 140;
const int blue_lower_s = 50;
const int blue_upper_s = 255;
const int blue_lower_v = 50;
const int blue_upper_v = 255;

const int yellow_lower_h = 20;
const int yellow_upper_h = 30;
const int yellow_lower_s = 100;
const int yellow_upper_s = 255;
const int yellow_lower_v = 100;
const int yellow_upper_v = 255;

void setup() {
  Serial.begin(115200);

  // カメラ初期化
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;

  if (psramFound()) {
    config.frame_size = FRAMESIZE_QVGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_QVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  // カメラ初期化
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }
}

void loop() {
  camera_fb_t *fb = NULL;
  fb = esp_camera_fb_get();
  if (!fb) {
    Serial.println("Camera capture failed");
    return;
  }

  // 画像データをMatオブジェクト(行列)に変換
  Mat img(fb->height, fb->width, CV_8UC3, fb->buf);

  // RBGからHSV((色相(Hue)、彩度(Saturation)、明度(Value・Brightness)」の3要素で表現)に変換
  Mat hsv;
  cvtColor(img, hsv, COLOR_BGR2HSV);

  // オレンジ、青、黄色の色の範囲を定義
  Scalar orange_lower(orange_lower_h, orange_lower_s, orange_lower_v);
  Scalar orange_upper(orange_upper_h, orange_upper_s, orange_upper_v);
  Scalar blue_lower(blue_lower_h, blue_lower_s, blue_lower_v);
  Scalar blue_upper(blue_upper_h, blue_upper_s, blue_upper_v);
  Scalar yellow_lower(yellow_lower_h, yellow_lower_s, yellow_lower_v);
  Scalar yellow_upper(yellow_upper_h, yellow_upper_s, yellow_upper_v);

  // カラーマスクを作成
  Mat orange_mask, blue_mask, yellow_mask;
  inRange(hsv, orange_lower, orange_upper, orange_mask);
  inRange(hsv, blue_lower, blue_upper, blue_mask);
  inRange(hsv, yellow_lower, yellow_upper, yellow_mask);

  // カラーマスクを合成
  Mat combined_mask;
  bitwise_or(orange_mask, blue_mask, combined_mask);
  bitwise_or(combined_mask, yellow_mask, combined_mask);

  // 輪郭を検出
  vector<vector<Point>> contours;
  findContours(combined_mask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

  // 各輪郭を処理
  for (size_t i = 0; i < contours.size(); i++) {
    // 輪郭が十分に大きいか確認
    if (contourArea(contours[i]) > 100) {
      // 物体の外接円を描画
      Point2f center;
      float radius;
      minEnclosingCircle(contours[i], center, radius);
      circle(img, center, radius, Scalar(0, 255, 255), 2);
      
      // 中心座標を描画
      circle(img, center, 5, Scalar(255, 255, 255), -1);
      putText(img, "centroid", Point(center.x - 25, center.y - 25), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 255, 255), 2);

      // 中心座標と大きさを出力
      Serial.print("X: ");
      Serial.print(center.x);
      Serial.print(" Y: ");
      Serial.print(center.y);
      Serial.print(" Radius: ");
      Serial.println(radius);
    }
  }

  // 画像を解放
  esp_camera_fb_return(fb);
}
 

0 likes

1Answer

どの部分を確認したいのでしょうか。
全体となると、デバイスのコンフィグレーションも合わせないといけないので厄介ですね。
それになぜお手元に無いデバイスに対するコーディングをされているのですか?

1Like

Comments

  1. @MN_nat

    Questioner

    ありがとうございます。デバイスは貸していて暫く返ってこないのです。戻り次第すぐにカラー判別に利用しようとしています。

Your answer might help someone💌