diff --git a/armor/src/armor_finder/anti_top/anti_top.cpp b/armor/src/armor_finder/anti_top/anti_top.cpp index ea12515..6e622d2 100644 --- a/armor/src/armor_finder/anti_top/anti_top.cpp +++ b/armor/src/armor_finder/anti_top/anti_top.cpp @@ -13,7 +13,7 @@ static double boxDistance(const cv::Rect2d &a, const cv::Rect2d &b) { return sqrt(dist.x * dist.x + dist.y * dist.y); } -template +template static double mean(RoundQueue &vec) { double sum = 0; for (int i = 0; i < vec.size(); i++) { @@ -33,13 +33,14 @@ ArmorFinder::BoxRatioChangeType ArmorFinder::getRatioChangeType(RoundQueue 700) { anti_top_cnt = 0; if (anti_top_state == ANTI_TOP) { @@ -76,4 +77,42 @@ void ArmorFinder::antiTop() { sendBoxPosition(shoot_delay); } } +*/ + +void ArmorFinder::antiTop() { + if (target_box.rect == cv::Rect2d()) return; + uint16_t shoot_delay = 0; + auto interval = getTimeIntervalms(frame_time, last_front_time); + if (anti_top_state == ANTI_TOP && interval > 500) { + anti_top_state = NORMAL; + LOGM(STR_CTR(WORD_YELLOW, "switch to normal")); + } + if (last_box.rect != cv::Rect2d() && + getPointLength(last_box.getCenter() - target_box.getCenter()) > last_box.rect.height * 1.0) { + LOGM("switch! %lf", getPointLength(last_box.getCenter() - target_box.getCenter()) / last_box.rect.height); + if (150 < interval && interval < 500) { + if (anti_top_state == ANTI_TOP) { + top_periodms.push(interval); + LOGM(STR_CTR(WORD_LIGHT_GREEN, "top period: %.1lf ms"), interval); + systime curr_time; + getsystime(curr_time); + auto calculate_time = getTimeIntervalms(curr_time, frame_time); + shoot_delay = mean(top_periodms) - calculate_time; + sendBoxPosition(shoot_delay); + } else { + if (++anti_top_cnt > 4) { + anti_top_state = ANTI_TOP; + LOGM(STR_CTR(WORD_CYAN, "switch to anti-top")); + } + } + } + last_front_time = frame_time; + } + if (anti_top_state == NORMAL) { + sendBoxPosition(0); + } else if (interval < top_periodms[-1] * 0.10) { + sendBoxPosition(0); + } + last_box = target_box; +} diff --git a/armor/src/armor_finder/classifier/classifier.cpp b/armor/src/armor_finder/classifier/classifier.cpp index 2c78d89..dcf8059 100644 --- a/armor/src/armor_finder/classifier/classifier.cpp +++ b/armor/src/armor_finder/classifier/classifier.cpp @@ -324,9 +324,9 @@ int Classifier::operator()(const cv::Mat &image) { // cout << result << "==============" < 0.90){ + if(result(minRow, minCol) > 0.50){ return minRow; }else{ return 0; } -} \ No newline at end of file +} diff --git a/energy/src/energy/calibrate/structing.cpp b/energy/src/energy/calibrate/structing.cpp index 96facbb..dc8338d 100644 --- a/energy/src/energy/calibrate/structing.cpp +++ b/energy/src/energy/calibrate/structing.cpp @@ -53,9 +53,9 @@ void Energy::ArmorStruct(cv::Mat &src) { // imshow("dilate_1", src); erode(src,src, element_erode_1); // imshow("erode_1", src); - erode(src,src, element_erode_2); +// erode(src,src, element_erode_2); // imshow("erode_2", src); - erode(src,src, element_erode_3); +// erode(src,src, element_erode_3); // imshow("erode_3", src); // dilate(src, src, element_dilate_2); diff --git a/energy/src/energy/find/energy_finder.cpp b/energy/src/energy/find/energy_finder.cpp index c81a34f..537baab 100644 --- a/energy/src/energy/find/energy_finder.cpp +++ b/energy/src/energy/find/energy_finder.cpp @@ -1,426 +1,426 @@ -// -// Created by xixiliadorabarry on 1/24/19. -// -#include "energy/energy.h" -#include "log.h" - -using namespace cv; -using std::cout; -using std::endl; -using std::vector; - - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数用于寻找图像内所有的大风车扇叶 -// --------------------------------------------------------------------------------------------------------------------- -int Energy::findFans(const cv::Mat src) { - if (src.empty()) { - if (show_info) cout << "empty!" << endl; - return 0; - } - static Mat src_bin; - src_bin = src.clone(); - if (src.type() == CV_8UC3) { - cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道 - } - std::vector > fan_contours; - FanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 - if (show_process)imshow("fan struct", src_bin); - findContours(src_bin, fan_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); - - for (auto &fan_contour : fan_contours) { - if (!isValidFanContour(src_bin, fan_contour)) { - continue; - } - fans.emplace_back(cv::minAreaRect(fan_contour)); - -// RotatedRect cur_rect = minAreaRect(fan_contour); -// Size2f cur_size = cur_rect.size; -// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; -// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; -// double cur_contour_area = contourArea(fan_contour); -// double non_zero_rate = nonZeroRateOfRotateRect(src_bin, cur_rect); -// if (length > 60 && width > 20) { -// fans.emplace_back(cv::minAreaRect(fan_contour)); -// cout << cur_rect.center << endl; -// cout << "fan area: " << length << '\t' << width << endl; -// cout << "non zero: " << nonZeroRateOfRotateRect(src_bin, cur_rect) << endl; -// cout << "rate: " << cur_contour_area / cur_size.area() << endl; -// } - } -// showFans("fan", src_bin); - if (fans.size() < last_fans_cnt) { - last_fans_cnt = static_cast(fans.size()); - return -1;//寻找到的扇叶比上一帧少,说明该帧有误,返回-1 - } - last_fans_cnt = static_cast(fans.size()); - return static_cast(fans.size()); -} - - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数用于寻找图像内所有的大风车装甲板模块 -// --------------------------------------------------------------------------------------------------------------------- -int Energy::findArmors(const cv::Mat src) { - if (src.empty()) { - if (show_info) cout << "empty!" << endl; - return 0; - } - static Mat src_bin; - src_bin = src.clone(); - if (src.type() == CV_8UC3) { - cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道 - } - std::vector > armor_contours; - std::vector > armor_contours_external;//用总轮廓减去外轮廓,只保留内轮廓,除去流动条的影响。 - - ArmorStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 - findContours(src_bin, armor_contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE); - if (show_process)imshow("armor struct", src_bin); - - findContours(src_bin, armor_contours_external, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); - for (int i = 0; i < armor_contours_external.size(); i++)//去除外轮廓 - { - unsigned long external_contour_size = armor_contours_external[i].size(); - for (int j = 0; j < armor_contours.size(); j++) { - unsigned long all_size = armor_contours[j].size(); - if (external_contour_size == all_size) { - swap(armor_contours[j], armor_contours[armor_contours.size() - 1]); - armor_contours.pop_back(); - break; - } - } - } - - for (auto &armor_contour : armor_contours) { - if (!isValidArmorContour(armor_contour)) { - continue; - } - armors.emplace_back(cv::minAreaRect(armor_contour)); - -// RotatedRect cur_rect = minAreaRect(armor_contour); -// Size2f cur_size = cur_rect.size; -// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; -// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; -// double cur_contour_area = contourArea(armor_contour); -// float length_width_ratio = length / width; -// cout << "area: " << cur_contour_area << '\t' << endl; -// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl; -// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl; -// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl; -// cout<(armors.size()); -} - - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数用于寻找图像内大风车中心字母“R” -// --------------------------------------------------------------------------------------------------------------------- -bool Energy::findCenterR(const cv::Mat src) { - if (src.empty()) { - if (show_info) cout << "empty!" << endl; - return false; - } - static Mat src_bin; - src_bin = src.clone(); - if (src.type() == CV_8UC3) { - cvtColor(src_bin, src_bin, CV_BGR2GRAY); - } - std::vector > center_R_contours; - CenterRStruct(src_bin); - if (show_process)imshow("R struct", src_bin); - findContours(src_bin, center_R_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); - for (auto ¢er_R_contour : center_R_contours) { - if (!isValidCenterRContour(center_R_contour)) { - continue; - } - centerR = cv::minAreaRect(center_R_contour); - float target_length = - target_armor.size.height > target_armor.size.width ? target_armor.size.height : target_armor.size.width; - circle_center_point = centerR.center; - circle_center_point.y += target_length / 7.5;//实际最小二乘得到的中心在R的下方 - -// RotatedRect cur_rect = minAreaRect(center_R_contour); -// Size2f cur_size = cur_rect.size; -// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; -// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; -// double cur_contour_area = contourArea(center_R_contour); -// float length_width_ratio = length / width; -// cout << "area: " << cur_contour_area << '\t' << endl; -// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl; -// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl; -// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl; -// cout< > flow_strip_fan_contours; - FlowStripFanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 - if (show_process)imshow("flow strip fan struct", src_bin); - - findContours(src_bin, flow_strip_fan_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); - std::vector candidate_flow_strip_fans; - - for (auto &flow_strip_fan_contour : flow_strip_fan_contours) { - if (!isValidFlowStripFanContour(src_bin, flow_strip_fan_contour)) { - continue; - } - flow_strip_fans.emplace_back(cv::minAreaRect(flow_strip_fan_contour)); - -// RotatedRect cur_rect = minAreaRect(flow_strip_fan_contour); -// Size2f cur_size = cur_rect.size; -// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; -// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; -// double cur_contour_area = contourArea(flow_strip_fan_contour); -// float length_width_ratio = length / width; -// cout << "area: " << cur_contour_area << '\t' << endl; -// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl; -// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl; -// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl; -// cout< candidate_target_armors = target_armors; - for (auto &candidate_target_armor: candidate_target_armors) { - Point2f vertices[4]; - candidate_target_armor.size.height *= 1.3; - candidate_target_armor.size.width *= 1.3; - candidate_target_armor.points(vertices); //计算矩形的4个顶点 - for (int i = 0; i < 4; i++) { - line(src_bin, vertices[i], vertices[(i + 1) % 4], Scalar(0, 0, 0), 20); - } - } - - cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道 - - FlowStripStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 - if (show_process)imshow("flow strip struct", src_bin); - - std::vector > flow_strip_contours; - findContours(src_bin, flow_strip_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); - - for (auto candidate_flow_strip_fan: flow_strip_fans) { - for (auto &flow_strip_contour : flow_strip_contours) { - if (!isValidFlowStripContour(flow_strip_contour)) { - continue; - } - - std::vector intersection; - RotatedRect cur_rect = minAreaRect(flow_strip_contour); - - if (rotatedRectangleIntersection(cur_rect, candidate_flow_strip_fan, intersection) == 0) { - continue; - } else if (contourArea(intersection) > energy_part_param_.FLOW_STRIP_CONTOUR_INTERSETION_AREA_MIN) { - flow_strips.emplace_back(cv::minAreaRect(flow_strip_contour)); -// cout << "intersection: " << contourArea(intersection) << '\t' << cur_rect.center << endl; - } else { - continue; - } - -// Size2f cur_size = cur_rect.size; -// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; -// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; -// double cur_contour_area = contourArea(flow_strip_contour); -// float length_width_ratio = length / width; -// cout << "area: " << cur_contour_area << '\t' << endl; -// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl; -// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl; -// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl; -// cout< 1) { - if (show_info)cout << "Too many flow strips!" << endl; -// waitKey(0); - return false; - } else { - flow_strip = flow_strips.at(0); - for (auto &candidate_flow_strip_fan: flow_strip_fans) { - std::vector intersection; - if (rotatedRectangleIntersection(flow_strip, candidate_flow_strip_fan, intersection) == 0) { - continue; - } else if (contourArea(intersection) > energy_part_param_.FLOW_STRIP_CONTOUR_INTERSETION_AREA_MIN) { - flow_strip_fan = candidate_flow_strip_fan; - } - } - int i = 0; - for (i = 0; i < target_armors.size(); ++i) { - std::vector intersection; - if (rotatedRectangleIntersection(target_armors.at(i), flow_strip_fan, intersection) == 0) - continue;//返回0表示没有重合面积 - double cur_contour_area = contourArea(intersection); - if (cur_contour_area > energy_part_param_.TARGET_INTERSETION_CONTOUR_AREA_MIN) { - target_armor = target_armors.at(i); - target_point = target_armor.center; - } - } - } - return true; -} - - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数用于弱识别寻找流动条 -// --------------------------------------------------------------------------------------------------------------------- -bool Energy::findFlowStripWeak(const cv::Mat src) { - if (src.empty()) { - if (show_info) cout << "empty!" << endl; - return false; - } - cv::Mat src_bin; - src_bin = src.clone(); - - if (src_bin.type() == CV_8UC1) // 黑白图像 - { - cvtColor(src_bin, src_bin, COLOR_GRAY2RGB); - - } - std::vector candidate_armors = armors; - for (auto &candidate_armor: candidate_armors) { - Point2f vertices[4]; - candidate_armor.size.height *= 1.3; - candidate_armor.size.width *= 1.3; - candidate_armor.points(vertices); //计算矩形的4个顶点 - for (int i = 0; i < 4; i++) { - line(src_bin, vertices[i], vertices[(i + 1) % 4], Scalar(0, 0, 0), 20); - } - } - - cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道 - - FlowStripStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 - if (show_process)imshow("weak struct", src_bin); -// waitKey(0); - - std::vector > flow_strip_contours; - findContours(src_bin, flow_strip_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); - - for (auto &flow_strip_contour : flow_strip_contours) { - if (!isValidFlowStripContour(flow_strip_contour)) { - continue; - } - - flow_strips.emplace_back(cv::minAreaRect(flow_strip_contour)); - -// RotatedRect cur_rect = minAreaRect(flow_strip_contour); -// Size2f cur_size = cur_rect.size; -// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; -// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; -// double cur_contour_area = contourArea(flow_strip_contour); -// float length_width_ratio = length / width; -// cout << "area: " << cur_contour_area << '\t' << endl; -// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl; -// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl; -// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl; -// cout << endl; - - } -// cout << "size: " << flow_strips.size() << endl; - - if (flow_strips.empty()) { - if (show_info)cout << "weak flow strip false!" << endl; -// waitKey(0); - return false; - } else { - for (const auto &candidate_flow_strip: flow_strips) { - for (const auto &candidate_armor: armors) { - if (pointDistance(candidate_flow_strip.center, candidate_armor.center) < - energy_part_param_.STRIP_ARMOR_DISTANCE_MIN || - pointDistance(candidate_flow_strip.center, candidate_armor.center) > - energy_part_param_.STRIP_ARMOR_DISTANCE_MAX) { - continue; - } - float angle_armor = candidate_armor.size.width > candidate_armor.size.height ? candidate_armor.angle : - candidate_armor.angle - 90; - float angle_strip = candidate_flow_strip.size.width > candidate_flow_strip.size.height ? - candidate_flow_strip.angle: candidate_flow_strip.angle - 90; - - if (abs(angle_armor - angle_strip) < 60 || abs(angle_armor - angle_strip) > 120) { - continue; - } - target_armor = candidate_armor; - target_point = candidate_armor.center; - flow_strip = candidate_flow_strip; - return true; - } - } - if (show_info)cout << "weak flow strip false!" << endl; -// waitKey(0); - return false; - } -} - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数用于框取中心R的寻找范围 -// --------------------------------------------------------------------------------------------------------------------- -bool Energy::findCenterROI(const cv::Mat src) { - float length = target_armor.size.height > target_armor.size.width ? - target_armor.size.height : target_armor.size.width; - - Point2f p2p(flow_strip.center.x - target_point.x, - flow_strip.center.y - target_point.y); - p2p = p2p / pointDistance(flow_strip.center, target_point);//单位化 - center_ROI = cv::RotatedRect(cv::Point2f(flow_strip.center + p2p * length * 1.7), - Size2f(length * 1.4, length * 1.4), -90); - return true; - -} - - +// +// Created by xixiliadorabarry on 1/24/19. +// +#include "energy/energy.h" +#include "log.h" + +using namespace cv; +using std::cout; +using std::endl; +using std::vector; + + +//---------------------------------------------------------------------------------------------------------------------- +// 此函数用于寻找图像内所有的大风车扇叶 +// --------------------------------------------------------------------------------------------------------------------- +int Energy::findFans(const cv::Mat src) { + if (src.empty()) { + if (show_info) cout << "empty!" << endl; + return 0; + } + static Mat src_bin; + src_bin = src.clone(); + if (src.type() == CV_8UC3) { + cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道 + } + std::vector > fan_contours; + FanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 + if (show_process)imshow("fan struct", src_bin); + findContours(src_bin, fan_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); + + for (auto &fan_contour : fan_contours) { + if (!isValidFanContour(src_bin, fan_contour)) { + continue; + } + fans.emplace_back(cv::minAreaRect(fan_contour)); + +// RotatedRect cur_rect = minAreaRect(fan_contour); +// Size2f cur_size = cur_rect.size; +// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; +// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; +// double cur_contour_area = contourArea(fan_contour); +// double non_zero_rate = nonZeroRateOfRotateRect(src_bin, cur_rect); +// if (length > 60 && width > 20) { +// fans.emplace_back(cv::minAreaRect(fan_contour)); +// cout << cur_rect.center << endl; +// cout << "fan area: " << length << '\t' << width << endl; +// cout << "non zero: " << nonZeroRateOfRotateRect(src_bin, cur_rect) << endl; +// cout << "rate: " << cur_contour_area / cur_size.area() << endl; +// } + } +// showFans("fan", src_bin); + if (fans.size() < last_fans_cnt) { + last_fans_cnt = static_cast(fans.size()); + return -1;//寻找到的扇叶比上一帧少,说明该帧有误,返回-1 + } + last_fans_cnt = static_cast(fans.size()); + return static_cast(fans.size()); +} + + +//---------------------------------------------------------------------------------------------------------------------- +// 此函数用于寻找图像内所有的大风车装甲板模块 +// --------------------------------------------------------------------------------------------------------------------- +int Energy::findArmors(const cv::Mat src) { + if (src.empty()) { + if (show_info) cout << "empty!" << endl; + return 0; + } + static Mat src_bin; + src_bin = src.clone(); + if (src.type() == CV_8UC3) { + cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道 + } + std::vector > armor_contours; + std::vector > armor_contours_external;//用总轮廓减去外轮廓,只保留内轮廓,除去流动条的影响。 + + ArmorStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 + findContours(src_bin, armor_contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE); + if (show_process)imshow("armor struct", src_bin); + + findContours(src_bin, armor_contours_external, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); + for (int i = 0; i < armor_contours_external.size(); i++)//去除外轮廓 + { + unsigned long external_contour_size = armor_contours_external[i].size(); + for (int j = 0; j < armor_contours.size(); j++) { + unsigned long all_size = armor_contours[j].size(); + if (external_contour_size == all_size) { + swap(armor_contours[j], armor_contours[armor_contours.size() - 1]); + armor_contours.pop_back(); + break; + } + } + } + + for (auto &armor_contour : armor_contours) { + if (!isValidArmorContour(armor_contour)) { + continue; + } + armors.emplace_back(cv::minAreaRect(armor_contour)); + +// RotatedRect cur_rect = minAreaRect(armor_contour); +// Size2f cur_size = cur_rect.size; +// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; +// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; +// double cur_contour_area = contourArea(armor_contour); +// float length_width_ratio = length / width; +// cout << "area: " << cur_contour_area << '\t' << endl; +// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl; +// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl; +// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl; +// cout<(armors.size()); +} + + +//---------------------------------------------------------------------------------------------------------------------- +// 此函数用于寻找图像内大风车中心字母“R” +// --------------------------------------------------------------------------------------------------------------------- +bool Energy::findCenterR(const cv::Mat src) { + if (src.empty()) { + if (show_info) cout << "empty!" << endl; + return false; + } + static Mat src_bin; + src_bin = src.clone(); + if (src.type() == CV_8UC3) { + cvtColor(src_bin, src_bin, CV_BGR2GRAY); + } + std::vector > center_R_contours; + CenterRStruct(src_bin); + if (show_process)imshow("R struct", src_bin); + findContours(src_bin, center_R_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); + for (auto ¢er_R_contour : center_R_contours) { + if (!isValidCenterRContour(center_R_contour)) { + continue; + } + centerR = cv::minAreaRect(center_R_contour); + float target_length = + target_armor.size.height > target_armor.size.width ? target_armor.size.height : target_armor.size.width; + circle_center_point = centerR.center; + circle_center_point.y += target_length / 7.5;//实际最小二乘得到的中心在R的下方 + +// RotatedRect cur_rect = minAreaRect(center_R_contour); +// Size2f cur_size = cur_rect.size; +// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; +// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; +// double cur_contour_area = contourArea(center_R_contour); +// float length_width_ratio = length / width; +// cout << "area: " << cur_contour_area << '\t' << endl; +// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl; +// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl; +// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl; +// cout< > flow_strip_fan_contours; + FlowStripFanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 + if (show_process)imshow("flow strip fan struct", src_bin); + + findContours(src_bin, flow_strip_fan_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); + std::vector candidate_flow_strip_fans; + + for (auto &flow_strip_fan_contour : flow_strip_fan_contours) { + if (!isValidFlowStripFanContour(src_bin, flow_strip_fan_contour)) { + continue; + } + flow_strip_fans.emplace_back(cv::minAreaRect(flow_strip_fan_contour)); + +// RotatedRect cur_rect = minAreaRect(flow_strip_fan_contour); +// Size2f cur_size = cur_rect.size; +// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; +// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; +// double cur_contour_area = contourArea(flow_strip_fan_contour); +// float length_width_ratio = length / width; +// cout << "area: " << cur_contour_area << '\t' << endl; +// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl; +// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl; +// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl; +// cout< candidate_target_armors = target_armors; + for (auto &candidate_target_armor: candidate_target_armors) { + Point2f vertices[4]; + candidate_target_armor.size.height *= 1.3; + candidate_target_armor.size.width *= 1.3; + candidate_target_armor.points(vertices); //计算矩形的4个顶点 + for (int i = 0; i < 4; i++) { + line(src_bin, vertices[i], vertices[(i + 1) % 4], Scalar(0, 0, 0), 20); + } + } + + cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道 + + FlowStripStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 + if (show_process)imshow("flow strip struct", src_bin); + + std::vector > flow_strip_contours; + findContours(src_bin, flow_strip_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); + + for (auto candidate_flow_strip_fan: flow_strip_fans) { + for (auto &flow_strip_contour : flow_strip_contours) { + if (!isValidFlowStripContour(flow_strip_contour)) { + continue; + } + + std::vector intersection; + RotatedRect cur_rect = minAreaRect(flow_strip_contour); + + if (rotatedRectangleIntersection(cur_rect, candidate_flow_strip_fan, intersection) == 0) { + continue; + } else if (contourArea(intersection) > energy_part_param_.FLOW_STRIP_CONTOUR_INTERSETION_AREA_MIN) { + flow_strips.emplace_back(cv::minAreaRect(flow_strip_contour)); +// cout << "intersection: " << contourArea(intersection) << '\t' << cur_rect.center << endl; + } else { + continue; + } + +// Size2f cur_size = cur_rect.size; +// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; +// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; +// double cur_contour_area = contourArea(flow_strip_contour); +// float length_width_ratio = length / width; +// cout << "area: " << cur_contour_area << '\t' << endl; +// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl; +// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl; +// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl; +// cout< 1) { + if (show_info)cout << "Too many flow strips!" << endl; +// waitKey(0); + return false; + } else { + flow_strip = flow_strips.at(0); + for (auto &candidate_flow_strip_fan: flow_strip_fans) { + std::vector intersection; + if (rotatedRectangleIntersection(flow_strip, candidate_flow_strip_fan, intersection) == 0) { + continue; + } else if (contourArea(intersection) > energy_part_param_.FLOW_STRIP_CONTOUR_INTERSETION_AREA_MIN) { + flow_strip_fan = candidate_flow_strip_fan; + } + } + int i = 0; + for (i = 0; i < target_armors.size(); ++i) { + std::vector intersection; + if (rotatedRectangleIntersection(target_armors.at(i), flow_strip_fan, intersection) == 0) + continue;//返回0表示没有重合面积 + double cur_contour_area = contourArea(intersection); + if (cur_contour_area > energy_part_param_.TARGET_INTERSETION_CONTOUR_AREA_MIN) { + target_armor = target_armors.at(i); + target_point = target_armor.center; + } + } + } + return true; +} + + +//---------------------------------------------------------------------------------------------------------------------- +// 此函数用于弱识别寻找流动条 +// --------------------------------------------------------------------------------------------------------------------- +bool Energy::findFlowStripWeak(const cv::Mat src) { + if (src.empty()) { + if (show_info) cout << "empty!" << endl; + return false; + } + cv::Mat src_bin; + src_bin = src.clone(); + + if (src_bin.type() == CV_8UC1) // 黑白图像 + { + cvtColor(src_bin, src_bin, COLOR_GRAY2RGB); + + } + std::vector candidate_armors = armors; + for (auto &candidate_armor: candidate_armors) { + Point2f vertices[4]; + candidate_armor.size.height *= 1.3; + candidate_armor.size.width *= 1.3; + candidate_armor.points(vertices); //计算矩形的4个顶点 + for (int i = 0; i < 4; i++) { + line(src_bin, vertices[i], vertices[(i + 1) % 4], Scalar(0, 0, 0), 20); + } + } + + cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道 + + FlowStripStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 + if (show_process)imshow("weak struct", src_bin); +// waitKey(0); + + std::vector > flow_strip_contours; + findContours(src_bin, flow_strip_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); + + for (auto &flow_strip_contour : flow_strip_contours) { + if (!isValidFlowStripContour(flow_strip_contour)) { + continue; + } + + flow_strips.emplace_back(cv::minAreaRect(flow_strip_contour)); + +// RotatedRect cur_rect = minAreaRect(flow_strip_contour); +// Size2f cur_size = cur_rect.size; +// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width; +// float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width; +// double cur_contour_area = contourArea(flow_strip_contour); +// float length_width_ratio = length / width; +// cout << "area: " << cur_contour_area << '\t' << endl; +// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl; +// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl; +// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl; +// cout << endl; + + } +// cout << "size: " << flow_strips.size() << endl; + + if (flow_strips.empty()) { + if (show_info)cout << "weak flow strip false!" << endl; +// waitKey(0); + return false; + } else { + for (const auto &candidate_flow_strip: flow_strips) { + for (const auto &candidate_armor: armors) { + if (pointDistance(candidate_flow_strip.center, candidate_armor.center) < + energy_part_param_.STRIP_ARMOR_DISTANCE_MIN || + pointDistance(candidate_flow_strip.center, candidate_armor.center) > + energy_part_param_.STRIP_ARMOR_DISTANCE_MAX) { + continue; + } + float angle_armor = candidate_armor.size.width > candidate_armor.size.height ? candidate_armor.angle : + candidate_armor.angle - 90; + float angle_strip = candidate_flow_strip.size.width > candidate_flow_strip.size.height ? + candidate_flow_strip.angle: candidate_flow_strip.angle - 90; + + if (abs(angle_armor - angle_strip) < 60 || abs(angle_armor - angle_strip) > 120) { + continue; + } + target_armor = candidate_armor; + target_point = candidate_armor.center; + flow_strip = candidate_flow_strip; + return true; + } + } + if (show_info)cout << "weak flow strip false!" << endl; +// waitKey(0); + return false; + } +} + +//---------------------------------------------------------------------------------------------------------------------- +// 此函数用于框取中心R的寻找范围 +// --------------------------------------------------------------------------------------------------------------------- +bool Energy::findCenterROI(const cv::Mat src) { + float length = target_armor.size.height > target_armor.size.width ? + target_armor.size.height : target_armor.size.width; + + Point2f p2p(flow_strip.center.x - target_point.x, + flow_strip.center.y - target_point.y); + p2p = p2p / pointDistance(flow_strip.center, target_point);//单位化 + center_ROI = cv::RotatedRect(cv::Point2f(flow_strip.center + p2p * length * 1.7), + Size2f(length * 1.4, length * 1.4), -90); + return true; + +} + + diff --git a/energy/src/energy/find/target_finder.cpp b/energy/src/energy/find/target_finder.cpp index 0dff96f..369ee94 100644 --- a/energy/src/energy/find/target_finder.cpp +++ b/energy/src/energy/find/target_finder.cpp @@ -1,79 +1,86 @@ -// -// Created by xixiliadorabarry on 1/24/19. -// - -#include "energy/energy.h" -#include "log.h" - -using namespace cv; -using std::cout; -using std::endl; -using std::vector; - - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数根据矩形重合面积匹配扇叶与装甲板 -// --------------------------------------------------------------------------------------------------------------------- -void Energy::findTargetByIntersection() { - if (fans.size() >= armors.size()) return;//扇叶多于装甲板,识别错误 - for (const auto &fan : fans) { - for (const auto &armor : armors) { - - } - } - /* if (fans.empty()) { - target_point = armors.at(0).rect.center; - return; - } - int i = 0, j = 0; - while (i < armors.size()) { - for (j = 0; j < fans.size(); ++j) { - std::vector intersection; - if (rotatedRectangleIntersection(armors.at(i).rect, fans.at(j).rect, intersection) == 0)//返回0表示没有重合面积 - continue; - else - rotatedRectangleIntersection(armors.at(i).rect, fans.at(j).rect, intersection); - double cur_contour_area = contourArea(intersection); - if (cur_contour_area > energy_part_param_.INTERSETION_CONTOUR_AREA_MIN) { - // cout << endl; - // cout << "NO. " << i << " armor and No. " << j << "fans are matched, the intersection area is" - // << cur_contour_area << endl; - break; - } - } - if (j == fans.size()) { - target_point = armors.at(i).rect.center; - break; - } - i++; - }*/ -} - - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数在流动条区域内寻找装甲板 -// --------------------------------------------------------------------------------------------------------------------- -bool Energy::findTargetInFlowStripFan() { - for (auto &candidate_flow_strip_fan: flow_strip_fans) { - int i = 0; - for (i = 0; i < armors.size(); ++i) { - std::vector intersection; - if (rotatedRectangleIntersection(armors.at(i), candidate_flow_strip_fan, intersection) == 0) - continue;//返回0表示没有重合面积 - double cur_contour_area = contourArea(intersection); -// cout< energy_part_param_.TARGET_INTERSETION_CONTOUR_AREA_MIN) { - target_armors.emplace_back(armors.at(i)); - } - } - } -// cout << "target armor cnt: " << target_armors.size() << endl; - if (target_armors.empty()) { - if (show_info)cout << "find target armor false" << endl; - return false; - } else { - return true; - } - - +// +// Created by xixiliadorabarry on 1/24/19. +// + +#include "energy/energy.h" +#include "log.h" + +using namespace cv; +using std::cout; +using std::endl; +using std::vector; + + +//---------------------------------------------------------------------------------------------------------------------- +// 此函数根据矩形重合面积匹配扇叶与装甲板 +// --------------------------------------------------------------------------------------------------------------------- +void Energy::findTargetByIntersection() { + if (fans.size() >= armors.size()) return;//扇叶多于装甲板,识别错误 + for (const auto &fan : fans) { + for (const auto &armor : armors) { + + } + } + /* if (fans.empty()) { + target_point = armors.at(0).rect.center; + return; + } + int i = 0, j = 0; + while (i < armors.size()) { + for (j = 0; j < fans.size(); ++j) { + std::vector intersection; + if (rotatedRectangleIntersection(armors.at(i).rect, fans.at(j).rect, intersection) == 0)//返回0表示没有重合面积 + continue; + else + rotatedRectangleIntersection(armors.at(i).rect, fans.at(j).rect, intersection); + double cur_contour_area = contourArea(intersection); + if (cur_contour_area > energy_part_param_.INTERSETION_CONTOUR_AREA_MIN) { + // cout << endl; + // cout << "NO. " << i << " armor and No. " << j << "fans are matched, the intersection area is" + // << cur_contour_area << endl; + break; + } + } + if (j == fans.size()) { + target_point = armors.at(i).rect.center; + break; + } + i++; + }*/ +} + + +//---------------------------------------------------------------------------------------------------------------------- +// 此函数在流动条区域内寻找装甲板 +// --------------------------------------------------------------------------------------------------------------------- +bool Energy::findTargetInFlowStripFan() { +// Mat draw(480,640,CV_8UC3,Scalar(0,0,0)); + for (auto &candidate_flow_strip_fan: flow_strip_fans) { +// Point2f vertices[4]; //定义矩形的4个顶点 +// candidate_flow_strip_fan.points(vertices); //计算矩形的4个顶点 +// for (int i = 0; i < 4; i++) +// line(draw, vertices[i], vertices[(i + 1) % 4], Scalar(0, 0, 255), 2); + int i = 0; + for (i = 0; i < armors.size(); ++i) { + std::vector intersection; + if (rotatedRectangleIntersection(armors.at(i), candidate_flow_strip_fan, intersection) == 0) + continue;//返回0表示没有重合面积 + double cur_contour_area = contourArea(intersection); +// cout< energy_part_param_.TARGET_INTERSETION_CONTOUR_AREA_MIN) { + target_armors.emplace_back(armors.at(i)); + } + } + } +// imshow("draw",draw); +// waitKey(); +// cout << "target armor cnt: " << target_armors.size() << endl; + if (target_armors.empty()) { + if (show_info)cout << "t6find target armor false" << endl; + return false; + } else { + return true; + } + + } \ No newline at end of file