diff --git a/.gitignore b/.gitignore index 6584eba..e84f100 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ tools/TrainCNN/.idea tools/TrainCNN/__pycache__ others/include/config/config.h .DS_Store +gimble_video +chassis_video \ No newline at end of file diff --git a/energy/include/energy/energy.h b/energy/include/energy/energy.h index 56798a2..4b431ab 100644 --- a/energy/include/energy/energy.h +++ b/energy/include/energy/energy.h @@ -33,8 +33,6 @@ public: Serial &serial;//串口 void setEnergyInit();//设置能量机关初始化 - void setBigEnergyInit();//设置大符初始化,判断顺逆时针函数 - void setSmallEnergyInit();//设置小符初始化 void sendTarget(Serial &serial, float x, float y, float z); @@ -46,7 +44,7 @@ private: bool isMark;//若操作手正在手动标定,则为true bool isBig;//大符模式为true bool isSmall;//小符模式为true - bool isgimbal;//同时具有底盘和云台摄像头时,处于云台摄像头对心过程 + bool isGimbal;//同时具有底盘和云台摄像头时,处于云台摄像头对心过程 bool isChassis;//同时具有底盘和云台摄像头时,处于底盘摄像头击打过程 bool isGuessing;//当前处于发弹到新目标出现的过程,则为true,此时猜测下一个目标 bool isPredicting;//当前处于新目标出现到发弹的过程,则为true,此时正常击打 @@ -166,10 +164,11 @@ private: void imagePreprocess(cv::Mat &src);//图像通道分离 void hsvFilter(cv::Mat &src);//此函数通过HSV颜色空间对图像纯度进行限制,进行滤光 - void StructingElementClose(cv::Mat &src, int length, int width);//闭运算 - void StructingElementErodeDilate(cv::Mat &src);//腐蚀和膨胀 - void StructingElementDilateErode(cv::Mat &src);//腐蚀和膨胀 - + void FanStruct(cv::Mat &src);//腐蚀和膨胀 + void ArmorStruct(cv::Mat &src);//腐蚀和膨胀 + void FlowStripFanStruct(cv::Mat &src);//腐蚀和膨胀 + void FlowStripStruct(cv::Mat &src);//腐蚀和膨胀 + void CenterRStruct(cv::Mat &src);//腐蚀和膨胀 }; #endif //ENERGY_H diff --git a/energy/src/energy/calibrate/split.cpp b/energy/src/energy/calibrate/split.cpp index c9a9dda..90701a0 100644 --- a/energy/src/energy/calibrate/split.cpp +++ b/energy/src/energy/calibrate/split.cpp @@ -41,9 +41,11 @@ void Energy::imagePreprocess(cv::Mat &src) { splitBayerBG(src, src_blue, src_red); if(ally_color == ALLY_RED) { - src = src_red - src_blue; +// src = src_red - src_blue; + src = src_red; }else if(ally_color == ALLY_BLUE){ - src = src_blue - src_red; +// src = src_blue - src_red; + src = src_blue; } } @@ -65,6 +67,6 @@ void Energy::imagePreprocess(cv::Mat &src) { } } cv::resize(src, src, cv::Size(src.size().width * 2, src.size().height * 2), 2); -// threshold(src, src, energy_part_param_.SPLIT_GRAY_THRESH, 255, THRESH_BINARY); + threshold(src, src, energy_part_param_.SPLIT_GRAY_THRESH, 255, THRESH_BINARY); } diff --git a/energy/src/energy/calibrate/structing.cpp b/energy/src/energy/calibrate/structing.cpp index 845608c..dcf55dd 100644 --- a/energy/src/energy/calibrate/structing.cpp +++ b/energy/src/energy/calibrate/structing.cpp @@ -9,14 +9,33 @@ using std::endl; using std::vector; + + //---------------------------------------------------------------------------------------------------------------------- -// 此函数对图像进行闭运算操作 +// 此函数对图像进行腐蚀与膨胀操作 // --------------------------------------------------------------------------------------------------------------------- -void Energy::StructingElementClose(cv::Mat &src,int length, int width){ - if (src.empty())return; - //threshold(src, src, energy_part_param_.CAMERA_GRAY_THRESH, 255, THRESH_BINARY); - Mat element = getStructuringElement(MORPH_RECT, Size(length, width)); - morphologyEx(src, src, MORPH_CLOSE, element); +void Energy::FanStruct(cv::Mat &src) { + Mat element_dilate_1 = getStructuringElement(MORPH_RECT, Size(5, 5)); + Mat element_erode_1 = getStructuringElement(MORPH_RECT, Size(2, 2)); + Mat element_dilate_2 = getStructuringElement(MORPH_RECT, Size(3, 3)); + Mat element_erode_2 = getStructuringElement(MORPH_RECT, Size(2 , 2)); + Mat element_dilate_3 = getStructuringElement(MORPH_RECT, Size(3, 3)); + Mat element_erode_3 = getStructuringElement(MORPH_RECT, Size(1 , 1)); + + dilate(src, src, element_dilate_1); +// imshow("dilate_1", src); + erode(src,src, element_erode_1); +// imshow("erode_1", src); + erode(src,src, element_erode_2); +// imshow("erode_2", src); + erode(src,src, element_erode_3); +// imshow("erode_3", src); +// dilate(src, src, element_dilate_2); +// imshow("dilate_2", src); +// dilate(src, src, element_dilate_3); +// imshow("dilate_3", src); +// erode(src,src, element_erode_2); +// imshow("erode_2", src); } @@ -24,7 +43,7 @@ void Energy::StructingElementClose(cv::Mat &src,int length, int width){ //---------------------------------------------------------------------------------------------------------------------- // 此函数对图像进行腐蚀与膨胀操作 // --------------------------------------------------------------------------------------------------------------------- -void Energy::StructingElementErodeDilate(cv::Mat &src) { +void Energy::ArmorStruct(cv::Mat &src) { Mat element_dilate_1 = getStructuringElement(MORPH_RECT, Size(8, 6)); Mat element_erode_1 = getStructuringElement(MORPH_RECT, Size(2, 1)); Mat element_dilate_2 = getStructuringElement(MORPH_RECT, Size(3, 3)); @@ -41,21 +60,80 @@ void Energy::StructingElementErodeDilate(cv::Mat &src) { } + //---------------------------------------------------------------------------------------------------------------------- // 此函数对图像进行腐蚀与膨胀操作 // --------------------------------------------------------------------------------------------------------------------- -void Energy::StructingElementDilateErode(cv::Mat &src) { - Mat element_dilate_1 = getStructuringElement(MORPH_RECT, Size(3, 3)); - Mat element_erode_1 = getStructuringElement(MORPH_RECT, Size(2, 1)); - Mat element_dilate_2 = getStructuringElement(MORPH_RECT, Size(8, 6)); - Mat element_erode_2 = getStructuringElement(MORPH_RECT, Size(4 , 4)); +void Energy::FlowStripFanStruct(cv::Mat &src) { + Mat element_dilate_1 = getStructuringElement(MORPH_RECT, Size(5, 5)); + Mat element_erode_1 = getStructuringElement(MORPH_RECT, Size(2, 2)); + Mat element_dilate_2 = getStructuringElement(MORPH_RECT, Size(3, 3)); + Mat element_erode_2 = getStructuringElement(MORPH_RECT, Size(2 , 2)); + Mat element_dilate_3 = getStructuringElement(MORPH_RECT, Size(3, 3)); + Mat element_erode_3 = getStructuringElement(MORPH_RECT, Size(1 , 1)); - dilate(src, src, element_dilate_2); + dilate(src, src, element_dilate_1); // imshow("dilate_1", src); -// erode(src,src, element_erode_1); + 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); +// imshow("erode_3", src); // dilate(src, src, element_dilate_2); // imshow("dilate_2", src); +// dilate(src, src, element_dilate_3); +// imshow("dilate_3", src); +// erode(src,src, element_erode_2); +// imshow("erode_2", src); +} + + + +//---------------------------------------------------------------------------------------------------------------------- +// 此函数对图像进行腐蚀与膨胀操作 +// --------------------------------------------------------------------------------------------------------------------- +void Energy::FlowStripStruct(cv::Mat &src) { + Mat element_dilate_1 = getStructuringElement(MORPH_RECT, Size(5, 5)); + Mat element_erode_1 = getStructuringElement(MORPH_RECT, Size(3, 3)); + Mat element_dilate_2 = getStructuringElement(MORPH_RECT, Size(3, 3)); + Mat element_erode_2 = getStructuringElement(MORPH_RECT, Size(2 , 2)); + Mat element_dilate_3 = getStructuringElement(MORPH_RECT, Size(3, 3)); + Mat element_erode_3 = getStructuringElement(MORPH_RECT, Size(1 , 1)); + + dilate(src, src, element_dilate_1); +// imshow("dilate_1", src); + erode(src,src, element_erode_1); +// imshow("erode_1", src); + erode(src,src, element_erode_2); +// imshow("erode_2", src); + erode(src,src, element_erode_3); +// imshow("erode_3", src); +// dilate(src, src, element_dilate_2); +// imshow("dilate_2", src); +// dilate(src, src, element_dilate_3); +// imshow("dilate_3", src); +// erode(src,src, element_erode_2); +// imshow("erode_2", src); +} + + + +//---------------------------------------------------------------------------------------------------------------------- +// 此函数对图像进行腐蚀与膨胀操作 +// --------------------------------------------------------------------------------------------------------------------- +void Energy::CenterRStruct(cv::Mat &src) { + Mat element_dilate_1 = getStructuringElement(MORPH_RECT, Size(8, 6)); + Mat element_erode_1 = getStructuringElement(MORPH_RECT, Size(2, 1)); + Mat element_dilate_2 = getStructuringElement(MORPH_RECT, Size(3, 3)); + Mat element_erode_2 = getStructuringElement(MORPH_RECT, Size(4 , 4)); + + erode(src,src, element_erode_1); +// imshow("erode_1", src); + dilate(src, src, element_dilate_1); +// imshow("dilate_1", src); + dilate(src, src, element_dilate_2); +// imshow("dilate_2", src); + erode(src,src, element_erode_2); +// imshow("erode_2", src); } \ No newline at end of file diff --git a/energy/src/energy/change/mode_change.cpp b/energy/src/energy/change/mode_change.cpp index a9430b4..61bc571 100644 --- a/energy/src/energy/change/mode_change.cpp +++ b/energy/src/energy/change/mode_change.cpp @@ -14,7 +14,7 @@ using namespace cv; // --------------------------------------------------------------------------------------------------------------------- void Energy::startChassis(){ isChassis = true; - isgimbal = false; + isGimbal = false; } diff --git a/energy/src/energy/energy.cpp b/energy/src/energy/energy.cpp index 0c3702c..2391d98 100644 --- a/energy/src/energy/energy.cpp +++ b/energy/src/energy/energy.cpp @@ -22,7 +22,7 @@ Energy::Energy(Serial &u, uint8_t &color) : serial(u), ally_color(color), energy_rotation_init = false; isBig = false; isSmall = false; - isgimbal = true; + isGimbal = true; isChassis = false; } @@ -44,35 +44,6 @@ void Energy::setEnergyInit() { energy_rotation_init = true; isBig = false; isSmall = false; - isgimbal = true; + isGimbal = true; isChassis = false; -} - - - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数为大能量机关再初始化函数 -// --------------------------------------------------------------------------------------------------------------------- -void Energy::setBigEnergyInit() { - initEnergy(); - initEnergyPartParam(); - - energy_rotation_init = true; - isBig = true; - isSmall = false; - isgimbal = true; - isChassis = false; -} - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数为小能量机关再初始化函数 -// --------------------------------------------------------------------------------------------------------------------- -void Energy::setSmallEnergyInit() { - initEnergy(); - initEnergyPartParam(); - - isBig = false; - isSmall = true; - isgimbal = true; - isChassis = false; -} +} \ No newline at end of file diff --git a/energy/src/energy/find/energy_finder.cpp b/energy/src/energy/find/energy_finder.cpp index d96039c..f2d4ae1 100644 --- a/energy/src/energy/find/energy_finder.cpp +++ b/energy/src/energy/find/energy_finder.cpp @@ -20,7 +20,7 @@ int Energy::findFans(const cv::Mat src) { cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道 } std::vector > fan_contours; - StructingElementErodeDilate(src_bin);//图像膨胀,防止图像断开并更方便寻找 + FanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 // imshow("fan struct",src_bin); findContours(src_bin, fan_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); @@ -62,24 +62,24 @@ int Energy::findArmors(const cv::Mat src) { std::vector > armor_contours; std::vector > armor_contours_external;//用总轮廓减去外轮廓,只保留内轮廓,除去流动条的影响。 - StructingElementErodeDilate(src_bin);//图像膨胀,防止图像断开并更方便寻找 + ArmorStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 // imshow("armor struct", src_bin); findContours(src_bin, armor_contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE); 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 (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; @@ -90,12 +90,15 @@ int Energy::findArmors(const cv::Mat src) { // 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; -// if(length>10&&width>5){ +// if (length > 10 && width > 7) { // armors.emplace_back(cv::minAreaRect(armor_contour)); -// cout<<"armor area: "<(armors.size()); } @@ -111,7 +114,7 @@ bool Energy::findCenterR(const cv::Mat src) { cvtColor(src_bin, src_bin, CV_BGR2GRAY); } std::vector > center_R_contours; - StructingElementErodeDilate(src_bin); + CenterRStruct(src_bin); // 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) { @@ -123,17 +126,26 @@ bool Energy::findCenterR(const cv::Mat src) { 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的下方 - return true; // 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; -// if(length>10 && width>5){ -// centerRs.emplace_back(cv::minAreaRect(center_R_contour)); -// cout<<"center R area: "<19) { +// continue; // } +// std::vector intersection; +// if (rotatedRectangleIntersection(cur_rect, center_ROI, intersection) != 0 && +// contourArea(intersection) > energy_part_param_.CENTER_R_CONTOUR_INTERSETION_AREA_MIN) { +// centerR = cv::minAreaRect(center_R_contour); +// cout << "center R area: " << length << '\t' << width << '\t' << cur_rect.center << endl; +// cout << "R intersection: " << contourArea(intersection) << endl; +// return true; +// } + + return true; } + cout << "find center R false!" << endl; return false; } @@ -145,12 +157,14 @@ bool Energy::findCenterR(const cv::Mat src) { bool Energy::findFlowStripFan(const cv::Mat src) { if (src.empty())return false; static Mat src_bin; + static Mat src_copy; src_bin = src.clone(); + src_copy = src.clone(); if (src.type() == CV_8UC3) { cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道 } std::vector > flow_strip_fan_contours; - StructingElementErodeDilate(src_bin);//图像膨胀,防止图像断开并更方便寻找 + FlowStripFanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 // imshow("flow strip fan struct", src_bin); findContours(src_bin, flow_strip_fan_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); @@ -165,14 +179,20 @@ bool Energy::findFlowStripFan(const cv::Mat src) { // 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; -// if (length > 10 && width > 10) { -// cout << cur_rect.center; +// double cur_contour_area = contourArea(flow_strip_fan_contour); +// double non_zero_rate = nonZeroRateOfRotateRect(src_bin, cur_rect); +// if (length > 40 && width > 30 && length < 110 && width < 100) { +// cout << cur_rect.center< > flow_strip_contours; findContours(src_bin, flow_strip_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); @@ -202,13 +222,14 @@ bool Energy::findFlowStrip(const cv::Mat src) { // 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; -// if (length > 40 && width > 5) { +// if (length > 20 && width > 5) { // cout << cur_rect.center << endl; // flow_strip = cv::minAreaRect(flow_strip_contour); // cout << "flow strip fan area: " << length << '\t' << width << endl; // } return true; } + cout << "flow strip false!" << endl; return false; } @@ -235,211 +256,9 @@ bool Energy::findCenterROI(const cv::Mat src) { 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.4), - Size2f(length * 1.2, length * 1.2), -90); + Size2f(length * 1.4, length * 1.4), -90); return true; } -//---------------------------------------------------------------------------------------------------------------------- -// 此函数用于判断找到的矩形候选区是否为扇叶 -// --------------------------------------------------------------------------------------------------------------------- -bool Energy::isValidFanContour(cv::Mat &src, const vector &fan_contour) { - double cur_contour_area = contourArea(fan_contour); - if (cur_contour_area > energy_part_param_.FAN_CONTOUR_AREA_MAX || - cur_contour_area < energy_part_param_.FAN_CONTOUR_AREA_MIN) { - //cout< cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长 - float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;//将矩形的短边设置为宽 - if (length < energy_part_param_.FAN_CONTOUR_LENGTH_MIN || width < energy_part_param_.FAN_CONTOUR_WIDTH_MIN || - length > energy_part_param_.FAN_CONTOUR_LENGTH_MAX || width > energy_part_param_.FAN_CONTOUR_WIDTH_MAX) { - //cout<<"length width fail."< energy_part_param_.FAN_CONTOUR_HW_RATIO_MAX || - length_width_ratio < energy_part_param_.FAN_CONTOUR_HW_RATIO_MIN) { - //cout<<"length width ratio fail."< energy_part_param_.FAN_NON_ZERO_RATE_MAX || - non_zero_rate < energy_part_param_.FAN_NON_ZERO_RATE_MIN) - return false; - //亮点占比不合格 - return true; -} - - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数用于判断找到的矩形候选区是否为装甲板 -// --------------------------------------------------------------------------------------------------------------------- -bool Energy::isValidArmorContour(const vector &armor_contour) { - double cur_contour_area = contourArea(armor_contour); - if (cur_contour_area > energy_part_param_.ARMOR_CONTOUR_AREA_MAX || - cur_contour_area < energy_part_param_.ARMOR_CONTOUR_AREA_MIN) { - //cout< cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长 - float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;//将矩形的短边设置为宽 - if (length < energy_part_param_.ARMOR_CONTOUR_LENGTH_MIN || width < energy_part_param_.ARMOR_CONTOUR_WIDTH_MIN || - length > energy_part_param_.ARMOR_CONTOUR_LENGTH_MAX || width > energy_part_param_.ARMOR_CONTOUR_WIDTH_MAX) { - //cout<<"length width fail."< energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MAX || - length_width_ratio < energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MIN) { - //cout<<"length width ratio fail."< ¢er_R_contour) { - double cur_contour_area = contourArea(center_R_contour); - if (cur_contour_area > energy_part_param_.ARMOR_CONTOUR_AREA_MAX || - cur_contour_area < energy_part_param_.ARMOR_CONTOUR_AREA_MIN) { - //cout< cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长 - float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;//将矩形的短边设置为宽 - if (length < energy_part_param_.CENTER_R_CONTOUR_LENGTH_MIN || width < energy_part_param_.CENTER_R_CONTOUR_WIDTH_MIN - || length > energy_part_param_.CENTER_R_CONTOUR_LENGTH_MAX || - width > energy_part_param_.CENTER_R_CONTOUR_WIDTH_MAX) { - //cout<<"length width fail."< energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MAX || - length_width_ratio < energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MIN) { - //cout<<"length width ratio fail."< intersection; - if (rotatedRectangleIntersection(cur_rect, center_ROI, intersection) == 0 || - contourArea(intersection) < energy_part_param_.CENTER_R_CONTOUR_INTERSETION_AREA_MIN) { - return false; - } - return true; -} - - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数用于判断找到的矩形候选区是否为流动条扇叶 -// --------------------------------------------------------------------------------------------------------------------- -bool Energy::isValidFlowStripFanContour(cv::Mat &src, const vector &flow_strip_fan_contour) { - double cur_contour_area = contourArea(flow_strip_fan_contour); - if (cur_contour_area > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MAX || - cur_contour_area < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MIN) { - //cout< cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长 - float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;//将矩形的短边设置为宽 - if (length < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MIN - || width < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MIN - || length > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MAX - || width > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MAX) { - //cout<<"length width fail."< energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MAX || - length_width_ratio < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MIN) { - //cout<<"length width ratio fail."< energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MAX) -// // 轮廓对矩形的面积占有率不合适 -// return false; - double non_zero_rate = nonZeroRateOfRotateRect(src, cur_rect); - if (non_zero_rate > energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MAX || - non_zero_rate < energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MIN) - return false; - //亮点占比不合格 - return true; -} - - -//---------------------------------------------------------------------------------------------------------------------- -// 此函数用于判断找到的矩形候选区是否为流动条 -// --------------------------------------------------------------------------------------------------------------------- -bool Energy::isValidFlowStripContour(const vector &flow_strip_contour) { - double cur_contour_area = contourArea(flow_strip_contour); - if (cur_contour_area > energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MAX || - cur_contour_area < energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MIN) { -// cout<<"area fail."< cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长 - float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;//将矩形的短边设置为宽 - if (length < energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MIN || - width < energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MIN || - length > energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MAX || - width > energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MAX) { -// cout<<"length width fail."< energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MAX || - length_width_ratio < energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MIN) { -// cout<<"hw fail."< intersection; - if (rotatedRectangleIntersection(cur_rect, flow_strip_fan, intersection) == 0 || - contourArea(intersection) < energy_part_param_.FLOW_STRIP_CONTOUR_INTERSETION_AREA_MIN) { - return false; - } - return true; -} diff --git a/energy/src/energy/find/target_finder.cpp b/energy/src/energy/find/target_finder.cpp index 300cf86..4afa9ba 100644 --- a/energy/src/energy/find/target_finder.cpp +++ b/energy/src/energy/find/target_finder.cpp @@ -59,6 +59,7 @@ bool Energy::findTargetInFlowStripFan() { if (rotatedRectangleIntersection(armors.at(i), flow_strip_fan, intersection) == 0) continue;//返回0表示没有重合面积 double cur_contour_area = contourArea(intersection); +// cout< &fan_contour) { + double cur_contour_area = contourArea(fan_contour); + if (cur_contour_area > energy_part_param_.FAN_CONTOUR_AREA_MAX || + cur_contour_area < energy_part_param_.FAN_CONTOUR_AREA_MIN) { + //cout< cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长 + float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;//将矩形的短边设置为宽 + if (length < energy_part_param_.FAN_CONTOUR_LENGTH_MIN || width < energy_part_param_.FAN_CONTOUR_WIDTH_MIN || + length > energy_part_param_.FAN_CONTOUR_LENGTH_MAX || width > energy_part_param_.FAN_CONTOUR_WIDTH_MAX) { + //cout<<"length width fail."< energy_part_param_.FAN_CONTOUR_HW_RATIO_MAX || + length_width_ratio < energy_part_param_.FAN_CONTOUR_HW_RATIO_MIN) { + //cout<<"length width ratio fail."< energy_part_param_.FAN_NON_ZERO_RATE_MAX || +// non_zero_rate < energy_part_param_.FAN_NON_ZERO_RATE_MIN) +// return false; +// //亮点占比不合格 + return true; +} + + +//---------------------------------------------------------------------------------------------------------------------- +// 此函数用于判断找到的矩形候选区是否为装甲板 +// --------------------------------------------------------------------------------------------------------------------- +bool Energy::isValidArmorContour(const vector &armor_contour) { + double cur_contour_area = contourArea(armor_contour); + if (cur_contour_area > energy_part_param_.ARMOR_CONTOUR_AREA_MAX || + cur_contour_area < energy_part_param_.ARMOR_CONTOUR_AREA_MIN) { + //cout< cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长 + float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;//将矩形的短边设置为宽 + if (length < energy_part_param_.ARMOR_CONTOUR_LENGTH_MIN || width < energy_part_param_.ARMOR_CONTOUR_WIDTH_MIN || + length > energy_part_param_.ARMOR_CONTOUR_LENGTH_MAX || width > energy_part_param_.ARMOR_CONTOUR_WIDTH_MAX) { + //cout<<"length width fail."< energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MAX || + length_width_ratio < energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MIN) { + //cout<<"length width ratio fail."< ¢er_R_contour) { + double cur_contour_area = contourArea(center_R_contour); + if (cur_contour_area > energy_part_param_.ARMOR_CONTOUR_AREA_MAX || + cur_contour_area < energy_part_param_.ARMOR_CONTOUR_AREA_MIN) { + //cout< cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长 + float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;//将矩形的短边设置为宽 + if (length < energy_part_param_.CENTER_R_CONTOUR_LENGTH_MIN || width < energy_part_param_.CENTER_R_CONTOUR_WIDTH_MIN + || length > energy_part_param_.CENTER_R_CONTOUR_LENGTH_MAX || + width > energy_part_param_.CENTER_R_CONTOUR_WIDTH_MAX) { + //cout<<"length width fail."< energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MAX || + length_width_ratio < energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MIN) { + //cout<<"length width ratio fail."< intersection; + if (rotatedRectangleIntersection(cur_rect, center_ROI, intersection) == 0) { + return false; + } else if (contourArea(intersection) < energy_part_param_.CENTER_R_CONTOUR_INTERSETION_AREA_MIN) { + cout << "R intersection: " << contourArea(intersection) << endl; + return false; + } + return true; +} + + +//---------------------------------------------------------------------------------------------------------------------- +// 此函数用于判断找到的矩形候选区是否为流动条扇叶 +// --------------------------------------------------------------------------------------------------------------------- +bool Energy::isValidFlowStripFanContour(cv::Mat &src, const vector &flow_strip_fan_contour) { + double cur_contour_area = contourArea(flow_strip_fan_contour); + if (cur_contour_area > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MAX || + cur_contour_area < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MIN) { + //cout< cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长 + float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;//将矩形的短边设置为宽 + if (length < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MIN + || width < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MIN + || length > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MAX + || width > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MAX) { + //cout<<"length width fail."< energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MAX || + length_width_ratio < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MIN) { + //cout<<"length width ratio fail."< energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MAX) { + return false; + } + // 轮廓对矩形的面积占有率不合适 + double non_zero_rate = nonZeroRateOfRotateRect(src, cur_rect); +// cout< energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MAX || +// non_zero_rate < energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MIN){ +// //cout< &flow_strip_contour) { + double cur_contour_area = contourArea(flow_strip_contour); + if (cur_contour_area > energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MAX || + cur_contour_area < energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MIN) { +// cout<<"area fail."< cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长 + float width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;//将矩形的短边设置为宽 + if (length < energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MIN || + width < energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MIN || + length > energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MAX || + width > energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MAX) { +// cout<<"length width fail."< energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MAX || + length_width_ratio < energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MIN) { +// cout<<"hw fail."< intersection; + if (rotatedRectangleIntersection(cur_rect, flow_strip_fan, intersection) == 0 || + contourArea(intersection) < energy_part_param_.FLOW_STRIP_CONTOUR_INTERSETION_AREA_MIN) { + return false; + } + return true; +} diff --git a/energy/src/energy/run.cpp b/energy/src/energy/run.cpp index 3a72e4c..c15f05c 100644 --- a/energy/src/energy/run.cpp +++ b/energy/src/energy/run.cpp @@ -15,7 +15,7 @@ using namespace cv; void Energy::run(cv::Mat &gimbal_src, cv::Mat &chassis_src) { if (chassis_src.empty()) run(gimbal_src);//仅拥有云台摄像头则调用单摄像头的run函数 - else if (isgimbal) { + else if (isGimbal) { energy_part_param_ = gimbal_energy_part_param_; clearAll(); initImage(gimbal_src); @@ -24,17 +24,16 @@ void Energy::run(cv::Mat &gimbal_src, cv::Mat &chassis_src) { if (!findFlowStripFan(gimbal_src))return; if (!findTargetInFlowStripFan()) return; if (!findCenterROI(gimbal_src))return; - if (!findCenterR(gimbal_src))return; - if (show_energy)showFlowStripFan("strip", gimbal_src); + if (!findCenterR(gimbal_src))return; if (show_energy)showCenterR("R", gimbal_src); if (!getOrigin())return; startChassis(); initEnergy(); - + destroyAllWindows(); } else if (isChassis) { - energy_part_param_ = chassis_energy_part_param_; + energy_part_param_ = gimbal_energy_part_param_; clearAll(); initImage(chassis_src); @@ -42,12 +41,11 @@ void Energy::run(cv::Mat &gimbal_src, cv::Mat &chassis_src) { if (isMark)return;//操作手强制手动标定origin_yaw和origin_pitch if (findArmors(chassis_src) < 1)return; - if (!findFlowStripFan(chassis_src))return; + if (!findFlowStripFan(chassis_src))return;showFlowStripFan("flow strip fan", chassis_src); if (!findTargetInFlowStripFan()) return; if (!findCenterROI(chassis_src))return; - if (!findCenterR(chassis_src))return; - if (show_energy)showFlowStripFan("strip", chassis_src); + if (!findCenterR(chassis_src))return; if (show_energy)showCenterR("R", chassis_src); getTargetPolarAngle(); diff --git a/main.cpp b/main.cpp index 700eb69..f8224bc 100644 --- a/main.cpp +++ b/main.cpp @@ -64,8 +64,8 @@ int main(int argc, char *argv[]) { video_gimbal = new CameraWrapper(0/*, "armor"*/); video_chassis = new CameraWrapper(1/*, "energy"*/); } else { - video_gimbal = new VideoWrapper("/home/sun/项目/energy_video/energy_test.avi"); - video_chassis = new VideoWrapper("/home/sun/项目/energy_video/energy_test.avi"); + video_gimbal = new VideoWrapper("/home/sun/项目/energy_video/147.avi"); + video_chassis = new VideoWrapper("/home/sun/项目/energy_video/147.avi"); } if (video_gimbal->init()) { LOGM("video_gimbal source initialization successfully."); @@ -102,14 +102,15 @@ int main(int argc, char *argv[]) { #endif } ok = checkReconnect(video_gimbal->read(gimbal_src)); + video_chassis->read(chassis_src); #ifdef GIMBAL_FLIP_MODE - flip(gimbal_src, gimbal_src, CHASSIS_FLIP_MODE); + flip(gimbal_src, gimbal_src, GIMBAL_FLIP_MODE); #endif if (!from_camera) extract(gimbal_src, chassis_src); if (save_video) saveVideos(gimbal_src, chassis_src);//保存视频 if (show_origin) showOrigin(gimbal_src, chassis_src);//显示原始图像 -// energy.run(gimbal_src, chassis_src); - energy.run(gimbal_src); + energy.run(gimbal_src, chassis_src); +// energy.run(gimbal_src); last_state = mcuData.state;//更新上一帧状态 } else { // 自瞄模式 if (last_state != ARMOR_STATE) { @@ -118,7 +119,7 @@ int main(int argc, char *argv[]) { last_state = mcuData.state; ok = checkReconnect(video_gimbal->read(gimbal_src)); #ifdef GIMBAL_FLIP_MODE - flip(gimbal_src, gimbal_src, CHASSIS_FLIP_MODE); + flip(gimbal_src, gimbal_src, GIMBAL_FLIP_MODE); #endif if (!from_camera) extract(gimbal_src); if (save_video) saveVideos(gimbal_src); @@ -127,7 +128,7 @@ int main(int argc, char *argv[]) { armorFinder.run(gimbal_src); }); } -// cv::waitKey(0); + cv::waitKey(0); }); } while (ok); delete video_gimbal; diff --git a/others/src/camera/camera_wrapper.cpp b/others/src/camera/camera_wrapper.cpp index eb328e4..cfad14e 100644 --- a/others/src/camera/camera_wrapper.cpp +++ b/others/src/camera/camera_wrapper.cpp @@ -78,7 +78,7 @@ bool CameraWrapper::init() { CameraSetExposureTime(h_camera, 10*1000); CameraSetAnalogGain(h_camera, 50); if(mode == 0){ - CameraSetGain(h_camera, 100, 100, 100); + CameraSetGain(h_camera, 100, 135, 119); CameraSetLutMode(h_camera, LUTMODE_PRESET); } #endif