From 5d72b61c60c88044be6da57f2802da68f7340c44 Mon Sep 17 00:00:00 2001 From: takuma Date: Mon, 28 Oct 2024 18:01:01 +0900 Subject: [PATCH] =?UTF-8?q?update:=20=E8=A7=92=E5=BA=A6=E8=A3=9C=E6=AD=A3?= =?UTF-8?q?=E3=82=92=E9=BB=84=E8=89=B2=E4=BB=A5=E5=A4=96=E3=81=A7=E3=82=82?= =?UTF-8?q?=E5=87=BA=E6=9D=A5=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- front_camera/Makefile | 2 +- .../front_camera/color_rectangle_detector.py | 60 +++++++++++++++++++ .../front_camera/frame_timing_calculator.py | 6 +- .../front_camera/get_correction_angle.py | 30 ++++++---- .../front_camera/yellow_rectangle_detector.py | 53 ---------------- module/Motion/AreaBCameraAction.cpp | 6 +- module/Motion/AreaBCameraAction.h | 3 +- module/Motion/CorrectingRotation.cpp | 14 +++-- module/Motion/CorrectingRotation.h | 6 +- module/MotionParser.cpp | 9 +-- 10 files changed, 103 insertions(+), 86 deletions(-) create mode 100644 front_camera/front_camera/color_rectangle_detector.py delete mode 100644 front_camera/front_camera/yellow_rectangle_detector.py diff --git a/front_camera/Makefile b/front_camera/Makefile index e5d8c5c..f913e7b 100644 --- a/front_camera/Makefile +++ b/front_camera/Makefile @@ -40,7 +40,7 @@ plarail-image: correction-angle: @${make} kill - @sudo python3 front_camera/get_correction_angle.py + @sudo python3 front_camera/get_correction_angle.py $(COLOR) rm-img: sudo rm -rf image_data/ diff --git a/front_camera/front_camera/color_rectangle_detector.py b/front_camera/front_camera/color_rectangle_detector.py new file mode 100644 index 0000000..91ef8ae --- /dev/null +++ b/front_camera/front_camera/color_rectangle_detector.py @@ -0,0 +1,60 @@ +""" +動画中の背景下部の指定色検出クラス +@author: bizyutyu YKhm20020 CHIHAYATAKU +""" + +import cv2 + + + +class ColorRectangleDetector: + # 色のHSV範囲を定数として定義 + COLOR_BOUNDS = { + 'yellow': ((20, 160, 160), (30, 255, 255)), + 'red': ((0, 160, 160), (10, 255, 255)), + } + + def __init__(self, color="yellow"): + """コンストラクタ + + Args: + color (str): 検出する色の名前。COLOR_BOUNDSに定義された色から選択する。 + """ + # 対象の色の範囲を保持 + if color not in self.COLOR_BOUNDS: + raise ValueError(f"{color}は定義されていません。定義されている色: {list(self.COLOR_BOUNDS.keys())}") + self.lower_bound, self.upper_bound = self.COLOR_BOUNDS[color] + self.color = color + + + def detect_rectangle(self, frame): + """対象色の矩形を検出する。 + + Args: + frame (int): 動画の何フレーム目を検出の対象とするかを示す数値 + """ + + # HSV色空間に変換 + hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) + + # 対象の色のマスクを作成 + mask = cv2.inRange(hsv, self.lower_bound, self.upper_bound) + + # 輪郭を検出 + contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + + # 最大の輪郭を見つける + if contours: + largest_contour = max(contours, key=cv2.contourArea) + return cv2.boundingRect(largest_contour) + + return None + + +if __name__ == "__main__": + video_path = "video_data/recorded_video.h264" + output_path = "image_data/Pla.jpg" + + # 循環インポート回避のため一旦コメントアウト + # frameTimingCalculator = FrameTimingCalculator(video_path) + # frameTimingCalculator.get_target_timing() diff --git a/front_camera/front_camera/frame_timing_calculator.py b/front_camera/front_camera/frame_timing_calculator.py index 7dee289..0449c1e 100644 --- a/front_camera/front_camera/frame_timing_calculator.py +++ b/front_camera/front_camera/frame_timing_calculator.py @@ -5,7 +5,7 @@ import os import cv2 -from yellow_rectangle_detector import YellowRectangleDetector +from color_rectangle_detector import ColorRectangleDetector class FrameTimingCalculator: @@ -20,7 +20,7 @@ def __init__(self, video_path, bounding_box_width=300, bounding_box_height=600): self.video_path = video_path self.bounding_box_width = bounding_box_width self.bounding_box_height = bounding_box_height - self.yellow_rectangle_detector = YellowRectangleDetector() + self.yellow_rectangle_detector = ColorRectangleDetector("yellow") def get_target_timing(self): """映像から特定のフレームを画像として切り出すタイミングを取得する""" @@ -35,7 +35,7 @@ def get_target_timing(self): return None # 黄色い長方形を検出 - yellow_rect = self.yellow_rectangle_detector.detect_yellow_rectangle(first_frame) + yellow_rect = self.yellow_rectangle_detector.detect_rectangle(first_frame) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) diff --git a/front_camera/front_camera/get_correction_angle.py b/front_camera/front_camera/get_correction_angle.py index 1c3f966..1fa5f75 100644 --- a/front_camera/front_camera/get_correction_angle.py +++ b/front_camera/front_camera/get_correction_angle.py @@ -1,6 +1,6 @@ """ 指定画像中の背景(の黄色矩形)が中心に来るような補正角度を返す -@author: bizyutyu YKhm20020 keiya121 +@author: bizyutyu YKhm20020 keiya121 CHIHAYATAKU """ import argparse @@ -8,13 +8,16 @@ import cv2 import math from camera_interface import CameraInterface -from yellow_rectangle_detector import YellowRectangleDetector +from color_rectangle_detector import ColorRectangleDetector class GetCorrectionAngle: - def __init__(self): - """コンストラクタ""" + def __init__(self, color="yellow"): + """コンストラクタ + Args: + color (str): 補正対象の色 + """ - self.yellow_rectangle_detector = YellowRectangleDetector() + self.rectangle_detector = ColorRectangleDetector(color) def calculate_correction_angle(self, image_path): """補正角度を算出する @@ -24,7 +27,7 @@ def calculate_correction_angle(self, image_path): Raises: ValueError: 画像読み込みができない - ValueError: 黄色の矩形を検出できない + ValueError: 対象色の矩形を検出できない Returns: int: 補正角度 @@ -39,13 +42,13 @@ def calculate_correction_angle(self, image_path): image_center_x = image.shape[1] // 2 # image_center_y = image.shape[0] // 2 - # 黄色い長方形を検出 - yellow_rect = self.yellow_rectangle_detector.detect_yellow_rectangle(image) - if yellow_rect is None: - raise ValueError("黄色い長方形が検出されませんでした") + # 対象色の長方形を検出 + target_color_rect = self.rectangle_detector.detect_rectangle(image) + if target_color_rect is None: + raise ValueError(f"{self.detector.color}色の長方形が検出されませんでした") - # 黄色い長方形の中心のx座標を計算 - rect_center_x = yellow_rect[0] + yellow_rect[2] // 2 + # 対象色の長方形の中心のx座標を計算 + rect_center_x = target_color_rect[0] + target_color_rect[2] // 2 # x軸方向の偏差を計算 delta_x = rect_center_x - image_center_x @@ -59,6 +62,7 @@ def calculate_correction_angle(self, image_path): if __name__ == "__main__": parser = argparse.ArgumentParser(description="フロントカメラに関するプログラム") parser.add_argument("--camera-num", type=int, default=0, help="カメラIDを指定する") + parser.add_argument("--color", type=str, default="yellow", help="検出する矩形の色を指定する") args = parser.parse_args() camera = CameraInterface() @@ -79,7 +83,7 @@ def calculate_correction_angle(self, image_path): camera.capture_save_image(save_path) #補正角度の算出 - angle_corrector = GetCorrectionAngle() + angle_corrector = GetCorrectionAngle(args.color) angle = angle_corrector.calculate_correction_angle(save_path) #四捨五入してintに変換 angle_int = int(round(angle)) diff --git a/front_camera/front_camera/yellow_rectangle_detector.py b/front_camera/front_camera/yellow_rectangle_detector.py deleted file mode 100644 index 2d34bf2..0000000 --- a/front_camera/front_camera/yellow_rectangle_detector.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -動画中の背景下部の黄色検出クラス -@author: bizyutyu YKhm20020 -""" - -import cv2 - - - -class YellowRectangleDetector: - def __init__(self, lower_yellow = (20, 160, 160), upper_yellow = (30, 255, 255)): - """コンストラクタ - - Args: - lower_yellow (tuple): 黄色と認識するBGR値範囲の下限、初期値は (20, 160, 160). - upper_yellow (tuple): 黄色と認識するBGR値範囲の上限、初期値は (30, 255, 255). - """ - # 受け取った黄色の範囲を保持 - self.lower_yellow = lower_yellow - self.upper_yellow = upper_yellow - - - def detect_yellow_rectangle(self, frame): - """配置エリアAにおける背景を検出するため、黄色の矩形を検出する。 - - Args: - frame (int): 動画の何フレーム目を検出の対象とするかを示す数値 - """ - - # HSV色空間に変換 - hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) - - # 黄色のマスクを作成 - mask = cv2.inRange(hsv, self.lower_yellow, self.upper_yellow) - - # 輪郭を検出 - contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) - - # 最大の輪郭を見つける - if contours: - largest_contour = max(contours, key=cv2.contourArea) - return cv2.boundingRect(largest_contour) - - return None - - -if __name__ == "__main__": - video_path = "video_data/recorded_video.h264" - output_path = "image_data/Pla.jpg" - - # 循環インポート回避のため一旦コメントアウト - # frameTimingCalculator = FrameTimingCalculator(video_path) - # frameTimingCalculator.get_target_timing() diff --git a/module/Motion/AreaBCameraAction.cpp b/module/Motion/AreaBCameraAction.cpp index e7dbec6..9a81029 100644 --- a/module/Motion/AreaBCameraAction.cpp +++ b/module/Motion/AreaBCameraAction.cpp @@ -1,7 +1,7 @@ /** * @file AreaBCameraAction.cpp * @brief 配置エリアBにおけるプラレール・背景撮影動作 - * @author keiya121 + * @author keiya121 CHIHAYATAKU */ #include "AreaBCameraAction.h" @@ -16,7 +16,7 @@ AreaBCameraAction::AreaBCameraAction(int _preTargetAngle, int _prePwm, bool _isC isClockwise(_isClockwise), pwmXr(_pwmXr), postTargetAngle(_postTargetAngle), - postPwm(_postPwm){}; + postPwm(_postPwm) {}; void AreaBCameraAction::run() { @@ -30,7 +30,7 @@ void AreaBCameraAction::run() ResetWheelsMotorPwm rm; PwmRotation prePR(preTargetAngle, prePwm, isClockwise); PwmRotation postPR(postTargetAngle, postPwm, !isClockwise); - CorrectingRotation xr(pwmXr); + CorrectingRotation xr(pwmXr, colorXr); CameraAction ca(CameraAction::Subject::PLARAIL); // 撮影のための回頭をする diff --git a/module/Motion/AreaBCameraAction.h b/module/Motion/AreaBCameraAction.h index 79495d2..dcf82f1 100644 --- a/module/Motion/AreaBCameraAction.h +++ b/module/Motion/AreaBCameraAction.h @@ -1,7 +1,7 @@ /** * @file AreaBCameraAction.h * @brief 配置エリアBにおけるプラレール・背景撮影動作 - * @author keiya121 + * @author keiya121 CHIHAYATAKU */ #ifndef AREABCAMERAACTION_H @@ -50,6 +50,7 @@ class AreaBCameraAction : public CompositeMotion { int pwmXr; // 角度補正回頭用のPWM値 int postTargetAngle; // 2回目の回頭目標回転角度(deg) int postPwm; // 2回目の回頭PWM値 + const char* colorXr = "yellow"; }; #endif \ No newline at end of file diff --git a/module/Motion/CorrectingRotation.cpp b/module/Motion/CorrectingRotation.cpp index c96f3b9..eaccc76 100644 --- a/module/Motion/CorrectingRotation.cpp +++ b/module/Motion/CorrectingRotation.cpp @@ -1,7 +1,7 @@ /** * @file CorrectingRotation.cpp * @brief プラレール・背景撮影のための角度補正回頭動作 - * @author bizyutyu + * @author bizyutyu CHIHAYATAKU */ #include "CorrectingRotation.h" @@ -9,7 +9,7 @@ using namespace std; -CorrectingRotation::CorrectingRotation(int _pwm) : pwm(_pwm){}; +CorrectingRotation::CorrectingRotation(int _pwm, const char* _color) : pwm(_pwm), color(_color) {}; void CorrectingRotation::run() { @@ -17,8 +17,10 @@ void CorrectingRotation::run() // Pytnon側で算出に必要な画像取得から補正角度算出までを行う char cmd[512]; snprintf(cmd, 512, - "cd etrobocon2024/front_camera && make correction-angle > correction_angle.txt && sudo " - "chmod 644 correction_angle.txt && cd ../.."); + "cd etrobocon2024/front_camera && make correction-angle COLOR=\"--color %s\"> " + "correction_angle.txt && sudo " + "chmod 644 correction_angle.txt && cd ../..", + color); system(cmd); // 一時ファイルから出力を読み取る @@ -75,7 +77,7 @@ void CorrectingRotation::logRunning() { char buf[LARGE_BUF_SIZE]; // log用にメッセージを一時保持する領域 - snprintf(buf, LARGE_BUF_SIZE, "Run CorrectingRotation (correctionAngle: %d, pwm: %d)", - correctionAngle, pwm); + snprintf(buf, LARGE_BUF_SIZE, "Run CorrectingRotation (correctionAngle: %d, pwm: %d, color: %s)", + correctionAngle, pwm, color); logger.log(buf); } diff --git a/module/Motion/CorrectingRotation.h b/module/Motion/CorrectingRotation.h index 3750668..36294cf 100644 --- a/module/Motion/CorrectingRotation.h +++ b/module/Motion/CorrectingRotation.h @@ -1,7 +1,7 @@ /** * @file CorrectingRotation.h * @brief プラレール・背景撮影のための角度補正回頭動作 - * @author bizyutyu + * @author bizyutyu CHIHAYATAKU */ #ifndef CORRECTINGROTATION_H @@ -16,8 +16,9 @@ class CorrectingRotation : public CompositeMotion { /** * コンストラクタ * @param _pwm 角度補正回頭時のPWM値 + * @param _color 検出する矩形の色("yellow" or "red") */ - CorrectingRotation(int _pwm = 50); + CorrectingRotation(int _pwm = 50, const char* _color = "yellow"); /** * @brief プラレール・背景撮影のための角度補正回頭動作を行う @@ -32,5 +33,6 @@ class CorrectingRotation : public CompositeMotion { private: int pwm; // 指定PWM値 0~100 int correctionAngle; // 補正角度 0~360 + const char* color; // 検出する矩形の色 }; #endif diff --git a/module/MotionParser.cpp b/module/MotionParser.cpp index 5e341ba..5024cb3 100644 --- a/module/MotionParser.cpp +++ b/module/MotionParser.cpp @@ -1,7 +1,7 @@ /** * @file MotionParser.cpp * @brief 動作コマンドファイルを解析するクラス - * @author keiya121 bizyutyu + * @author keiya121 bizyutyu CHIHAYATAKU */ #include "MotionParser.h" @@ -125,9 +125,10 @@ vector MotionParser::createMotions(const char* commandFilePath, int tar atof(params[6]), // 前進、後退の距離 atof(params[7])); // 前進、後退の速度 - motionList.push_back(ac); // 動作リストに追加 - } else if(command == COMMAND::XR) { // プラレール・背景撮影のための角度補正回頭の追加 - CorrectingRotation* xr = new CorrectingRotation(atoi(params[1])); // 目標PWM + motionList.push_back(ac); // 動作リストに追加 + } else if(command == COMMAND::XR) { // 角度補正回頭動作の生成 + CorrectingRotation* xr = new CorrectingRotation(atoi(params[1]), // 目標PWM + params[2]); // 補正対象の色 motionList.push_back(xr); // 動作リストに追加 } else if(command == COMMAND::BC) { // 配置エリアB撮影動作の生成