energy changed
This commit is contained in:
@@ -132,6 +132,7 @@ private:
|
||||
bool findFlowStrip(const cv::Mat src);//寻找图中的流动条
|
||||
bool findCenterROI(const cv::Mat src);//框取中心R候选区
|
||||
bool findFlowStripFan(const cv::Mat src);//寻找图中的流动条所在扇叶
|
||||
bool findFlowStripWeak(const cv::Mat src);//弱识别寻找图中的流动条
|
||||
|
||||
bool isValidFanContour(cv::Mat &src, const vector<cv::Point> &fan_contour);//扇叶矩形尺寸要求
|
||||
bool isValidArmorContour(const vector<cv::Point> &armor_contour);//装甲板矩形尺寸要求
|
||||
@@ -143,6 +144,7 @@ private:
|
||||
void showArmors(std::string windows_name, const cv::Mat src);//显示装甲板
|
||||
void showBoth(std::string windows_name, const cv::Mat src);//显示扇叶和装甲板
|
||||
void showCenterR(std::string windows_name, const cv::Mat src);//显示风车中心候选区R
|
||||
void showFlowStrip(std::string windows_name, const cv::Mat src);//显示流动条
|
||||
void showFlowStripFan(std::string windows_name, const cv::Mat src);//显示流动条所在扇叶
|
||||
void showGuessTarget(std::string windows_name, const cv::Mat src);//显示猜测点位
|
||||
|
||||
|
||||
@@ -83,6 +83,9 @@ struct EnergyPartParam {
|
||||
|
||||
long TARGET_CHANGE_DISTANCE_MAX;//目标未更改时,目标装甲板中心与原目标装甲板中心的距离变化最大值
|
||||
long TWIN_POINT_MAX;//两个点相同时距离最大值
|
||||
|
||||
long STRIP_ARMOR_DISTANCE_MIN;//流动条中心和目标装甲板中心距离最小值
|
||||
long STRIP_ARMOR_DISTANCE_MAX;//流动条中心和目标装甲板中心距离最大值
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -71,7 +71,6 @@ void Energy::initEnergy() {
|
||||
all_target_armor_centers.clear();
|
||||
while(!recent_target_armor_centers.empty())recent_target_armor_centers.pop();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +80,7 @@ void Energy::initEnergy() {
|
||||
void Energy::initEnergyPartParam() {
|
||||
// gimbal_energy_part_param_.GRAY_THRESH = 120;//home
|
||||
// gimbal_energy_part_param_.GRAY_THRESH = 200;//official
|
||||
gimbal_energy_part_param_.GRAY_THRESH = 180;
|
||||
gimbal_energy_part_param_.GRAY_THRESH = 180;//game
|
||||
gimbal_energy_part_param_.SPLIT_GRAY_THRESH = 180;
|
||||
gimbal_energy_part_param_.FAN_GRAY_THRESH = 75;
|
||||
gimbal_energy_part_param_.ARMOR_GRAY_THRESH = 80;
|
||||
@@ -100,8 +99,8 @@ void Energy::initEnergyPartParam() {
|
||||
// gimbal_energy_part_param_.FAN_NON_ZERO_RATE_MAX = 0.3;
|
||||
// gimbal_energy_part_param_.FAN_NON_ZERO_RATE_MIN = 0.16;
|
||||
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_AREA_MAX = 100000;
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_AREA_MIN = 0;
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_AREA_MAX = 500;
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_AREA_MIN = 180;
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_LENGTH_MIN = 16;
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_LENGTH_MAX = 32;
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_WIDTH_MIN = 5;
|
||||
@@ -109,42 +108,41 @@ void Energy::initEnergyPartParam() {
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MAX = 3;
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MIN = 1;
|
||||
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_AREA_MAX = 100000;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_AREA_MIN = 0;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_LENGTH_MIN = 8;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_LENGTH_MAX = 45;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_WIDTH_MIN = 8;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_WIDTH_MAX = 45;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MAX = 3;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_AREA_MAX = 200;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_AREA_MIN = 40;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_LENGTH_MIN = 6;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_LENGTH_MAX = 20;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_WIDTH_MIN = 6;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_WIDTH_MAX = 20;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MAX = 2;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MIN = 1;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_AREA_RATIO_MIN = 0.3;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_AREA_RATIO_MIN = 0.6;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_INTERSETION_AREA_MIN = 10;
|
||||
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MAX = 3000;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MIN = 1000;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MAX = 2000;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MIN = 500;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MIN = 60;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MAX = 100;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MIN = 20;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MAX = 52;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MAX = 3;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MIN = 1;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MAX = 0.65;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MAX = 2.8;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MIN = 1.2;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MAX = 0.58;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MIN = 0.34;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MAX = 0.65;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MAX = 0.58;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MIN = 0.34;
|
||||
// gimbal_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MAX = 0.2;
|
||||
// gimbal_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MIN = 0.08;
|
||||
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MAX = 100000;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MIN = 0;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MIN = 30;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MAX = 700;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MIN = 100;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MIN = 32;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MAX = 55;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MIN = 4;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MAX = 20;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MAX = 12;
|
||||
// gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MIN = 4;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MIN = 1.5;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_AREA_RATIO_MIN = 0.5;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MAX = 7;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MIN = 3;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_AREA_RATIO_MIN = 0.6;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_INTERSETION_AREA_MIN = 100;
|
||||
|
||||
gimbal_energy_part_param_.TWIN_ANGEL_MAX = 10;
|
||||
@@ -153,6 +151,9 @@ void Energy::initEnergyPartParam() {
|
||||
gimbal_energy_part_param_.TARGET_CHANGE_DISTANCE_MAX = 20;
|
||||
gimbal_energy_part_param_.TWIN_POINT_MAX = 20;
|
||||
|
||||
gimbal_energy_part_param_.STRIP_ARMOR_DISTANCE_MIN = 28;
|
||||
gimbal_energy_part_param_.STRIP_ARMOR_DISTANCE_MAX = 52;
|
||||
|
||||
|
||||
|
||||
chassis_energy_part_param_.GRAY_THRESH = 120;//home
|
||||
|
||||
@@ -14,7 +14,7 @@ using std::vector;
|
||||
// 此函数用于寻找图像内所有的大风车扇叶
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
int Energy::findFans(const cv::Mat src) {
|
||||
if (src.empty()){
|
||||
if (src.empty()) {
|
||||
if (show_info) cout << "empty!" << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -62,7 +62,7 @@ int Energy::findFans(const cv::Mat src) {
|
||||
// 此函数用于寻找图像内所有的大风车装甲板模块
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
int Energy::findArmors(const cv::Mat src) {
|
||||
if (src.empty()){
|
||||
if (src.empty()) {
|
||||
if (show_info) cout << "empty!" << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -77,40 +77,44 @@ int Energy::findArmors(const cv::Mat src) {
|
||||
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;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
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;
|
||||
// if (length > 5 && width > 5) {
|
||||
// armors.emplace_back(cv::minAreaRect(armor_contour));
|
||||
// cout << "armor area: " << length << '\t' << width << '\t' << cur_rect.center << endl;
|
||||
// }
|
||||
// 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<<endl;
|
||||
|
||||
}
|
||||
|
||||
// cout<<armors.size()<<endl;
|
||||
// showArmors("armor",src);
|
||||
|
||||
// if (armors.size() < 1)cout << "no armors!" << endl;
|
||||
if (show_info) {
|
||||
// if (armors.size() < 1)cout << "no armors!" << endl;
|
||||
}
|
||||
|
||||
return static_cast<int>(armors.size());
|
||||
}
|
||||
@@ -120,7 +124,7 @@ int Energy::findArmors(const cv::Mat src) {
|
||||
// 此函数用于寻找图像内大风车中心字母“R”
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
bool Energy::findCenterR(const cv::Mat src) {
|
||||
if (src.empty()){
|
||||
if (src.empty()) {
|
||||
if (show_info) cout << "empty!" << endl;
|
||||
return false;
|
||||
}
|
||||
@@ -147,22 +151,18 @@ bool Energy::findCenterR(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 || length>19) {
|
||||
// continue;
|
||||
// }
|
||||
// std::vector<cv::Point2f> 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;
|
||||
// }
|
||||
// cout << cur_rect.center << endl;
|
||||
// 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<<endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
if (show_info)cout << "find center R false!" << endl;
|
||||
// cv::waitKey(0);
|
||||
// cv::waitKey(0);
|
||||
return false;
|
||||
|
||||
}
|
||||
@@ -172,7 +172,7 @@ bool Energy::findCenterR(const cv::Mat src) {
|
||||
// 此函数用于判断找到的矩形候选区是否为含流动条的扇叶
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
bool Energy::findFlowStripFan(const cv::Mat src) {
|
||||
if (src.empty()){
|
||||
if (src.empty()) {
|
||||
if (show_info) cout << "empty!" << endl;
|
||||
return false;
|
||||
}
|
||||
@@ -201,17 +201,16 @@ bool Energy::findFlowStripFan(const cv::Mat src) {
|
||||
// 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);
|
||||
// if (length > 40 && width > 30 && length < 110 && width < 100) {
|
||||
// cout << cur_rect.center<<endl;
|
||||
// flow_strip_fan = cv::minAreaRect(flow_strip_fan_contour);
|
||||
// cout << "flow strip fan area: " << length << '\t' << width << endl;
|
||||
// cout << "non zero: " << non_zero_rate << endl;
|
||||
// cout<<cur_contour_area / cur_size.area()<<endl;
|
||||
// }
|
||||
// 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 << "flow_strip_fans_cnt: " << flow_strip_fans.size() << endl;
|
||||
if (flow_strip_fans.empty()) {
|
||||
if (show_info)cout << "flow strip fan false!" << endl;
|
||||
if (show_info)cout << "flow strip fan false!" << endl;\
|
||||
// waitKey(0);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -274,25 +273,15 @@ 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;
|
||||
// float length_width_ratio = length / 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;
|
||||
|
||||
// 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;
|
||||
// if (length / width > 2.5 && width > 7 && width<40) {
|
||||
// cout << cur_rect.center << endl;
|
||||
// flow_strip = cv::minAreaRect(flow_strip_contour);
|
||||
// cout << "flow strip area: " << length << '\t' << width << endl;
|
||||
// }
|
||||
// cout << cur_rect.center << endl;
|
||||
// cout<<endl;
|
||||
}
|
||||
}
|
||||
// cout << "flow strip cnt: " << flow_strips.size() << endl;
|
||||
if (flow_strips.empty()) {
|
||||
if (show_info)cout << "flow strip false!" << endl;
|
||||
// waitKey(0);
|
||||
@@ -327,6 +316,97 @@ bool Energy::findFlowStrip(const cv::Mat src) {
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// 此函数用于弱识别寻找流动条
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
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<cv::RotatedRect> 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<vector<Point> > 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的寻找范围
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -100,8 +100,8 @@ bool Energy::isValidArmorContour(const vector<cv::Point> &armor_contour) {
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
bool Energy::isValidCenterRContour(const vector<cv::Point> ¢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) {
|
||||
if (cur_contour_area > energy_part_param_.CENTER_R_CONTOUR_AREA_MAX ||
|
||||
cur_contour_area < energy_part_param_.CENTER_R_CONTOUR_AREA_MIN) {
|
||||
//cout<<cur_contour_area<<" "<<energy_fan_param_.CONTOUR_AREA_MIN<<" "<<energy_fan_param_.CONTOUR_AREA_MAX<<endl;
|
||||
//cout<<"area fail."<<endl;
|
||||
return false;
|
||||
|
||||
@@ -78,11 +78,15 @@ void Energy::runBig(cv::Mat &gimbal_src) {
|
||||
if (show_process)imshow("bin", gimbal_src);
|
||||
if (findArmors(gimbal_src) < 1)return;
|
||||
if (show_energy)showArmors("armor", gimbal_src);
|
||||
if (!findFlowStripFan(gimbal_src))return;
|
||||
if (!findTargetInFlowStripFan()) return;
|
||||
if (!findFlowStrip(gimbal_src))return;
|
||||
if (!findFlowStripFan(gimbal_src)) {
|
||||
if (!findFlowStripWeak(gimbal_src))return;
|
||||
} else {
|
||||
if (show_energy)showFlowStripFan("strip fan", gimbal_src);
|
||||
if (!findTargetInFlowStripFan()) return;
|
||||
if (!findFlowStrip(gimbal_src))return;
|
||||
}
|
||||
if (!findCenterROI(gimbal_src))return;
|
||||
if (show_energy)showFlowStripFan("strip", gimbal_src);
|
||||
if (show_energy)showFlowStrip("strip", gimbal_src);
|
||||
if (!findCenterR(gimbal_src))return;
|
||||
if (show_energy)showCenterR("R", gimbal_src);
|
||||
|
||||
|
||||
@@ -19,28 +19,23 @@ void Energy::sendEnergy() {
|
||||
sum_yaw += yaw_rotation;
|
||||
sum_pitch += pitch_rotation;
|
||||
MINMAX(sum_yaw, -100, 100);
|
||||
MINMAX(sum_pitch, -100, 100);
|
||||
// float KP = 4.5;
|
||||
// if(abs(yaw_rotation)<0.3)KP=0.1;
|
||||
// else if(abs(yaw_rotation)<0.5)KP=0.1;
|
||||
// else KP = 0.1; " << yaw_rotation << '\t' << "pitch: " << pitch_rotation << endl;
|
||||
yaw_rotation = YAW_AIM_KP * yaw_rotation + YAW_AIM_KI * sum_yaw + YAW_AIM_KD * (yaw_rotation - last_yaw);
|
||||
pitch_rotation = PITCH_AIM_KP * pitch_rotation + PITCH_AIM_KI * sum_pitch +
|
||||
PITCH_AIM_KD * (pitch_rotation - last_pitch);
|
||||
MINMAX(sum_pitch, -100, 100);\
|
||||
yaw_rotation = BIG_YAW_AIM_KP * yaw_rotation + BIG_YAW_AIM_KI * sum_yaw + BIG_YAW_AIM_KD * (yaw_rotation - last_yaw);
|
||||
pitch_rotation = BIG_PITCH_AIM_KP * pitch_rotation + BIG_PITCH_AIM_KI * sum_pitch +
|
||||
BIG_PITCH_AIM_KD * (pitch_rotation - last_pitch);
|
||||
} else if (is_chassis) {
|
||||
sum_yaw += yaw_rotation - mcuData.curr_yaw;
|
||||
sum_pitch += pitch_rotation - mcuData.curr_pitch;
|
||||
yaw_rotation = YAW_AIM_KP * (yaw_rotation - mcuData.curr_yaw) + YAW_AIM_KI * sum_yaw;
|
||||
pitch_rotation = PITCH_AIM_KP * (pitch_rotation - mcuData.curr_pitch) + PITCH_AIM_KI * sum_pitch;
|
||||
yaw_rotation = BIG_YAW_AIM_KP * (yaw_rotation - mcuData.curr_yaw) + BIG_YAW_AIM_KI * sum_yaw;
|
||||
pitch_rotation = BIG_PITCH_AIM_KP * (pitch_rotation - mcuData.curr_pitch) + BIG_PITCH_AIM_KI * sum_pitch;
|
||||
}
|
||||
} else if (is_small){
|
||||
sum_yaw += yaw_rotation;
|
||||
sum_pitch += pitch_rotation;
|
||||
MINMAX(sum_yaw, -100, 100);
|
||||
MINMAX(sum_pitch, -100, 100);
|
||||
yaw_rotation = 2.5 * yaw_rotation + 0.08 * sum_yaw + 1.5 * (yaw_rotation - last_yaw);
|
||||
pitch_rotation = 2.4 * pitch_rotation + 0.07 * sum_pitch +
|
||||
1.3 * (pitch_rotation - last_pitch);
|
||||
yaw_rotation = SMALL_YAW_AIM_KP * yaw_rotation + SMALL_YAW_AIM_KD * (yaw_rotation - last_yaw);
|
||||
pitch_rotation = SMALL_PITCH_AIM_KP * pitch_rotation + SMALL_PITCH_AIM_KD * (pitch_rotation - last_pitch);
|
||||
}
|
||||
|
||||
if (change_target) {
|
||||
|
||||
@@ -126,7 +126,7 @@ void Energy::showCenterR(std::string windows_name, const cv::Mat src) {
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// 此函数用于显示图像中所有流动条
|
||||
// 此函数用于显示图像中流动条扇叶
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
void Energy::showFlowStripFan(std::string windows_name, const cv::Mat src) {
|
||||
if (src.empty())return;
|
||||
@@ -145,7 +145,23 @@ void Energy::showFlowStripFan(std::string windows_name, const cv::Mat src) {
|
||||
flow_strip_fan.points(strip_fan_vertices); //计算矩形的4个顶点for (int i = 0; i < 4; i++)
|
||||
for (int i = 0; i < 4; i++)
|
||||
line(image2show, strip_fan_vertices[i], strip_fan_vertices[(i + 1) % 4], Scalar(127, 127, 255), 2);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// 此函数用于显示图像中流动条扇叶
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
void Energy::showFlowStrip(std::string windows_name, const cv::Mat src) {
|
||||
if (src.empty())return;
|
||||
static Mat image2show;
|
||||
|
||||
if (src.type() == CV_8UC1) // 黑白图像
|
||||
{
|
||||
cvtColor(src, image2show, COLOR_GRAY2RGB);
|
||||
|
||||
} else if (src.type() == CV_8UC3) //RGB 彩色
|
||||
{
|
||||
image2show = src.clone();
|
||||
}
|
||||
|
||||
Point2f strip_vertices[4]; //定义矩形的4个顶点
|
||||
flow_strip.points(strip_vertices); //计算矩形的4个顶点
|
||||
|
||||
Reference in New Issue
Block a user