energy changed
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,3 +7,5 @@ tools/TrainCNN/.idea
|
||||
tools/TrainCNN/__pycache__
|
||||
others/include/config/config.h
|
||||
.DS_Store
|
||||
gimble_video
|
||||
chassis_video
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -14,7 +14,7 @@ using namespace cv;
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
void Energy::startChassis(){
|
||||
isChassis = true;
|
||||
isgimbal = false;
|
||||
isGimbal = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
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;
|
||||
isGimbal = true;
|
||||
isChassis = false;
|
||||
}
|
||||
@@ -20,7 +20,7 @@ int Energy::findFans(const cv::Mat src) {
|
||||
cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
|
||||
}
|
||||
std::vector<vector<Point> > 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<vector<Point> > armor_contours;
|
||||
std::vector<vector<Point> > 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: " << length << '\t' << width << '\t' << cur_rect.center << endl;
|
||||
// }
|
||||
|
||||
}
|
||||
// cout<<armors.size()<<endl;
|
||||
// showArmors("armor",src);
|
||||
if (armors.size() < 1)cout << "no armors!" << endl;
|
||||
return static_cast<int>(armors.size());
|
||||
}
|
||||
|
||||
@@ -111,7 +114,7 @@ bool Energy::findCenterR(const cv::Mat src) {
|
||||
cvtColor(src_bin, src_bin, CV_BGR2GRAY);
|
||||
}
|
||||
std::vector<vector<Point> > 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: "<<length<<'\t'<<width<<'\t'<<cur_rect.center<<endl;
|
||||
// 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;
|
||||
// }
|
||||
|
||||
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<vector<Point> > 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<<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;
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
// showFlowStripFan("strip fan", src_bin);
|
||||
cout << "flow strip fan false!" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -187,8 +207,8 @@ bool Energy::findFlowStrip(const cv::Mat src) {
|
||||
if (src.type() == CV_8UC3) {
|
||||
cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
|
||||
}
|
||||
StructingElementErodeDilate(src_bin);//图像膨胀,防止图像断开并更方便寻找
|
||||
// imshow("flow strip struct", src_bin);
|
||||
FlowStripStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
|
||||
imshow("flow strip struct", src_bin);
|
||||
|
||||
std::vector<vector<Point> > 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<cv::Point> &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_contour_area<<" "<<energy_fan_param_.CONTOUR_AREA_MIN<<" "<<energy_fan_param_.CONTOUR_AREA_MAX<<endl;
|
||||
//cout<<"area fail."<<endl;
|
||||
return false;
|
||||
//选区面积大小不合适
|
||||
}
|
||||
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;//将矩形的短边设置为宽
|
||||
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."<<endl;
|
||||
return false;
|
||||
//矩形边长不合适
|
||||
}
|
||||
float length_width_ratio = length / width;//计算矩形长宽比
|
||||
if (length_width_ratio > energy_part_param_.FAN_CONTOUR_HW_RATIO_MAX ||
|
||||
length_width_ratio < energy_part_param_.FAN_CONTOUR_HW_RATIO_MIN) {
|
||||
//cout<<"length width ratio fail."<<endl;
|
||||
return false;
|
||||
//长宽比不合适
|
||||
}
|
||||
// if (cur_contour_area / cur_size.area() < energy_part_param_.FAN_CONTOUR_AREA_RATIO_MIN)
|
||||
// return false;//轮廓对矩形的面积占有率不合适
|
||||
double non_zero_rate = nonZeroRateOfRotateRect(src, cur_rect);
|
||||
if (non_zero_rate > 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<cv::Point> &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_contour_area<<" "<<energy_fan_param_.CONTOUR_AREA_MIN<<" "<<energy_fan_param_.CONTOUR_AREA_MAX<<endl;
|
||||
//cout<<"area fail."<<endl;
|
||||
return false;
|
||||
//选区面积大小不合适
|
||||
}
|
||||
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 < 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."<<endl;
|
||||
return false;
|
||||
//矩形边长不合适
|
||||
}
|
||||
|
||||
float length_width_ratio = length / width;//计算矩形长宽比
|
||||
if (length_width_ratio > energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MAX ||
|
||||
length_width_ratio < energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MIN) {
|
||||
//cout<<"length width ratio fail."<<endl;
|
||||
return false;
|
||||
//长宽比不合适
|
||||
}
|
||||
if (cur_contour_area / cur_size.area() < energy_part_param_.ARMOR_CONTOUR_AREA_RATIO_MIN)
|
||||
return false;//轮廓对矩形的面积占有率不合适
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// 此函数用于判断找到的矩形候选区是否为可能的风车中心R候选区
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
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) {
|
||||
//cout<<cur_contour_area<<" "<<energy_fan_param_.CONTOUR_AREA_MIN<<" "<<energy_fan_param_.CONTOUR_AREA_MAX<<endl;
|
||||
//cout<<"area fail."<<endl;
|
||||
return false;
|
||||
//选区面积大小不合适
|
||||
}
|
||||
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 < 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."<<endl;
|
||||
return false;
|
||||
//矩形边长不合适
|
||||
}
|
||||
float length_width_ratio = length / width;//计算矩形长宽比
|
||||
if (length_width_ratio > 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."<<endl;
|
||||
return false;
|
||||
//长宽比不合适
|
||||
}
|
||||
if (cur_contour_area / cur_size.area() < energy_part_param_.CENTER_R_CONTOUR_AREA_RATIO_MIN)
|
||||
return false;//轮廓对矩形的面积占有率不合适
|
||||
std::vector<cv::Point2f> 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<cv::Point> &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_contour_area<<" "<<energy_fan_param_.CONTOUR_AREA_MIN<<" "<<energy_fan_param_.CONTOUR_AREA_MAX<<endl;
|
||||
//cout<<"area fail."<<endl;
|
||||
return false;
|
||||
//选区面积大小不合适
|
||||
}
|
||||
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;//将矩形的短边设置为宽
|
||||
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."<<endl;
|
||||
return false;
|
||||
//矩形边长不合适
|
||||
}
|
||||
|
||||
float length_width_ratio = length / width;//计算矩形长宽比
|
||||
if (length_width_ratio > 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."<<endl;
|
||||
return false;
|
||||
//长宽比不合适
|
||||
}
|
||||
// if (cur_contour_area / cur_size.area() < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MIN
|
||||
// || cur_contour_area / cur_size.area() > 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<cv::Point> &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."<<endl;
|
||||
|
||||
return false;
|
||||
//选区面积大小不合适
|
||||
}
|
||||
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 < 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."<<endl;
|
||||
return false;
|
||||
//矩形边长不合适
|
||||
}
|
||||
float length_width_ratio = length / width;//计算矩形长宽比
|
||||
if (length_width_ratio > energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MAX ||
|
||||
length_width_ratio < energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MIN) {
|
||||
// cout<<"hw fail."<<endl;
|
||||
return false;
|
||||
//长宽比不合适
|
||||
}
|
||||
if (cur_contour_area / cur_size.area() < energy_part_param_.FLOW_STRIP_CONTOUR_AREA_RATIO_MIN)
|
||||
return false;//轮廓对矩形的面积占有率不合适
|
||||
std::vector<cv::Point2f> 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;
|
||||
}
|
||||
|
||||
@@ -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<<cur_contour_area<<endl;
|
||||
if (cur_contour_area < energy_part_param_.TARGET_INTERSETION_CONTOUR_AREA_MIN)
|
||||
continue;
|
||||
else {
|
||||
@@ -67,5 +68,7 @@ bool Energy::findTargetInFlowStripFan() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// cout<<"find target false"<<endl;
|
||||
// cout<<armors.size()<<'\t'<<armors.at(0).size<<endl;
|
||||
return false;
|
||||
}
|
||||
@@ -51,8 +51,6 @@ void Energy::initEnergy() {
|
||||
|
||||
clockwise_rotation_init_cnt = 0;
|
||||
anticlockwise_rotation_init_cnt = 0;
|
||||
|
||||
destroyAllWindows();
|
||||
}
|
||||
|
||||
|
||||
@@ -60,8 +58,8 @@ void Energy::initEnergy() {
|
||||
// 此函数对能量机关参数进行初始化
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
void Energy::initEnergyPartParam() {
|
||||
gimbal_energy_part_param_.GRAY_THRESH = 160;
|
||||
gimbal_energy_part_param_.SPLIT_GRAY_THRESH = 180;
|
||||
gimbal_energy_part_param_.GRAY_THRESH = 80;
|
||||
gimbal_energy_part_param_.SPLIT_GRAY_THRESH = 230;
|
||||
gimbal_energy_part_param_.FAN_GRAY_THRESH = 75;
|
||||
gimbal_energy_part_param_.ARMOR_GRAY_THRESH = 80;
|
||||
|
||||
@@ -75,22 +73,24 @@ void Energy::initEnergyPartParam() {
|
||||
gimbal_energy_part_param_.FAN_CONTOUR_HW_RATIO_MIN = 1;
|
||||
gimbal_energy_part_param_.FAN_NON_ZERO_RATE_MAX = 0.8;
|
||||
gimbal_energy_part_param_.FAN_NON_ZERO_RATE_MIN = 0.48;
|
||||
// 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_LENGTH_MIN = 18;
|
||||
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 = 10;
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_WIDTH_MAX = 30;
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_WIDTH_MIN = 7;
|
||||
gimbal_energy_part_param_.ARMOR_CONTOUR_WIDTH_MAX = 25;
|
||||
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 = 7;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_LENGTH_MAX = 19;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_LENGTH_MAX = 25;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_WIDTH_MIN = 7;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_WIDTH_MAX = 19;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_WIDTH_MAX = 25;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MAX = 3;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MIN = 1;
|
||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_AREA_RATIO_MIN = 0.7;
|
||||
@@ -98,35 +98,38 @@ void Energy::initEnergyPartParam() {
|
||||
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MAX = 17000;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MIN = 0;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MIN = 56;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MAX = 88;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MIN = 21;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MAX = 40;
|
||||
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 = 50;
|
||||
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.55;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MIN = 0.25;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MAX = 0.48;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MIN = 0.25;
|
||||
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.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 = 31;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MAX = 57;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MIN = 2;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MAX = 13;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MIN = 40;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MAX = 65;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MIN = 8;
|
||||
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 = 4;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MIN = 3;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_AREA_RATIO_MIN = 0.5;
|
||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_INTERSETION_AREA_MIN = 117;
|
||||
|
||||
gimbal_energy_part_param_.TWIN_ANGEL_MAX = 10;
|
||||
gimbal_energy_part_param_.TARGET_INTERSETION_CONTOUR_AREA_MIN = 24;
|
||||
gimbal_energy_part_param_.TARGET_INTERSETION_CONTOUR_AREA_MIN = 40;
|
||||
|
||||
|
||||
|
||||
chassis_energy_part_param_.GRAY_THRESH = 225;
|
||||
chassis_energy_part_param_.SPLIT_GRAY_THRESH = 60;
|
||||
chassis_energy_part_param_.GRAY_THRESH = 80;
|
||||
chassis_energy_part_param_.SPLIT_GRAY_THRESH = 230;
|
||||
chassis_energy_part_param_.FAN_GRAY_THRESH = 75;
|
||||
chassis_energy_part_param_.ARMOR_GRAY_THRESH = 80;
|
||||
|
||||
@@ -141,6 +144,8 @@ void Energy::initEnergyPartParam() {
|
||||
chassis_energy_part_param_.FAN_CONTOUR_AREA_RATIO_MIN = 0.6;
|
||||
chassis_energy_part_param_.FAN_NON_ZERO_RATE_MAX = 0.8;
|
||||
chassis_energy_part_param_.FAN_NON_ZERO_RATE_MIN = 0.48;
|
||||
// chassis_energy_part_param_.FAN_NON_ZERO_RATE_MAX = 0.3;
|
||||
// chassis_energy_part_param_.FAN_NON_ZERO_RATE_MIN = 0.16;
|
||||
|
||||
chassis_energy_part_param_.ARMOR_CONTOUR_AREA_MAX = 100000;
|
||||
chassis_energy_part_param_.ARMOR_CONTOUR_AREA_MIN = 0;
|
||||
@@ -175,6 +180,8 @@ void Energy::initEnergyPartParam() {
|
||||
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MIN = 0.25;
|
||||
chassis_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MAX = 0.48;
|
||||
chassis_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MIN = 0.25;
|
||||
// chassis_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MAX = 0.2;
|
||||
// chassis_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MIN = 0.08;
|
||||
|
||||
chassis_energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MAX = 100000;
|
||||
chassis_energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MIN = 0;
|
||||
|
||||
223
energy/src/energy/judge/judge_contour.cpp
Normal file
223
energy/src/energy/judge/judge_contour.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
//
|
||||
// Created by sun on 19-7-13.
|
||||
//
|
||||
|
||||
#include "energy/energy.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// 此函数用于判断找到的矩形候选区是否为扇叶
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
bool Energy::isValidFanContour(cv::Mat &src, const vector<cv::Point> &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_contour_area<<" "<<energy_fan_param_.CONTOUR_AREA_MIN<<" "<<energy_fan_param_.CONTOUR_AREA_MAX<<endl;
|
||||
//cout<<"area fail."<<endl;
|
||||
return false;
|
||||
//选区面积大小不合适
|
||||
}
|
||||
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;//将矩形的短边设置为宽
|
||||
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."<<endl;
|
||||
return false;
|
||||
//矩形边长不合适
|
||||
}
|
||||
float length_width_ratio = length / width;//计算矩形长宽比
|
||||
if (length_width_ratio > energy_part_param_.FAN_CONTOUR_HW_RATIO_MAX ||
|
||||
length_width_ratio < energy_part_param_.FAN_CONTOUR_HW_RATIO_MIN) {
|
||||
//cout<<"length width ratio fail."<<endl;
|
||||
return false;
|
||||
//长宽比不合适
|
||||
}
|
||||
// cout << cur_contour_area / cur_size.area() << endl;
|
||||
if (cur_contour_area / cur_size.area() < energy_part_param_.FAN_CONTOUR_AREA_RATIO_MIN) {
|
||||
// cout << cur_contour_area / cur_size.area() << endl;
|
||||
return false;//轮廓对矩形的面积占有率不合适
|
||||
}
|
||||
double non_zero_rate = nonZeroRateOfRotateRect(src, cur_rect);
|
||||
// cout << non_zero_rate<<endl;
|
||||
// if (non_zero_rate > 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<cv::Point> &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_contour_area<<" "<<energy_fan_param_.CONTOUR_AREA_MIN<<" "<<energy_fan_param_.CONTOUR_AREA_MAX<<endl;
|
||||
//cout<<"area fail."<<endl;
|
||||
return false;
|
||||
//选区面积大小不合适
|
||||
}
|
||||
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 < 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."<<endl;
|
||||
return false;
|
||||
//矩形边长不合适
|
||||
}
|
||||
|
||||
float length_width_ratio = length / width;//计算矩形长宽比
|
||||
if (length_width_ratio > energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MAX ||
|
||||
length_width_ratio < energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MIN) {
|
||||
//cout<<"length width ratio fail."<<endl;
|
||||
return false;
|
||||
//长宽比不合适
|
||||
}
|
||||
if (cur_contour_area / cur_size.area() < energy_part_param_.ARMOR_CONTOUR_AREA_RATIO_MIN)
|
||||
return false;//轮廓对矩形的面积占有率不合适
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// 此函数用于判断找到的矩形候选区是否为可能的风车中心R候选区
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
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) {
|
||||
//cout<<cur_contour_area<<" "<<energy_fan_param_.CONTOUR_AREA_MIN<<" "<<energy_fan_param_.CONTOUR_AREA_MAX<<endl;
|
||||
//cout<<"area fail."<<endl;
|
||||
return false;
|
||||
//选区面积大小不合适
|
||||
}
|
||||
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 < 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."<<endl;
|
||||
return false;
|
||||
//矩形边长不合适
|
||||
}
|
||||
float length_width_ratio = length / width;//计算矩形长宽比
|
||||
if (length_width_ratio > 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."<<endl;
|
||||
return false;
|
||||
//长宽比不合适
|
||||
}
|
||||
if (cur_contour_area / cur_size.area() < energy_part_param_.CENTER_R_CONTOUR_AREA_RATIO_MIN)
|
||||
return false;//轮廓对矩形的面积占有率不合适
|
||||
std::vector<cv::Point2f> 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<cv::Point> &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_contour_area<<" "<<energy_fan_param_.CONTOUR_AREA_MIN<<" "<<energy_fan_param_.CONTOUR_AREA_MAX<<endl;
|
||||
//cout<<"area fail."<<endl;
|
||||
return false;
|
||||
//选区面积大小不合适
|
||||
}
|
||||
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;//将矩形的短边设置为宽
|
||||
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."<<endl;
|
||||
return false;
|
||||
//矩形边长不合适
|
||||
}
|
||||
|
||||
float length_width_ratio = length / width;//计算矩形长宽比
|
||||
if (length_width_ratio > 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."<<endl;
|
||||
return false;
|
||||
//长宽比不合适
|
||||
}
|
||||
// cout << cur_contour_area / cur_size.area() << endl;
|
||||
if (cur_contour_area / cur_size.area() < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MIN
|
||||
|| cur_contour_area / cur_size.area() > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MAX) {
|
||||
return false;
|
||||
}
|
||||
// 轮廓对矩形的面积占有率不合适
|
||||
double non_zero_rate = nonZeroRateOfRotateRect(src, cur_rect);
|
||||
// cout<<non_zero_rate<<endl;
|
||||
// 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){
|
||||
// //cout<<non_zero_rate<<endl;
|
||||
// return false;
|
||||
// }
|
||||
//亮点占比不合格
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// 此函数用于判断找到的矩形候选区是否为流动条
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
bool Energy::isValidFlowStripContour(const vector<cv::Point> &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."<<endl;
|
||||
|
||||
return false;
|
||||
//选区面积大小不合适
|
||||
}
|
||||
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 < 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."<<endl;
|
||||
return false;
|
||||
//矩形边长不合适
|
||||
}
|
||||
float length_width_ratio = length / width;//计算矩形长宽比
|
||||
if (length_width_ratio > energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MAX ||
|
||||
length_width_ratio < energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MIN) {
|
||||
// cout<<"hw fail."<<endl;
|
||||
return false;
|
||||
//长宽比不合适
|
||||
}
|
||||
if (cur_contour_area / cur_size.area() < energy_part_param_.FLOW_STRIP_CONTOUR_AREA_RATIO_MIN)
|
||||
return false;//轮廓对矩形的面积占有率不合适
|
||||
std::vector<cv::Point2f> 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;
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
15
main.cpp
15
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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user