From e358c825d39e2b8ac348f2f8780a1ba38b0a71e0 Mon Sep 17 00:00:00 2001 From: lxm <1367240116@qq.com> Date: Fri, 30 Jun 2023 10:49:29 +0800 Subject: [PATCH 1/9] add color line detection code --- CMakeLists.txt | 7 + algorithm/color_line/sv_color_line.cpp | 252 +++++++++++++++++++++++ include/sv_color_line.h | 48 +++++ include/sv_world.h | 1 + params/a-params/sv_algorithm_params.json | 9 + samples/demo/color_line_detect.cpp | 69 +++++++ 6 files changed, 386 insertions(+) create mode 100644 algorithm/color_line/sv_color_line.cpp create mode 100644 include/sv_color_line.h create mode 100644 samples/demo/color_line_detect.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 77f1305..0a0a2d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/common_det/cuda ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/landing_det/cuda ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/tracking/ocv470 + ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/color_line ${CMAKE_CURRENT_SOURCE_DIR}/video_io ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/ellipse_det ${CMAKE_CURRENT_SOURCE_DIR}/utils @@ -108,6 +109,7 @@ set( include/sv_common_det.h include/sv_landing_det.h include/sv_tracking.h + include/sv_color_line.h include/sv_video_input.h include/sv_video_output.h include/sv_world.h @@ -148,10 +150,13 @@ set(spirecv_SRCS algorithm/common_det/sv_common_det.cpp algorithm/landing_det/sv_landing_det.cpp algorithm/tracking/sv_tracking.cpp + algorithm/color_line/sv_color_line.cpp ) file(GLOB ALG_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/tracking/ocv470/*.cpp) list(APPEND spirecv_SRCS ${ALG_SRC_FILES}) +file(GLOB ALG_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/color_line/*.cpp) +list(APPEND spirecv_SRCS ${ALG_SRC_FILES}) file(GLOB ALG_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/video_io/*.cpp) list(APPEND spirecv_SRCS ${ALG_SRC_FILES}) file(GLOB ALG_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/utils/*.cpp) @@ -252,6 +257,8 @@ add_executable(LandingMarkerDetection samples/demo/landing_marker_detection.cpp) target_link_libraries(LandingMarkerDetection sv_world) add_executable(SingleObjectTracking samples/demo/single_object_tracking.cpp) target_link_libraries(SingleObjectTracking sv_world) +add_executable(ColorLineDetection samples/demo/color_line_detect.cpp) +target_link_libraries(ColorLineDetection sv_world) add_executable(UdpDetectionInfoReceiver samples/demo/udp_detection_info_receiver.cpp) target_link_libraries(UdpDetectionInfoReceiver sv_world) add_executable(UdpDetectionInfoSender samples/demo/udp_detection_info_sender.cpp) diff --git a/algorithm/color_line/sv_color_line.cpp b/algorithm/color_line/sv_color_line.cpp new file mode 100644 index 0000000..671423a --- /dev/null +++ b/algorithm/color_line/sv_color_line.cpp @@ -0,0 +1,252 @@ +#include "sv_color_line.h" +#include "gason.h" +#include "sv_util.h" +#include +#include + + +namespace sv { +ColorLineDetector::ColorLineDetector() +{ + this->is_load_parameter = false; +} + +ColorLineDetector::~ColorLineDetector() +{ +} + +void ColorLineDetector::_load() +{ + JsonValue all_value; + JsonAllocator allocator; + _load_all_json(this->alg_params_fn, all_value, allocator); + + JsonValue colorliner_params_value; + _parser_algorithm_params("ColorLineDetector", all_value, colorliner_params_value); + + for (auto i : colorliner_params_value) { + if ("line_color" == std::string(i->key)) { + this->line_color = i->value.toString(); + std::cout << "line_color: " << this->line_color << std::endl; + } + else if ("line_location" == std::string(i->key)) { + this->line_location = i->value.toNumber(); + } + else if ("line_location_a1" == std::string(i->key)) { + this->line_location_a1 = i->value.toNumber(); + } + else if ("line_location_a2" == std::string(i->key)) { + this->line_location_a2 = i->value.toNumber(); + } + + } + +} + +void ColorLineDetector::get_line_area(cv::Mat &frame, cv::Mat &line_area, cv::Mat &line_area_a1, cv::Mat &line_area_a2) { + + int h = frame.rows; + half_h = h / 2.0; + half_w = frame.cols / 2.0; + int l1 = int(h * (1 - line_location - 0.05)); + int l2 = int(h * (1 - line_location)); + line_area = frame(cv::Range(l1, l2), cv::Range::all()); + + l1 = int(h * (1 - line_location_a1 - 0.05)); + l2 = int(h * (1 - line_location_a1)); + line_area_a1 = frame(cv::Range(l1, l2), cv::Range::all()); + cy_a1 = l1; + + l1 = int(h * (1 - line_location_a2 - 0.05)); + l2 = int(h * (1 - line_location_a2)); + cy_a2 = l1; + line_area_a2 = frame(cv::Range(l1, l2), cv::Range::all()); +} + +float ColorLineDetector::cnt_area(std::vector cnt) { + float area = cv::contourArea(cnt); + return area; +} + +void ColorLineDetector::seg(cv::Mat line_area, cv::Mat line_area_a1, cv::Mat line_area_a2, std::string _line_color, cv::Point ¢er, int &area, cv::Point ¢er_a1, cv::Point ¢er_a2) { + int hmin, smin, vmin, hmax, smax, vmax; + if (_line_color == "black") { + hmin = 0; + smin = 0; + vmin = 0; + hmax = 180; + smax = 255; + vmax = 46; + } + else if (_line_color == "red") { + hmin = 0; + smin = 43; + vmin = 46; + hmax = 10; + smax = 255; + vmax = 255; + } + else if (_line_color == "yellow") { + hmin = 26; + smin = 43; + vmin = 46; + hmax = 34; + smax = 255; + vmax = 255; + } + else if (_line_color == "green") { + hmin = 35; + smin = 43; + vmin = 46; + hmax = 77; + smax = 255; + vmax = 255; + } + else if (_line_color == "blue") { + hmin = 100; + smin = 43; + vmin = 46; + hmax = 124; + smax = 255; + vmax = 255; + } + else { + hmin = 0; + smin = 0; + vmin = 0; + hmax = 180; + smax = 255; + vmax = 46; + } + + cv::cvtColor(line_area, line_area, cv::COLOR_BGR2HSV); + cv::inRange(line_area, cv::Scalar(hmin, smin, vmin), cv::Scalar(hmax, smax, vmax), line_area); + + cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5)); + cv::morphologyEx(line_area, line_area, cv::MORPH_OPEN, kernel); + + std::vector> contours; + std::vector hierarchy; + cv::findContours(line_area, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); + + if (contours.size() > 0) { + cv::Rect rect = cv::boundingRect(contours[0]); + int cx = rect.x + rect.width / 2; + int cy = rect.y + rect.height / 2; + std::sort(contours.begin(), contours.end(),[](const std::vector& a, const std::vector& b) {return cv::contourArea(a) > cv::contourArea(b);}); + area = cnt_area(contours[0]); + center = cv::Point(cx, cy); + } + + cv::cvtColor(line_area_a1, line_area_a1, cv::COLOR_BGR2HSV); + cv::inRange(line_area_a1, cv::Scalar(hmin, smin, vmin), cv::Scalar(hmax, smax, vmax), line_area_a1); + + //cv2.MORPH_CLOSE 先进行膨胀,再进行腐蚀操作 + kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5)); + cv::morphologyEx(line_area_a1, line_area_a1, cv::MORPH_CLOSE, kernel); + + std::vector> contours_a1; + cv::findContours(line_area_a1, contours_a1, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); + + if (contours_a1.size() > 0) { + cv::Rect rect = cv::boundingRect(contours_a1[0]); + int cx = rect.x + rect.width / 2; + int cy = rect.y + rect.height / 2 + cy_a1; + center_a1 = cv::Point(cx - half_w, cy - half_h); + } + + cv::cvtColor(line_area_a2, line_area_a2, cv::COLOR_BGR2HSV); + cv::inRange(line_area_a2, cv::Scalar(hmin, smin, vmin), cv::Scalar(hmax, smax, vmax), line_area_a2); + + kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5)); + cv::morphologyEx(line_area_a2, line_area_a2, cv::MORPH_CLOSE, kernel); + + std::vector> contours_a2; + cv::findContours(line_area_a2, contours_a2, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); + + if (contours_a2.size() > 0) { + cv::Rect rect = cv::boundingRect(contours_a2[0]); + int cx = rect.x + rect.width / 2; + int cy = rect.y + rect.height / 2 + cy_a2; + center_a2 = cv::Point(cx - half_w, cy - half_h); + } +} + +void ColorLineDetector::detect(cv::Mat img, sv::TargetsInFrame& tgts_) +{ + + if(!this->is_load_parameter) + { + _load(); + + this->is_load_parameter = true; + } + int area_n = -1; + cv::Mat area_base, area_base_a1, area_base_a2; + cv::Point cxcy_n(0, 0), center_a1_n(0,0), center_a2_n(0, 0); + + get_line_area(img, area_base, area_base_a1, area_base_a2); + seg(area_base, area_base_a1, area_base_a2, line_color, cxcy_n, area_n, center_a1_n, center_a2_n); + pose.x = 0.0; + pose.y = -1.0; + pose.z = 0.0; + + + if (area_n > 0) + { + circle(area_base, cv::Point(cxcy_n.x, cxcy_n.y), 4, cv::Scalar(0, 0, 255), -1); + double angle = (cxcy_n.x - this->camera_matrix.at(0, 2)) / this->camera_matrix.at(0, 2) * atan((double)(area_base.rows / 2) / this->fov_x); + pose.x = angle; + pose.y = 1.0; + } + else + { + cv::Point cxcy__n(0, 0), center_a1__n(0, 0), center_a2__n(0, 0); + seg(area_base, area_base_a1, area_base_a2, line_color, cxcy__n, area_n = 0, center_a1__n, center_a2__n); + if (area_n > 0) + { + circle(area_base, cv::Point(cxcy_n.x, cxcy_n.y), 4, cv::Scalar(0, 0, 255), -1); + double angle = (cxcy_n.x - this->camera_matrix.at(0, 2)) / this->camera_matrix.at(0, 2) * atan((double)(area_base.rows / 2) / this->fov_x); + pose.x = angle; + pose.y = 1.0; + pose.z = 0.0; + + } + } + + tgts_.setSize(img.cols, img.rows); + tgts_.setFOV(this->fov_x, this->fov_y); + auto t1 = std::chrono::system_clock::now(); + tgts_.setFPS(1000.0/std::chrono::duration_cast(t1- this->_t0).count()); + this->_t0 = std::chrono::system_clock::now(); + tgts_.setTimeNow(); + + + if(area_n > 0) + { + Target tgt; + tgt.los_ax = pose.x; + if(cxcy_n.x !=0 || cxcy_n.y !=0) + { + tgt.cx = cxcy_n.x; + tgt.cy = cxcy_n.y; + } + else if(center_a1_n.x != 0 || center_a1_n.y != 0) + { + tgt.cx = center_a1_n.x; + tgt.cy = center_a1_n.y; + } + else if(center_a2_n.x != 0 || center_a2_n.y != 0) + { + tgt.cx = center_a2_n.x; + tgt.cy = center_a2_n.y; + } + + tgts_.targets.push_back(tgt); + } + + +} + +} + diff --git a/include/sv_color_line.h b/include/sv_color_line.h new file mode 100644 index 0000000..2ebfe85 --- /dev/null +++ b/include/sv_color_line.h @@ -0,0 +1,48 @@ +#ifndef __SV_COLOR_LINE__ +#define __SV_COLOR_LINE__ + +#include "sv_core.h" +#include +#include +#include + + + +namespace sv { + +class ColorLineDetector : public CameraAlgorithm +{ +public: + ColorLineDetector(); + ~ColorLineDetector(); + + void detect(cv::Mat img_, TargetsInFrame& tgts_); + +protected: + + float cy_a1; + float cy_a2; + float half_h; + float half_w; + + cv::Mat img; + cv::Point3d pose; + + double line_location; + double line_location_a1; + double line_location_a2; + + bool is_load_parameter; + + std::string line_color; + + void _load(); + float cnt_area(std::vector cnt); + void get_line_area(cv::Mat &frame, cv::Mat &line_area, cv::Mat &line_area_a1, cv::Mat &line_area_a2); + void seg(cv::Mat line_area, cv::Mat line_area_a1, cv::Mat line_area_a2, std::string _line_color, cv::Point ¢er, int &area, cv::Point ¢er_a1, cv::Point ¢er_a2); + +}; + + +} +#endif \ No newline at end of file diff --git a/include/sv_world.h b/include/sv_world.h index 5746122..14fccd1 100644 --- a/include/sv_world.h +++ b/include/sv_world.h @@ -5,6 +5,7 @@ #include "sv_common_det.h" #include "sv_landing_det.h" #include "sv_tracking.h" +#include "sv_color_line.h" #include "sv_video_input.h" #include "sv_video_output.h" diff --git a/params/a-params/sv_algorithm_params.json b/params/a-params/sv_algorithm_params.json index 81362a6..9e8e447 100644 --- a/params/a-params/sv_algorithm_params.json +++ b/params/a-params/sv_algorithm_params.json @@ -174,5 +174,14 @@ "perspectiveRemovePixelPerCell": 4, "polygonalApproxAccuracyRate": 0.03, "useAruco3Detection": false + + }, + "ColorLineDetector": { + "line_color": "black", + "line_location": 0.5, + "line_location_a1": 0.3, + "line_location_a2": 0.7, + + } } diff --git a/samples/demo/color_line_detect.cpp b/samples/demo/color_line_detect.cpp new file mode 100644 index 0000000..bd554eb --- /dev/null +++ b/samples/demo/color_line_detect.cpp @@ -0,0 +1,69 @@ +#include +#include +// 包含SpireCV SDK头文件 +#include + +using namespace std; +using namespace sv; + + + +int main(int argc, char *argv[]) { + // 实例化 color line detection 检测器类 + sv::ColorLineDetector cld; + // 手动导入相机参数,如果使用Amov的G1等吊舱或相机,则可以忽略该步骤,将自动下载相机参数文件 + cld.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml"); + + // 打开摄像头 + sv::Camera cap; + cap.setWH(640, 480); + //cap.setFps(30); + cap.open(sv::CameraType::WEBCAM, 0); // CameraID 0 + // 实例化OpenCV的Mat类,用于内存单帧图像 + cv::Mat img; + int frame_id = 0; + while (1) + { + // 实例化SpireCV的 单帧检测结果 接口类 TargetsInFrame + sv::TargetsInFrame tgts(frame_id++); + // 读取一帧图像到img + cap.read(img); + cv::resize(img, img, cv::Size(cld.image_width, cld.image_height)); + + // 执行 color line detection 检测 + cld.detect(img, tgts); + // 可视化检测结果,叠加到img上 + sv::drawTargetsInFrame(img, tgts); + + // 控制台打印 color line detection 检测结果 + printf("Frame-[%d]\n", frame_id); + // 打印当前检测的FPS + printf(" FPS = %.2f\n", tgts.fps); + // 打印当前相机的视场角(degree) + printf(" FOV (fx, fy) = (%.2f, %.2f)\n", tgts.fov_x, tgts.fov_y); + // 打印当前输入图像的像素宽度和高度 + printf(" Frame Size (width, height) = (%d, %d)\n", tgts.width, tgts.height); + for (int i=0; i Date: Mon, 3 Jul 2023 12:19:38 +0800 Subject: [PATCH 2/9] modefied some variables, abbreviation, and some files path bugs. --- algorithm/color_line/sv_color_line.cpp | 275 +++++++++--------- algorithm/sv_algorithm_base.cpp | 2 +- include/sv_color_line.h | 29 +- params/a-params/sv_algorithm_params.json | 3 +- samples/demo/aruco_detection.cpp | 2 +- samples/demo/color_line_detect.cpp | 31 +- samples/demo/common_object_detection.cpp | 2 +- .../demo/detection_with_clicked_tracking.cpp | 4 +- samples/demo/ellipse_detection.cpp | 2 +- ...gimbal_detection_with_clicked_tracking.cpp | 4 +- .../demo/gimbal_landing_marker_detection.cpp | 2 +- .../demo/gimbal_udp_detection_info_sender.cpp | 2 +- samples/demo/landing_marker_detection.cpp | 2 +- samples/demo/single_object_tracking.cpp | 8 +- samples/demo/udp_detection_info_sender.cpp | 2 +- samples/demo/video_saving.cpp | 2 +- 16 files changed, 185 insertions(+), 187 deletions(-) diff --git a/algorithm/color_line/sv_color_line.cpp b/algorithm/color_line/sv_color_line.cpp index 671423a..6af5fa0 100644 --- a/algorithm/color_line/sv_color_line.cpp +++ b/algorithm/color_line/sv_color_line.cpp @@ -4,8 +4,11 @@ #include #include +namespace sv +{ + + -namespace sv { ColorLineDetector::ColorLineDetector() { this->is_load_parameter = false; @@ -17,60 +20,67 @@ ColorLineDetector::~ColorLineDetector() void ColorLineDetector::_load() { - JsonValue all_value; - JsonAllocator allocator; - _load_all_json(this->alg_params_fn, all_value, allocator); + JsonValue all_value; + JsonAllocator allocator; + _load_all_json(this->alg_params_fn, all_value, allocator); - JsonValue colorliner_params_value; - _parser_algorithm_params("ColorLineDetector", all_value, colorliner_params_value); - - for (auto i : colorliner_params_value) { - if ("line_color" == std::string(i->key)) { - this->line_color = i->value.toString(); - std::cout << "line_color: " << this->line_color << std::endl; - } - else if ("line_location" == std::string(i->key)) { - this->line_location = i->value.toNumber(); - } - else if ("line_location_a1" == std::string(i->key)) { - this->line_location_a1 = i->value.toNumber(); - } - else if ("line_location_a2" == std::string(i->key)) { - this->line_location_a2 = i->value.toNumber(); - } - - } + JsonValue colorliner_params_value; + _parser_algorithm_params("ColorLineDetector", all_value, colorliner_params_value); + for (auto i : colorliner_params_value) + { + if ("line_color" == std::string(i->key)) + { + this->line_color = i->value.toString(); + std::cout << "line_color: " << this->line_color << std::endl; + } + else if ("line_location" == std::string(i->key)) + { + this->line_location = i->value.toNumber(); + } + else if ("line_location_a1" == std::string(i->key)) + { + this->line_location_a1 = i->value.toNumber(); + } + else if ("line_location_a2" == std::string(i->key)) + { + this->line_location_a2 = i->value.toNumber(); + } + } } -void ColorLineDetector::get_line_area(cv::Mat &frame, cv::Mat &line_area, cv::Mat &line_area_a1, cv::Mat &line_area_a2) { - - int h = frame.rows; - half_h = h / 2.0; - half_w = frame.cols / 2.0; +void ColorLineDetector::get_line_area(cv::Mat &frame_, cv::Mat &line_area_, cv::Mat &line_area_a1_, cv::Mat &line_area_a2_) +{ + + int h = frame_.rows; + _half_h = h / 2.0; + _half_w = frame_.cols / 2.0; int l1 = int(h * (1 - line_location - 0.05)); int l2 = int(h * (1 - line_location)); - line_area = frame(cv::Range(l1, l2), cv::Range::all()); + line_area_ = frame_(cv::Range(l1, l2), cv::Range::all()); l1 = int(h * (1 - line_location_a1 - 0.05)); l2 = int(h * (1 - line_location_a1)); - line_area_a1 = frame(cv::Range(l1, l2), cv::Range::all()); - cy_a1 = l1; + line_area_a1_ = frame_(cv::Range(l1, l2), cv::Range::all()); + _cy_a1 = l1; l1 = int(h * (1 - line_location_a2 - 0.05)); l2 = int(h * (1 - line_location_a2)); - cy_a2 = l1; - line_area_a2 = frame(cv::Range(l1, l2), cv::Range::all()); + _cy_a2 = l1; + line_area_a2_ = frame_(cv::Range(l1, l2), cv::Range::all()); } -float ColorLineDetector::cnt_area(std::vector cnt) { - float area = cv::contourArea(cnt); +float ColorLineDetector::cnt_area(std::vector cnt_) +{ + float area = cv::contourArea(cnt_); return area; } -void ColorLineDetector::seg(cv::Mat line_area, cv::Mat line_area_a1, cv::Mat line_area_a2, std::string _line_color, cv::Point ¢er, int &area, cv::Point ¢er_a1, cv::Point ¢er_a2) { +void ColorLineDetector::seg(cv::Mat line_area_, cv::Mat line_area_a1_, cv::Mat line_area_a2_, std::string line_color_, cv::Point ¢er_, int &area_, cv::Point ¢er_a1_, cv::Point ¢er_a2_) +{ int hmin, smin, vmin, hmax, smax, vmax; - if (_line_color == "black") { + if (line_color_ == "black") + { hmin = 0; smin = 0; vmin = 0; @@ -78,7 +88,8 @@ void ColorLineDetector::seg(cv::Mat line_area, cv::Mat line_area_a1, cv::Mat lin smax = 255; vmax = 46; } - else if (_line_color == "red") { + else if (line_color_ == "red") + { hmin = 0; smin = 43; vmin = 46; @@ -86,7 +97,8 @@ void ColorLineDetector::seg(cv::Mat line_area, cv::Mat line_area_a1, cv::Mat lin smax = 255; vmax = 255; } - else if (_line_color == "yellow") { + else if (line_color_ == "yellow") + { hmin = 26; smin = 43; vmin = 46; @@ -94,7 +106,8 @@ void ColorLineDetector::seg(cv::Mat line_area, cv::Mat line_area_a1, cv::Mat lin smax = 255; vmax = 255; } - else if (_line_color == "green") { + else if (line_color_ == "green") + { hmin = 35; smin = 43; vmin = 46; @@ -102,7 +115,8 @@ void ColorLineDetector::seg(cv::Mat line_area, cv::Mat line_area_a1, cv::Mat lin smax = 255; vmax = 255; } - else if (_line_color == "blue") { + else if (line_color_ == "blue") + { hmin = 100; smin = 43; vmin = 46; @@ -110,7 +124,8 @@ void ColorLineDetector::seg(cv::Mat line_area, cv::Mat line_area_a1, cv::Mat lin smax = 255; vmax = 255; } - else { + else + { hmin = 0; smin = 0; vmin = 0; @@ -119,134 +134,130 @@ void ColorLineDetector::seg(cv::Mat line_area, cv::Mat line_area_a1, cv::Mat lin vmax = 46; } - cv::cvtColor(line_area, line_area, cv::COLOR_BGR2HSV); - cv::inRange(line_area, cv::Scalar(hmin, smin, vmin), cv::Scalar(hmax, smax, vmax), line_area); - + cv::cvtColor(line_area_, line_area_, cv::COLOR_BGR2HSV); + cv::inRange(line_area_, cv::Scalar(hmin, smin, vmin), cv::Scalar(hmax, smax, vmax), line_area_); + cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5)); - cv::morphologyEx(line_area, line_area, cv::MORPH_OPEN, kernel); - + cv::morphologyEx(line_area_, line_area_, cv::MORPH_OPEN, kernel); + std::vector> contours; std::vector hierarchy; - cv::findContours(line_area, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); - - if (contours.size() > 0) { + cv::findContours(line_area_, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); + + if (contours.size() > 0) + { cv::Rect rect = cv::boundingRect(contours[0]); int cx = rect.x + rect.width / 2; int cy = rect.y + rect.height / 2; - std::sort(contours.begin(), contours.end(),[](const std::vector& a, const std::vector& b) {return cv::contourArea(a) > cv::contourArea(b);}); - area = cnt_area(contours[0]); - center = cv::Point(cx, cy); + std::sort(contours.begin(), contours.end(),[](const std::vector &a, const std::vector &b) + {return cv::contourArea(a) > cv::contourArea(b);}); + area_ = cnt_area(contours[0]); + center_ = cv::Point(cx, cy); } - cv::cvtColor(line_area_a1, line_area_a1, cv::COLOR_BGR2HSV); - cv::inRange(line_area_a1, cv::Scalar(hmin, smin, vmin), cv::Scalar(hmax, smax, vmax), line_area_a1); + cv::cvtColor(line_area_a1_, line_area_a1_, cv::COLOR_BGR2HSV); + cv::inRange(line_area_a1_, cv::Scalar(hmin, smin, vmin), cv::Scalar(hmax, smax, vmax), line_area_a1_); //cv2.MORPH_CLOSE 先进行膨胀,再进行腐蚀操作 kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5)); - cv::morphologyEx(line_area_a1, line_area_a1, cv::MORPH_CLOSE, kernel); + cv::morphologyEx(line_area_a1_, line_area_a1_, cv::MORPH_CLOSE, kernel); std::vector> contours_a1; - cv::findContours(line_area_a1, contours_a1, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); - - if (contours_a1.size() > 0) { + cv::findContours(line_area_a1_, contours_a1, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); + + if (contours_a1.size() > 0){ cv::Rect rect = cv::boundingRect(contours_a1[0]); int cx = rect.x + rect.width / 2; - int cy = rect.y + rect.height / 2 + cy_a1; - center_a1 = cv::Point(cx - half_w, cy - half_h); + int cy = rect.y + rect.height / 2 + _cy_a1; + center_a1_ = cv::Point(cx - _half_w, cy - _half_h); } - cv::cvtColor(line_area_a2, line_area_a2, cv::COLOR_BGR2HSV); - cv::inRange(line_area_a2, cv::Scalar(hmin, smin, vmin), cv::Scalar(hmax, smax, vmax), line_area_a2); - + cv::cvtColor(line_area_a2_, line_area_a2_, cv::COLOR_BGR2HSV); + cv::inRange(line_area_a2_, cv::Scalar(hmin, smin, vmin), cv::Scalar(hmax, smax, vmax), line_area_a2_); + kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5)); - cv::morphologyEx(line_area_a2, line_area_a2, cv::MORPH_CLOSE, kernel); + cv::morphologyEx(line_area_a2_, line_area_a2_, cv::MORPH_CLOSE, kernel); std::vector> contours_a2; - cv::findContours(line_area_a2, contours_a2, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); + cv::findContours(line_area_a2_, contours_a2, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); - if (contours_a2.size() > 0) { + if (contours_a2.size() > 0) + { cv::Rect rect = cv::boundingRect(contours_a2[0]); int cx = rect.x + rect.width / 2; - int cy = rect.y + rect.height / 2 + cy_a2; - center_a2 = cv::Point(cx - half_w, cy - half_h); + int cy = rect.y + rect.height / 2 + _cy_a2; + center_a2_ = cv::Point(cx - _half_w, cy - _half_h); } } -void ColorLineDetector::detect(cv::Mat img, sv::TargetsInFrame& tgts_) +void ColorLineDetector::detect(cv::Mat img_, sv::TargetsInFrame &tgts_) { - if(!this->is_load_parameter) - { - _load(); + if (!this->is_load_parameter) + { + _load(); - this->is_load_parameter = true; - } - int area_n = -1; - cv::Mat area_base, area_base_a1, area_base_a2; - cv::Point cxcy_n(0, 0), center_a1_n(0,0), center_a2_n(0, 0); + this->is_load_parameter = true; + } + int area_n = -1; + cv::Mat area_base, area_base_a1, area_base_a2; + cv::Point cxcy_n(0, 0), center_a1_n(0, 0), center_a2_n(0, 0); - get_line_area(img, area_base, area_base_a1, area_base_a2); - seg(area_base, area_base_a1, area_base_a2, line_color, cxcy_n, area_n, center_a1_n, center_a2_n); - pose.x = 0.0; - pose.y = -1.0; - pose.z = 0.0; + get_line_area(img_, area_base, area_base_a1, area_base_a2); + seg(area_base, area_base_a1, area_base_a2, line_color, cxcy_n, area_n, center_a1_n, center_a2_n); + pose.x = 0.0; + pose.y = -1.0; + pose.z = 0.0; - - if (area_n > 0) - { - circle(area_base, cv::Point(cxcy_n.x, cxcy_n.y), 4, cv::Scalar(0, 0, 255), -1); - double angle = (cxcy_n.x - this->camera_matrix.at(0, 2)) / this->camera_matrix.at(0, 2) * atan((double)(area_base.rows / 2) / this->fov_x); - pose.x = angle; - pose.y = 1.0; - } - else - { - cv::Point cxcy__n(0, 0), center_a1__n(0, 0), center_a2__n(0, 0); - seg(area_base, area_base_a1, area_base_a2, line_color, cxcy__n, area_n = 0, center_a1__n, center_a2__n); - if (area_n > 0) - { + if (area_n > 0) + { circle(area_base, cv::Point(cxcy_n.x, cxcy_n.y), 4, cv::Scalar(0, 0, 255), -1); double angle = (cxcy_n.x - this->camera_matrix.at(0, 2)) / this->camera_matrix.at(0, 2) * atan((double)(area_base.rows / 2) / this->fov_x); pose.x = angle; pose.y = 1.0; - pose.z = 0.0; - - } - } - - tgts_.setSize(img.cols, img.rows); - tgts_.setFOV(this->fov_x, this->fov_y); - auto t1 = std::chrono::system_clock::now(); - tgts_.setFPS(1000.0/std::chrono::duration_cast(t1- this->_t0).count()); - this->_t0 = std::chrono::system_clock::now(); - tgts_.setTimeNow(); - - - if(area_n > 0) - { - Target tgt; - tgt.los_ax = pose.x; - if(cxcy_n.x !=0 || cxcy_n.y !=0) - { - tgt.cx = cxcy_n.x; - tgt.cy = cxcy_n.y; } - else if(center_a1_n.x != 0 || center_a1_n.y != 0) + else { - tgt.cx = center_a1_n.x; - tgt.cy = center_a1_n.y; - } - else if(center_a2_n.x != 0 || center_a2_n.y != 0) + cv::Point cxcy__n(0, 0), center_a1__n(0, 0), center_a2__n(0, 0); + seg(area_base, area_base_a1, area_base_a2, line_color, cxcy__n, area_n = 0, center_a1__n, center_a2__n); + if (area_n > 0) + { + circle(area_base, cv::Point(cxcy_n.x, cxcy_n.y), 4, cv::Scalar(0, 0, 255), -1); + double angle = (cxcy_n.x - this->camera_matrix.at(0, 2)) / this->camera_matrix.at(0, 2) * atan((double)(area_base.rows / 2) / this->fov_x); + pose.x = angle; + pose.y = 1.0; + pose.z = 0.0; + } + } + + tgts_.setSize(img_.cols, img_.rows); + tgts_.setFOV(this->fov_x, this->fov_y); + auto t1 = std::chrono::system_clock::now(); + tgts_.setFPS(1000.0 / std::chrono::duration_cast(t1 - this->_t0).count()); + this->_t0 = std::chrono::system_clock::now(); + tgts_.setTimeNow(); + + if (area_n > 0) { - tgt.cx = center_a2_n.x; - tgt.cy = center_a2_n.y; - } - - tgts_.targets.push_back(tgt); - } - + Target tgt; + tgt.los_ax = pose.x; + if (cxcy_n.x != 0 || cxcy_n.y != 0) + { + tgt.cx = cxcy_n.x; + tgt.cy = cxcy_n.y; + } + else if (center_a1_n.x != 0 || center_a1_n.y != 0) + { + tgt.cx = center_a1_n.x; + tgt.cy = center_a1_n.y; + } + else if (center_a2_n.x != 0 || center_a2_n.y != 0) + { + tgt.cx = center_a2_n.x; + tgt.cy = center_a2_n.y; + } + tgts_.targets.push_back(tgt); + } } - } - diff --git a/algorithm/sv_algorithm_base.cpp b/algorithm/sv_algorithm_base.cpp index f99142f..182bce3 100644 --- a/algorithm/sv_algorithm_base.cpp +++ b/algorithm/sv_algorithm_base.cpp @@ -9,7 +9,7 @@ #include "ellipse_detector.h" #define SV_MODEL_DIR "/SpireCV/models/" -#define SV_ROOT_DIR "/SpireCV/" +#define SV_ROOT_DIR "/SpireCV/params/a-params/" namespace sv { diff --git a/include/sv_color_line.h b/include/sv_color_line.h index 2ebfe85..3d2da94 100644 --- a/include/sv_color_line.h +++ b/include/sv_color_line.h @@ -6,26 +6,18 @@ #include #include +namespace sv +{ -namespace sv { - class ColorLineDetector : public CameraAlgorithm { public: ColorLineDetector(); ~ColorLineDetector(); - void detect(cv::Mat img_, TargetsInFrame& tgts_); - -protected: + void detect(cv::Mat img_, TargetsInFrame &tgts_); - float cy_a1; - float cy_a2; - float half_h; - float half_w; - - cv::Mat img; cv::Point3d pose; double line_location; @@ -36,13 +28,16 @@ protected: std::string line_color; +protected: + float _cy_a1; + float _cy_a2; + float _half_h; + float _half_w; + void _load(); - float cnt_area(std::vector cnt); - void get_line_area(cv::Mat &frame, cv::Mat &line_area, cv::Mat &line_area_a1, cv::Mat &line_area_a2); - void seg(cv::Mat line_area, cv::Mat line_area_a1, cv::Mat line_area_a2, std::string _line_color, cv::Point ¢er, int &area, cv::Point ¢er_a1, cv::Point ¢er_a2); - + float cnt_area(std::vector cnt_); + void get_line_area(cv::Mat &frame_, cv::Mat &line_area_, cv::Mat &line_area_a1_, cv::Mat &line_area_a2_); + void seg(cv::Mat line_area_, cv::Mat line_area_a1_, cv::Mat line_area_a2_, std::string line_color_, cv::Point ¢er_, int &area_, cv::Point ¢er_a1_, cv::Point ¢er_a2_); }; - - } #endif \ No newline at end of file diff --git a/params/a-params/sv_algorithm_params.json b/params/a-params/sv_algorithm_params.json index 9e8e447..5804ab4 100644 --- a/params/a-params/sv_algorithm_params.json +++ b/params/a-params/sv_algorithm_params.json @@ -180,8 +180,7 @@ "line_color": "black", "line_location": 0.5, "line_location_a1": 0.3, - "line_location_a2": 0.7, + "line_location_a2": 0.7 - } } diff --git a/samples/demo/aruco_detection.cpp b/samples/demo/aruco_detection.cpp index 0229400..b8520ba 100644 --- a/samples/demo/aruco_detection.cpp +++ b/samples/demo/aruco_detection.cpp @@ -9,7 +9,7 @@ int main(int argc, char *argv[]) { // 实例化Aruco检测器类 sv::ArucoDetector ad; // 手动导入相机参数,如果使用Amov的G1等吊舱或相机,则可以忽略该步骤,将自动下载相机参数文件 - ad.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml"); + ad.loadCameraParams(sv::get_home() + "/SpireCV/params/c-params/calib_webcam_640x480.yaml"); // 打开摄像头 sv::Camera cap; diff --git a/samples/demo/color_line_detect.cpp b/samples/demo/color_line_detect.cpp index bd554eb..2679518 100644 --- a/samples/demo/color_line_detect.cpp +++ b/samples/demo/color_line_detect.cpp @@ -6,19 +6,18 @@ using namespace std; using namespace sv; - - -int main(int argc, char *argv[]) { +int main(int argc, char *argv[]) +{ // 实例化 color line detection 检测器类 sv::ColorLineDetector cld; // 手动导入相机参数,如果使用Amov的G1等吊舱或相机,则可以忽略该步骤,将自动下载相机参数文件 - cld.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml"); - + cld.loadCameraParams(sv::get_home() + "/SpireCV/params/c-params/calib_webcam_640x480.yaml"); + // 打开摄像头 sv::Camera cap; cap.setWH(640, 480); - //cap.setFps(30); - cap.open(sv::CameraType::WEBCAM, 0); // CameraID 0 + // cap.setFps(30); + cap.open(sv::CameraType::WEBCAM, 0); // CameraID 0 // 实例化OpenCV的Mat类,用于内存单帧图像 cv::Mat img; int frame_id = 0; @@ -43,27 +42,21 @@ int main(int argc, char *argv[]) { printf(" FOV (fx, fy) = (%.2f, %.2f)\n", tgts.fov_x, tgts.fov_y); // 打印当前输入图像的像素宽度和高度 printf(" Frame Size (width, height) = (%d, %d)\n", tgts.width, tgts.height); - for (int i=0; i Date: Tue, 4 Jul 2023 09:00:26 +0000 Subject: [PATCH 3/9] update include/sv_video_base.h. Signed-off-by: Daniel <1367240116@qq.com> --- include/sv_video_base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sv_video_base.h b/include/sv_video_base.h index 47ee94d..f026ea3 100644 --- a/include/sv_video_base.h +++ b/include/sv_video_base.h @@ -323,7 +323,7 @@ protected: }; -enum class CameraType {NONE, WEBCAM, G1, Q10}; +enum class CameraType {NONE, WEBCAM, G1, Q10, MIPI}; class CameraBase { public: From 4554e8d2561a386eecfa9fd145b8f1dda2d0c5b7 Mon Sep 17 00:00:00 2001 From: Daniel <1367240116@qq.com> Date: Tue, 4 Jul 2023 09:04:29 +0000 Subject: [PATCH 4/9] update video_io/sv_video_base.cpp. Signed-off-by: Daniel <1367240116@qq.com> --- video_io/sv_video_base.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/video_io/sv_video_base.cpp b/video_io/sv_video_base.cpp index 573f744..d0bd037 100644 --- a/video_io/sv_video_base.cpp +++ b/video_io/sv_video_base.cpp @@ -1133,6 +1133,22 @@ void CameraBase::openImpl() // this->_cap.open(pipe); // cv::CAP_GSTREAMER this->_cap.open(pipe, cv::CAP_GSTREAMER); } + else if (this->_type == CameraType::MIPI) + { + char pipe[512]; + this->_cap.open(this->_camera_id); + if (this->_width <= 0 || this->_height <= 0) + { + this->_width = 1280; + this->_height = 720; + } + if (this->_fps <= 0) + { + this->_fps = 30; + } + sprintf(pipe, "nvarguscamerasrc framerate=(fraction)%d/1 ! nvvidconv flip-method=0 ! video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink", this->_fps, this->_width, this->_height); + this->_cap.open(pipe, cv::CAP_GSTREAMER); + } } void CameraBase::open(CameraType type, int id) { From e47854bcf1374d866b91304481191b4c1b94c743 Mon Sep 17 00:00:00 2001 From: Daniel <1367240116@qq.com> Date: Tue, 4 Jul 2023 09:05:17 +0000 Subject: [PATCH 5/9] update video_io/sv_video_input.cpp. Signed-off-by: Daniel <1367240116@qq.com> --- video_io/sv_video_input.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/video_io/sv_video_input.cpp b/video_io/sv_video_input.cpp index 352850b..14fcae9 100644 --- a/video_io/sv_video_input.cpp +++ b/video_io/sv_video_input.cpp @@ -70,6 +70,22 @@ void Camera::openImpl() sprintf(pipe, "rtspsrc location=rtsp://%s:%d/H264?W=%d&H=%d&FPS=%d&BR=4000000 latency=100 ! application/x-rtp,media=video ! rtph264depay ! parsebin ! nvv4l2decoder enable-max-performancegst=1 ! nvvidconv ! video/x-raw,format=(string)BGRx ! videoconvert ! appsink sync=false", this->_ip.c_str(), this->_port, this->_width, this->_height, this->_fps); this->_cap.open(pipe, cv::CAP_GSTREAMER); } + else if (this->_type == CameraType::MIPI) + { + char pipe[512]; + this->_cap.open(this->_camera_id); + if (this->_width <= 0 || this->_height <= 0) + { + this->_width = 1280; + this->_height = 720; + } + if (this->_fps <= 0) + { + this->_fps = 30; + } + sprintf(pipe, "nvarguscamerasrc framerate=(fraction)%d/1 ! nvvidconv flip-method=0 ! video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink", this->_fps, this->_width, this->_height); + this->_cap.open(pipe, cv::CAP_GSTREAMER); + } } From e4e6ef1fd815f133f9b4bd34c881c2f85cec98fb Mon Sep 17 00:00:00 2001 From: Daniel <1367240116@qq.com> Date: Wed, 5 Jul 2023 04:18:28 +0000 Subject: [PATCH 6/9] update algorithm/sv_algorithm_base.cpp. Signed-off-by: Daniel <1367240116@qq.com> --- algorithm/sv_algorithm_base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithm/sv_algorithm_base.cpp b/algorithm/sv_algorithm_base.cpp index 182bce3..f99142f 100644 --- a/algorithm/sv_algorithm_base.cpp +++ b/algorithm/sv_algorithm_base.cpp @@ -9,7 +9,7 @@ #include "ellipse_detector.h" #define SV_MODEL_DIR "/SpireCV/models/" -#define SV_ROOT_DIR "/SpireCV/params/a-params/" +#define SV_ROOT_DIR "/SpireCV/" namespace sv { From 5e0077bec00e85c63b1ce8263656ea8a4033ebac Mon Sep 17 00:00:00 2001 From: Daniel <1367240116@qq.com> Date: Wed, 5 Jul 2023 04:19:56 +0000 Subject: [PATCH 7/9] update video_io/sv_video_base.cpp. Signed-off-by: Daniel <1367240116@qq.com> --- video_io/sv_video_base.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/video_io/sv_video_base.cpp b/video_io/sv_video_base.cpp index d0bd037..573f744 100644 --- a/video_io/sv_video_base.cpp +++ b/video_io/sv_video_base.cpp @@ -1133,22 +1133,6 @@ void CameraBase::openImpl() // this->_cap.open(pipe); // cv::CAP_GSTREAMER this->_cap.open(pipe, cv::CAP_GSTREAMER); } - else if (this->_type == CameraType::MIPI) - { - char pipe[512]; - this->_cap.open(this->_camera_id); - if (this->_width <= 0 || this->_height <= 0) - { - this->_width = 1280; - this->_height = 720; - } - if (this->_fps <= 0) - { - this->_fps = 30; - } - sprintf(pipe, "nvarguscamerasrc framerate=(fraction)%d/1 ! nvvidconv flip-method=0 ! video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink", this->_fps, this->_width, this->_height); - this->_cap.open(pipe, cv::CAP_GSTREAMER); - } } void CameraBase::open(CameraType type, int id) { From e1a8bb62bf38375aad194f3b067493584bb10dd3 Mon Sep 17 00:00:00 2001 From: Daniel <1367240116@qq.com> Date: Wed, 5 Jul 2023 04:21:02 +0000 Subject: [PATCH 8/9] update samples/demo/aruco_detection.cpp. Signed-off-by: Daniel <1367240116@qq.com> --- samples/demo/aruco_detection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/demo/aruco_detection.cpp b/samples/demo/aruco_detection.cpp index b8520ba..0229400 100644 --- a/samples/demo/aruco_detection.cpp +++ b/samples/demo/aruco_detection.cpp @@ -9,7 +9,7 @@ int main(int argc, char *argv[]) { // 实例化Aruco检测器类 sv::ArucoDetector ad; // 手动导入相机参数,如果使用Amov的G1等吊舱或相机,则可以忽略该步骤,将自动下载相机参数文件 - ad.loadCameraParams(sv::get_home() + "/SpireCV/params/c-params/calib_webcam_640x480.yaml"); + ad.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml"); // 打开摄像头 sv::Camera cap; From 46b6808542f389a8ff3a49e44779ecdeb276ad89 Mon Sep 17 00:00:00 2001 From: Daniel <1367240116@qq.com> Date: Wed, 5 Jul 2023 04:21:36 +0000 Subject: [PATCH 9/9] update samples/demo/color_line_detect.cpp. Signed-off-by: Daniel <1367240116@qq.com> --- samples/demo/color_line_detect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/demo/color_line_detect.cpp b/samples/demo/color_line_detect.cpp index 2679518..cd3fa0c 100644 --- a/samples/demo/color_line_detect.cpp +++ b/samples/demo/color_line_detect.cpp @@ -11,7 +11,7 @@ int main(int argc, char *argv[]) // 实例化 color line detection 检测器类 sv::ColorLineDetector cld; // 手动导入相机参数,如果使用Amov的G1等吊舱或相机,则可以忽略该步骤,将自动下载相机参数文件 - cld.loadCameraParams(sv::get_home() + "/SpireCV/params/c-params/calib_webcam_640x480.yaml"); + cld.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml"); // 打开摄像头 sv::Camera cap;