赤色検知と7セグ

By K10-K10

こんにちはK10-K10です。
今回は赤色を検知するプログラムができたということで、その解説と、
機体の状況判断用の7セグLEDの使い方をまとめたいと思います。

プログラム

赤色検知をする関数です。

def detect_red_marks(orig_image, blackline_image):
  image = orig_image.copy()
  global red_marks, red_black_detected

  hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)

  lower_red1 = np.array([0, 40, 0])
  upper_red1 = np.array([30, 255, 255])

  lower_red2 = np.array([100, 40, 0])
  upper_red2 = np.array([180, 255, 255])

  red_mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
  red_mask2 = cv2.inRange(hsv, lower_red2, upper_red2)

  red_mask = cv2.bitwise_or(red_mask1, red_mask2)

  kernel = np.ones((3, 3), np.uint8)
  red_mask = cv2.erode(red_mask, kernel, iterations=2)
  red_mask = cv2.dilate(red_mask, kernel, iterations=2)

  if DEBUG_MODE:
    time_str = str(time.time())
    cv2.imwrite(f"bin/{time_str}_red_mask1.jpg", red_mask1)
    cv2.imwrite(f"bin/{time_str}_red_mask2.jpg", red_mask2)
    cv2.imwrite(f"bin/{time_str}_red_mask.jpg", red_mask)

  contours, _ = cv2.findContours(red_mask, cv2.RETR_EXTERNAL,
                                 cv2.CHAIN_APPROX_SIMPLE)

  red_marks = []
  red_black_detected = []

  for contour in contours:
    if cv2.contourArea(contour) > min_red_area:
      x, y, w, h = cv2.boundingRect(contour)

      center_x = x + w // 2
      center_y = y + h // 2
      red_marks.append((center_x, center_y, w, h))

      if DEBUG_MODE:
        cv2.line(image, (x, y), (x + w, y + h), (0, 0, 255),
                 2)
        cv2.line(image, (x + w, y), (x, y + h), (0, 0, 255), 2)
        cv2.circle(image, (center_x, center_y), 5, (0, 0, 255), -1)

後半のノイズ除去と、画像へのマークは 前回の緑色と同じです。

解説

  lower_red1 = np.array([0, 40, 0])
  upper_red1 = np.array([30, 255, 255])

  lower_red2 = np.array([100, 40, 0])
  upper_red2 = np.array([180, 255, 255])

赤のHSV(色相)は0~60度、300~360度に分かれています。
この値をOpenCV(0~180)に直すと、0~30 150~180度 となります。
数値は違いますが、これから調整していきます。

  red_mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
  red_mask2 = cv2.inRange(hsv, lower_red2, upper_red2)

  red_mask = cv2.bitwise_or(red_mask1, red_mask2)

先程の色値の範囲でフィルターをかけます。
red_mask1が色値が下のもの
red_mask2が色値が上のものです。
これで赤色は白、その他は黒の画像が出来上がります。
この2つの画像をbitwise_orにかけ、最終的なred_maskを得ます。
bitwise_orは論理演算子orと同じ結果を画像に返します。

画像1 画像2 出力

これで赤色は白、その他は黒の画像が出来上がります。
これで色値が2箇所ある赤色でも、マスク処理を行うことができます。

7セグLED

機体が行っている動作をLEDのランプで判断できるようにしたいと思い、導入しました。
どのピンがどこと対応しているかわからなかった(検索で出てくるものとは違っていた)ので、ここにメモを残しておきます

ピン

1—— ——5
2—— ——6
GND- -GND
3—— ——7
4—— ——8

LED

 ---5---
|       |
2       6
|       |
 ---1---
|       |
3       7
|       |
 ---4---   8 (ドット)

終わりに

検知できている画像を載せようと思ったのですが、取り忘れました。
また、今の機体では、ライントレース用のカメラの視野が狭すぎるので、修正しないといけません。
基盤のミスも見つかったので、間に合うか心配です。

あと、安定化電源をつなぐときは、小数点の位置を必ず確認しましょう
3.3v だと思って33vを流さないようにしましょう。

Thank you for reading~

📝 author: K10-K10