Merge remote-tracking branch 'origin/anti-top'
# Conflicts: # armor/src/armor_finder/send_target/send_target.cpp # energy/src/energy/clear/energy_init.cpp # energy/src/energy/find/energy_finder.cpp # energy/src/energy/judge/judge_contour.cpp # energy/src/energy/run.cpp # main.cpp # others/src/camera/camera_wrapper.cpp
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
#define _ARMOR_FINDER_H_
|
#define _ARMOR_FINDER_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <constants.h>
|
#include <constants.h>
|
||||||
#include <opencv2/core.hpp>
|
#include <opencv2/core.hpp>
|
||||||
#include <opencv2/tracking.hpp>
|
#include <opencv2/tracking.hpp>
|
||||||
@@ -13,30 +14,73 @@
|
|||||||
#include <armor_finder/classifier/classifier.h>
|
#include <armor_finder/classifier/classifier.h>
|
||||||
#include <additions/additions.h>
|
#include <additions/additions.h>
|
||||||
|
|
||||||
#define BLOB_RED ENEMY_RED
|
#define BLOB_RED ENEMY_RED
|
||||||
#define BLOB_BLUE ENEMY_BLUE
|
#define BLOB_BLUE ENEMY_BLUE
|
||||||
|
|
||||||
#define DISTANCE_HEIGHT_5MM (113.0) // 单位: m*pixel
|
#define BOX_RED ENEMY_RED
|
||||||
|
#define BOX_BLUE ENEMY_BLUE
|
||||||
|
|
||||||
|
#define DISTANCE_HEIGHT_5MM (107.0) // 单位: m*pixel
|
||||||
#define DISTANCE_HEIGHT DISTANCE_HEIGHT_5MM
|
#define DISTANCE_HEIGHT DISTANCE_HEIGHT_5MM
|
||||||
|
|
||||||
|
#define B1 1
|
||||||
|
#define B2 2
|
||||||
|
#define B3 3
|
||||||
|
#define B4 4
|
||||||
|
#define B5 5
|
||||||
|
#define B7 6
|
||||||
|
#define B8 7
|
||||||
|
#define R1 8
|
||||||
|
#define R2 9
|
||||||
|
#define R3 10
|
||||||
|
#define R4 11
|
||||||
|
#define R5 12
|
||||||
|
#define R7 13
|
||||||
|
#define R8 14
|
||||||
|
|
||||||
extern std::map<int, string> id2name; //装甲板id到名称的map
|
extern std::map<int, string> id2name; //装甲板id到名称的map
|
||||||
extern std::map<string, int> name2id; //装甲板名称到id的map
|
extern std::map<string, int> name2id; //装甲板名称到id的map
|
||||||
|
|
||||||
|
|
||||||
/******************* 灯条类定义 ***********************/
|
/******************* 灯条类定义 ***********************/
|
||||||
class LightBlob {
|
class LightBlob {
|
||||||
public:
|
public:
|
||||||
cv::RotatedRect rect; //灯条位置
|
cv::RotatedRect rect; //灯条位置
|
||||||
double length; //灯条长度
|
double length; //灯条长度
|
||||||
uint8_t BlobColor; //灯条颜色
|
uint8_t blob_color; //灯条颜色
|
||||||
|
|
||||||
LightBlob(cv::RotatedRect &r) : rect(r) {
|
LightBlob(cv::RotatedRect &r, uint8_t color) : rect(r), blob_color(color) {
|
||||||
length = max(rect.size.height, rect.size.width);
|
length = max(rect.size.height, rect.size.width);
|
||||||
};
|
};
|
||||||
|
LightBlob() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<LightBlob> LightBlobs;
|
typedef std::vector<LightBlob> LightBlobs;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************* 装甲板类定义 **********************/
|
||||||
|
class ArmorBox{
|
||||||
|
public:
|
||||||
|
typedef enum{
|
||||||
|
FRONT, SIDE, UNKNOWN
|
||||||
|
} BoxOrientation;
|
||||||
|
|
||||||
|
cv::Rect2d rect;
|
||||||
|
LightBlobs light_blobs;
|
||||||
|
uint8_t box_color;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
explicit ArmorBox(const cv::Rect &pos=cv::Rect2d(), const LightBlobs &blobs=LightBlobs(), uint8_t color=0, int i=0);
|
||||||
|
|
||||||
|
double blobsDistance() const;
|
||||||
|
double lengthRatio() const;
|
||||||
|
double lengthDistanceRatio() const;
|
||||||
|
double getDistance() const;
|
||||||
|
BoxOrientation getOrientation() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<ArmorBox> ArmorBoxes;
|
||||||
|
|
||||||
/********************* 自瞄类定义 **********************/
|
/********************* 自瞄类定义 **********************/
|
||||||
class ArmorFinder{
|
class ArmorFinder{
|
||||||
public:
|
public:
|
||||||
@@ -50,30 +94,36 @@ private:
|
|||||||
SEARCHING_STATE, TRACKING_STATE, STANDBY_STATE
|
SEARCHING_STATE, TRACKING_STATE, STANDBY_STATE
|
||||||
} State; // 自瞄状态枚举定义
|
} State; // 自瞄状态枚举定义
|
||||||
|
|
||||||
cv::Mat src_raw; // 当前原图
|
typedef enum{
|
||||||
|
NORMAL, ANTI_TOP
|
||||||
|
} AntiTopState;
|
||||||
|
|
||||||
const uint8_t &enemy_color; // 敌方颜色,引用外部变量,自动变化
|
const uint8_t &enemy_color; // 敌方颜色,引用外部变量,自动变化
|
||||||
State state; // 自瞄状态对象实例
|
State state; // 自瞄状态对象实例
|
||||||
cv::Rect2d armor_box; // 当前目标位置
|
ArmorBox armor_box; // 当前目标装甲板
|
||||||
int boxid; // 当前目标id
|
|
||||||
cv::Ptr<cv::Tracker> tracker; // tracker对象实例
|
cv::Ptr<cv::Tracker> tracker; // tracker对象实例
|
||||||
Classifier classifier; // CNN分类器对象实例,用于数字识别
|
Classifier classifier; // CNN分类器对象实例,用于数字识别
|
||||||
int contour_area; // 装甲区域亮点个数,用于数字识别未启用时判断是否跟丢(已弃用)
|
int contour_area; // 装甲区域亮点个数,用于数字识别未启用时判断是否跟丢(已弃用)
|
||||||
int tracking_cnt; // 记录追踪帧数,用于定时退出追踪
|
int tracking_cnt; // 记录追踪帧数,用于定时退出追踪
|
||||||
Serial &serial; // 串口对象,引用外部变量,用于和能量机关共享同一个变量
|
Serial &serial; // 串口对象,引用外部变量,用于和能量机关共享同一个变量
|
||||||
const uint8_t &use_classifier; // 标记是否启用CNN分类器,引用外部变量,自动变化
|
const uint8_t &use_classifier; // 标记是否启用CNN分类器,引用外部变量,自动变化
|
||||||
|
ArmorBox::BoxOrientation last_orient; // 上一帧目标装甲板方向,用于反陀螺
|
||||||
|
timeval last_front_time; // 上一次发生装甲板方向切换的时间
|
||||||
|
int anti_top_cnt; // 满足条件的装甲板方向切换持续次数,用于反陀螺
|
||||||
|
AntiTopState anti_top_state; // 当前是否识别到陀螺
|
||||||
|
|
||||||
|
bool findLightBlobs(const cv::Mat &src, LightBlobs &light_blobs);
|
||||||
|
bool findArmorBox(const cv::Mat &src, ArmorBox &box);
|
||||||
|
|
||||||
bool stateSearchingTarget(cv::Mat &src); // searching state主函数
|
bool stateSearchingTarget(cv::Mat &src); // searching state主函数
|
||||||
bool stateTrackingTarget(cv::Mat &src); // tracking state主函数
|
bool stateTrackingTarget(cv::Mat &src); // tracking state主函数
|
||||||
bool stateStandBy(); // stand by state主函数(已弃用)
|
bool stateStandBy(); // stand by state主函数(已弃用)
|
||||||
|
|
||||||
bool findLightBlobs(const cv::Mat &src_bin, // 在二值图上寻找灯条
|
void antiTop(); // 反小陀螺
|
||||||
LightBlobs &light_blobs);
|
|
||||||
bool findArmorBoxes(const LightBlobs &light_blobs, // 根据灯条匹配装甲板候选区
|
|
||||||
std::vector<cv::Rect2d> &armor_boxes);
|
|
||||||
public:
|
public:
|
||||||
void run(cv::Mat &src); // 自瞄主函数
|
void run(cv::Mat &src); // 自瞄主函数
|
||||||
bool sendBoxPosition(); // 和主控板通讯
|
bool sendBoxPosition(uint16_t shoot); // 和主控板通讯
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _ARMOR_FINDER_H_ */
|
#endif /* _ARMOR_FINDER_H_ */
|
||||||
|
|||||||
@@ -9,9 +9,10 @@
|
|||||||
#include <armor_finder/armor_finder.h>
|
#include <armor_finder/armor_finder.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
void showArmorBoxVector(std::string windows_name, const cv::Mat &src, const std::vector<cv::Rect2d> &armor_box);
|
void showArmorBoxes(std::string windows_name, const cv::Mat &src, const ArmorBoxes &armor_boxes);
|
||||||
void showArmorBox(std::string windows_name, const cv::Mat &src, cv::Rect2d armor_box, int boxid);
|
void showArmorBox(std::string windows_name, const cv::Mat &src, const ArmorBox &armor_box);
|
||||||
void showContours(std::string windows_name, const cv::Mat &src, const std::vector<LightBlob> &light_blobs);
|
void showLightBlobs(std::string windows_name, const cv::Mat &src, const LightBlobs &light_blobs);
|
||||||
void showArmorBoxClass(std::string window_names, const cv::Mat &src, vector<cv::Rect2d> boxes[10]);
|
void showArmorBoxesClass(std::string window_names, const cv::Mat &src, const ArmorBoxes boxes[15]);
|
||||||
|
void showTrackSearchingPos(std::string window_names, const cv::Mat &src, const cv::Rect2d pos);
|
||||||
|
|
||||||
#endif /* _SHOW_IMAGES_H_ */
|
#endif /* _SHOW_IMAGES_H_ */
|
||||||
|
|||||||
66
armor/src/armor_finder/anti_top/anti_top.cpp
Normal file
66
armor/src/armor_finder/anti_top/anti_top.cpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// Created by xinyang on 19-7-15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <armor_finder/armor_finder.h>
|
||||||
|
#include <log.h>
|
||||||
|
|
||||||
|
static double getTimeIntervalms(const timeval& now, const timeval &last){
|
||||||
|
return (now.tv_sec-last.tv_sec)*1000.0 + (now.tv_usec-last.tv_usec)/1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArmorFinder::antiTop() {
|
||||||
|
static double top_periodms = 0;
|
||||||
|
static double last_top_periodms = 0;
|
||||||
|
uint16_t shoot_delay = 0;
|
||||||
|
timeval curr_time;
|
||||||
|
// if(anti_top_state == ANTI_TOP){
|
||||||
|
// cout << "anti top" << endl;
|
||||||
|
// }else if(anti_top_state == NORMAL){
|
||||||
|
// cout << "Normal" << endl;
|
||||||
|
// }
|
||||||
|
gettimeofday(&curr_time, nullptr);
|
||||||
|
auto interval = getTimeIntervalms(curr_time, last_front_time);
|
||||||
|
if(interval > 700){
|
||||||
|
anti_top_state = NORMAL;
|
||||||
|
anti_top_cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArmorBox::BoxOrientation orientation = armor_box.getOrientation();
|
||||||
|
if(orientation == ArmorBox::UNKNOWN){
|
||||||
|
if(anti_top_state == NORMAL){
|
||||||
|
sendBoxPosition(shoot_delay);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(orientation!=last_orient && orientation==ArmorBox::FRONT){
|
||||||
|
last_front_time = curr_time;
|
||||||
|
if(150<interval && interval<700){
|
||||||
|
if(anti_top_state == ANTI_TOP){
|
||||||
|
last_top_periodms = top_periodms;
|
||||||
|
top_periodms = interval;
|
||||||
|
LOGM(STR_CTR(WORD_LIGHT_GREEN, "top period: %.1lf ms"), top_periodms);
|
||||||
|
shoot_delay = (last_top_periodms+top_periodms)/2.0-110;
|
||||||
|
last_orient = orientation;
|
||||||
|
}else if(anti_top_state == NORMAL){
|
||||||
|
// LOGM("interval:%.1lf", interval);
|
||||||
|
if(++anti_top_cnt > 4){
|
||||||
|
anti_top_state = ANTI_TOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(anti_top_state == ANTI_TOP){
|
||||||
|
if(orientation == ArmorBox::FRONT){
|
||||||
|
sendBoxPosition(shoot_delay);
|
||||||
|
}
|
||||||
|
}else if(anti_top_state == NORMAL){
|
||||||
|
sendBoxPosition(shoot_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
last_orient = orientation;
|
||||||
|
}
|
||||||
|
|
||||||
81
armor/src/armor_finder/armor_box/armor_box.cpp
Normal file
81
armor/src/armor_finder/armor_box/armor_box.cpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
//
|
||||||
|
// Created by xinyang on 19-7-13.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <armor_finder/armor_finder.h>
|
||||||
|
#include <log.h>
|
||||||
|
|
||||||
|
ArmorBox::ArmorBox(const cv::Rect &pos, const LightBlobs &blobs, uint8_t color, int i) :
|
||||||
|
rect(pos), light_blobs(blobs), box_color(color), id(i){};
|
||||||
|
|
||||||
|
double ArmorBox::blobsDistance() const{
|
||||||
|
if(light_blobs.size() == 2){
|
||||||
|
auto &x = light_blobs[0].rect.center;
|
||||||
|
auto &y = light_blobs[1].rect.center;
|
||||||
|
return sqrt((x.x-y.x)*(x.x-y.x) + (x.y-y.y)*(x.y-y.y));
|
||||||
|
}else{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double ArmorBox::lengthRatio() const{
|
||||||
|
if(light_blobs.size() == 2){
|
||||||
|
return light_blobs[0].length / light_blobs[1].length < 1 ?
|
||||||
|
(light_blobs[0].length / light_blobs[1].length) :
|
||||||
|
(light_blobs[1].length / light_blobs[0].length);
|
||||||
|
}else{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double ArmorBox::lengthDistanceRatio() const {
|
||||||
|
if(light_blobs.size() == 2){
|
||||||
|
return max(light_blobs[0].length, light_blobs[1].length)
|
||||||
|
/ blobsDistance();
|
||||||
|
}else{
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double ArmorBox::getDistance() const{
|
||||||
|
if(light_blobs.size() == 2 ){
|
||||||
|
return DISTANCE_HEIGHT / 2 / max(light_blobs[0].length, light_blobs[1].length);
|
||||||
|
} else {
|
||||||
|
return DISTANCE_HEIGHT / rect.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ArmorBox::BoxOrientation ArmorBox::getOrientation() const{
|
||||||
|
// cout << lengthDistanceRatio() << endl;
|
||||||
|
if(light_blobs.size() != 2){
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
switch (id) {
|
||||||
|
case R1:
|
||||||
|
case R7:
|
||||||
|
case R8:
|
||||||
|
case B1:
|
||||||
|
case B7:
|
||||||
|
case B8:
|
||||||
|
if(lengthDistanceRatio() < 0.24){
|
||||||
|
return FRONT;
|
||||||
|
}else{
|
||||||
|
return SIDE;
|
||||||
|
}
|
||||||
|
case R2:
|
||||||
|
case R3:
|
||||||
|
case R4:
|
||||||
|
case R5:
|
||||||
|
case B2:
|
||||||
|
case B3:
|
||||||
|
case B4:
|
||||||
|
case B5:
|
||||||
|
if (lengthDistanceRatio() < 0.48) {
|
||||||
|
return FRONT;
|
||||||
|
}else{
|
||||||
|
return SIDE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,32 +42,25 @@ ArmorFinder::ArmorFinder(uint8_t &color, Serial &u, const string ¶s_folder,
|
|||||||
classifier(paras_folder),
|
classifier(paras_folder),
|
||||||
contour_area(0),
|
contour_area(0),
|
||||||
use_classifier(use),
|
use_classifier(use),
|
||||||
boxid(-1),
|
|
||||||
tracking_cnt(0) {
|
tracking_cnt(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArmorFinder::run(cv::Mat &src) {
|
void ArmorFinder::run(cv::Mat &src) {
|
||||||
src_raw = src;
|
// stateSearchingTarget(src); // for debug
|
||||||
cv::Mat src_use = src.clone(); // 实际参与计算的图像对象
|
// goto end;
|
||||||
|
|
||||||
if (show_armor_box) { // 根据条件显示当前目标装甲板
|
|
||||||
showArmorBox("box", src, armor_box, boxid);
|
|
||||||
cv::waitKey(1);
|
|
||||||
}
|
|
||||||
// stateSearchingTarget(src_use); // for debug
|
|
||||||
// return;
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case SEARCHING_STATE:
|
case SEARCHING_STATE:
|
||||||
if (stateSearchingTarget(src_use)) {
|
if (stateSearchingTarget(src)) {
|
||||||
if ((armor_box & cv::Rect2d(0, 0, 640, 480)) == armor_box) { // 判断装甲板区域是否脱离图像区域
|
// cout << armor_box.rect << endl;
|
||||||
|
if ((armor_box.rect & cv::Rect2d(0, 0, 640, 480)) == armor_box.rect) { // 判断装甲板区域是否脱离图像区域
|
||||||
if (!classifier || !use_classifier) { /* 如果分类器不可用或者不使用分类器 */
|
if (!classifier || !use_classifier) { /* 如果分类器不可用或者不使用分类器 */
|
||||||
cv::Mat roi = src_use.clone()(armor_box), roi_gray; /* 就使用装甲区域亮点数判断是否跟丢 */
|
cv::Mat roi = src(armor_box.rect).clone(), roi_gray; /* 就使用装甲区域亮点数判断是否跟丢 */
|
||||||
cv::cvtColor(roi, roi_gray, CV_RGB2GRAY);
|
cv::cvtColor(roi, roi_gray, CV_RGB2GRAY);
|
||||||
cv::threshold(roi_gray, roi_gray, 180, 255, cv::THRESH_BINARY);
|
cv::threshold(roi_gray, roi_gray, 180, 255, cv::THRESH_BINARY);
|
||||||
contour_area = cv::countNonZero(roi_gray);
|
contour_area = cv::countNonZero(roi_gray);
|
||||||
}
|
}
|
||||||
tracker = TrackerToUse::create(); // 成功搜寻到装甲板,创建tracker对象
|
tracker = TrackerToUse::create(); // 成功搜寻到装甲板,创建tracker对象
|
||||||
tracker->init(src_use, armor_box);
|
tracker->init(src, armor_box.rect);
|
||||||
state = TRACKING_STATE;
|
state = TRACKING_STATE;
|
||||||
tracking_cnt = 0;
|
tracking_cnt = 0;
|
||||||
LOGM(STR_CTR(WORD_LIGHT_CYAN, "into track"));
|
LOGM(STR_CTR(WORD_LIGHT_CYAN, "into track"));
|
||||||
@@ -75,7 +68,7 @@ void ArmorFinder::run(cv::Mat &src) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TRACKING_STATE:
|
case TRACKING_STATE:
|
||||||
if (!stateTrackingTarget(src_use) || ++tracking_cnt > 100) { // 最多追踪100帧图像
|
if (!stateTrackingTarget(src) || ++tracking_cnt > 100) { // 最多追踪100帧图像
|
||||||
state = SEARCHING_STATE;
|
state = SEARCHING_STATE;
|
||||||
LOGM(STR_CTR(WORD_LIGHT_YELLOW, "into search!"));
|
LOGM(STR_CTR(WORD_LIGHT_YELLOW, "into search!"));
|
||||||
}
|
}
|
||||||
@@ -84,5 +77,12 @@ void ArmorFinder::run(cv::Mat &src) {
|
|||||||
default:
|
default:
|
||||||
stateStandBy();
|
stateStandBy();
|
||||||
}
|
}
|
||||||
|
end:
|
||||||
|
antiTop();
|
||||||
|
|
||||||
|
if (show_armor_box) { // 根据条件显示当前目标装甲板
|
||||||
|
showArmorBox("box", src, armor_box);
|
||||||
|
cv::waitKey(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
201
armor/src/armor_finder/find/find_armor_box.cpp
Normal file
201
armor/src/armor_finder/find/find_armor_box.cpp
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
//
|
||||||
|
// Created by xinyang on 19-7-18.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <armor_finder/armor_finder.h>
|
||||||
|
#include <show_images/show_images.h>
|
||||||
|
#include <options/options.h>
|
||||||
|
#include <opencv2/highgui.hpp>
|
||||||
|
#include <log.h>
|
||||||
|
|
||||||
|
static string prior_blue[] = {
|
||||||
|
"B8", "B1", "B3", "B4", "B5", "B7", "B2",
|
||||||
|
"R8", "R1", "R3", "R4", "R5", "R7", "R2",
|
||||||
|
};
|
||||||
|
|
||||||
|
static string prior_red[] = {
|
||||||
|
"R8", "R1", "R3", "R4", "R5", "R7", "R2",
|
||||||
|
"B8", "B1", "B3", "B4", "B5", "B7", "B2",
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool angelJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
||||||
|
float angle_i = light_blob_i.rect.size.width > light_blob_i.rect.size.height ? light_blob_i.rect.angle :
|
||||||
|
light_blob_i.rect.angle - 90;
|
||||||
|
float angle_j = light_blob_j.rect.size.width > light_blob_j.rect.size.height ? light_blob_j.rect.angle :
|
||||||
|
light_blob_j.rect.angle - 90;
|
||||||
|
return abs(angle_i - angle_j) < 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool heightJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
||||||
|
cv::Point2f centers = light_blob_i.rect.center - light_blob_j.rect.center;
|
||||||
|
return abs(centers.y) < 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool lengthJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
||||||
|
double side_length;
|
||||||
|
cv::Point2f centers = light_blob_i.rect.center - light_blob_j.rect.center;
|
||||||
|
side_length = sqrt(centers.ddot(centers));
|
||||||
|
return (side_length / light_blob_i.length < 8 && side_length / light_blob_i.length > 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool lengthRatioJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
||||||
|
return (light_blob_i.length / light_blob_j.length < 2.5
|
||||||
|
&& light_blob_i.length / light_blob_j.length > 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 判断两个灯条的错位度,不知道英文是什么!!! */
|
||||||
|
static bool CuoWeiDuJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
||||||
|
float angle_i = light_blob_i.rect.size.width > light_blob_i.rect.size.height ? light_blob_i.rect.angle :
|
||||||
|
light_blob_i.rect.angle - 90;
|
||||||
|
float angle_j = light_blob_j.rect.size.width > light_blob_j.rect.size.height ? light_blob_j.rect.angle :
|
||||||
|
light_blob_j.rect.angle - 90;
|
||||||
|
float angle = (angle_i + angle_j) / 2.0 / 180.0 * 3.14159265459;
|
||||||
|
if (abs(angle_i - angle_j) > 90) {
|
||||||
|
angle += 3.14159265459 / 2;
|
||||||
|
}
|
||||||
|
Vector2f orientation(cos(angle), sin(angle));
|
||||||
|
Vector2f p2p(light_blob_j.rect.center.x - light_blob_i.rect.center.x,
|
||||||
|
light_blob_j.rect.center.y - light_blob_i.rect.center.y);
|
||||||
|
return abs(orientation.dot(p2p)) < 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool boxAngleJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
||||||
|
float angle_i = light_blob_i.rect.size.width > light_blob_i.rect.size.height ? light_blob_i.rect.angle :
|
||||||
|
light_blob_i.rect.angle - 90;
|
||||||
|
float angle_j = light_blob_j.rect.size.width > light_blob_j.rect.size.height ? light_blob_j.rect.angle :
|
||||||
|
light_blob_j.rect.angle - 90;
|
||||||
|
float angle = (angle_i + angle_j) / 2.0;
|
||||||
|
if (abs(angle_i - angle_j) > 90) {
|
||||||
|
angle += 90.0;
|
||||||
|
}
|
||||||
|
return (-120.0 < angle && angle < -60.0) || (60.0 < angle && angle < 120.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isCoupleLight(const LightBlob &light_blob_i, const LightBlob &light_blob_j, uint8_t enemy_color) {
|
||||||
|
return light_blob_i.blob_color == enemy_color &&
|
||||||
|
light_blob_j.blob_color == enemy_color &&
|
||||||
|
lengthRatioJudge(light_blob_i, light_blob_j) &&
|
||||||
|
lengthJudge(light_blob_i, light_blob_j) &&
|
||||||
|
// heightJudge(light_blob_i, light_blob_j) &&
|
||||||
|
angelJudge(light_blob_i, light_blob_j) &&
|
||||||
|
boxAngleJudge(light_blob_i, light_blob_j) &&
|
||||||
|
CuoWeiDuJudge(light_blob_i, light_blob_j);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static double centerDistance(const cv::Rect2d &box) {
|
||||||
|
double dx = box.x - box.width / 2 - 320;
|
||||||
|
double dy = box.y - box.height / 2 - 240;
|
||||||
|
return dx * dx + dy * dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matchArmorBoxes(const cv::Mat &src, const LightBlobs &light_blobs, ArmorBoxes &armor_boxes, uint8_t color) {
|
||||||
|
armor_boxes.clear();
|
||||||
|
for (int i = 0; i < light_blobs.size() - 1; ++i) {
|
||||||
|
for (int j = i + 1; j < light_blobs.size(); ++j) {
|
||||||
|
if (!isCoupleLight(light_blobs.at(i), light_blobs.at(j), color)) {
|
||||||
|
// cout << "match fail" << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cv::Rect2d rect_left = light_blobs.at(static_cast<unsigned long>(i)).rect.boundingRect();
|
||||||
|
cv::Rect2d rect_right = light_blobs.at(static_cast<unsigned long>(j)).rect.boundingRect();
|
||||||
|
double min_x, min_y, max_x, max_y;
|
||||||
|
min_x = fmin(rect_left.x, rect_right.x) - 4;
|
||||||
|
max_x = fmax(rect_left.x + rect_left.width, rect_right.x + rect_right.width) + 4;
|
||||||
|
min_y = fmin(rect_left.y, rect_right.y) - 0.5 * (rect_left.height + rect_right.height) / 2.0;
|
||||||
|
max_y = fmax(rect_left.y + rect_left.height, rect_right.y + rect_right.height) +
|
||||||
|
0.5 * (rect_left.height + rect_right.height) / 2.0;
|
||||||
|
if (min_x < 0 || max_x > src.cols || min_y < 0 || max_y > src.rows) {
|
||||||
|
// cout << "out of range" << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LightBlobs pair_blobs = {light_blobs.at(i), light_blobs.at(j)};
|
||||||
|
armor_boxes.emplace_back(
|
||||||
|
cv::Rect2d(min_x, min_y, max_x - min_x, max_y - min_y),
|
||||||
|
pair_blobs,
|
||||||
|
color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (armor_boxes.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sort(armor_boxes.begin(), armor_boxes.end(), [](ArmorBox box1, ArmorBox box2) -> bool {
|
||||||
|
return centerDistance(box1.rect) < centerDistance(box2.rect);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmorFinder::findArmorBox(const cv::Mat &src, ArmorBox &box){
|
||||||
|
LightBlobs light_blobs; // 存储所有可能的灯条
|
||||||
|
ArmorBoxes armor_boxes; // 装甲板候选区
|
||||||
|
ArmorBoxes boxes_number[15]; // 装甲板候选区放置在对应id位置
|
||||||
|
|
||||||
|
box.rect = cv::Rect2d(0,0,0,0);
|
||||||
|
box.id = -1;
|
||||||
|
|
||||||
|
if (!findLightBlobs(src, light_blobs)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (show_light_blobs && src.size()==cv::Size(640, 480)) {
|
||||||
|
showLightBlobs("light_blobs", src, light_blobs);
|
||||||
|
cv::waitKey(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matchArmorBoxes(src, light_blobs, armor_boxes, enemy_color)) {
|
||||||
|
// cout << "Box fail!" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (show_armor_boxes && src.size()==cv::Size(640, 480)) {
|
||||||
|
showArmorBoxes("boxes", src, armor_boxes);
|
||||||
|
cv::waitKey(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classifier && use_classifier) {
|
||||||
|
for (auto &armor_box : armor_boxes) {
|
||||||
|
cv::Mat roi = src(armor_box.rect).clone();
|
||||||
|
cv::resize(roi, roi, cv::Size(48, 36));
|
||||||
|
int c = classifier(roi);
|
||||||
|
armor_box.id = c;
|
||||||
|
boxes_number[c].emplace_back(armor_box);
|
||||||
|
}
|
||||||
|
if (enemy_color == ENEMY_BLUE) {
|
||||||
|
for (auto &name : prior_blue) {
|
||||||
|
if (!boxes_number[name2id[name]].empty()) {
|
||||||
|
box = boxes_number[name2id[name]][0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (enemy_color == ENEMY_RED) {
|
||||||
|
for (auto &name : prior_red) {
|
||||||
|
if (!boxes_number[name2id[name]].empty()) {
|
||||||
|
box = boxes_number[name2id[name]][0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOGE_INFO("enemy_color ERROR!");
|
||||||
|
}
|
||||||
|
if (save_labelled_boxes) {
|
||||||
|
for (int i = 0; i < sizeof(boxes_number) / sizeof(boxes_number[0]); i++) {
|
||||||
|
for (auto &armor_box : boxes_number[i]) {
|
||||||
|
char filename[100];
|
||||||
|
sprintf(filename, PROJECT_DIR"/armor_box_photo/%s_%d.jpg", id2name[i].data(),
|
||||||
|
time(nullptr) + clock());
|
||||||
|
cv::imwrite(filename, src(armor_box.rect));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (box.rect == cv::Rect2d(0, 0, 0, 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (show_armor_boxes && src.size()==cv::Size(640, 480)) {
|
||||||
|
showArmorBoxesClass("class", src, boxes_number);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
box = armor_boxes[0];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
157
armor/src/armor_finder/find/find_light_blobs.cpp
Normal file
157
armor/src/armor_finder/find/find_light_blobs.cpp
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
//
|
||||||
|
// Created by xinyang on 19-7-10.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <armor_finder/armor_finder.h>
|
||||||
|
#include <options/options.h>
|
||||||
|
#include <opencv2/highgui.hpp>
|
||||||
|
|
||||||
|
static double lw_rate(const cv::RotatedRect &rect) {
|
||||||
|
return rect.size.height > rect.size.width ?
|
||||||
|
rect.size.height / rect.size.width :
|
||||||
|
rect.size.width / rect.size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static double areaRatio(const std::vector<cv::Point> &contour, const cv::RotatedRect &rect){
|
||||||
|
return cv::contourArea(contour) / rect.size.area();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isValidLightBlob(const std::vector<cv::Point> &contour, const cv::RotatedRect &rect) {
|
||||||
|
return (1.5 < lw_rate(rect) && lw_rate(rect) < 10) &&
|
||||||
|
// (rect.size.area() < 3000) &&
|
||||||
|
((rect.size.area() < 50 && areaRatio(contour, rect) > 0.4) ||
|
||||||
|
(rect.size.area() >= 50 && areaRatio(contour, rect) > 0.6));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 此函数可以有性能优化.
|
||||||
|
static uint8_t get_blob_color(const cv::Mat &src, const cv::RotatedRect &blobPos) {
|
||||||
|
auto region = blobPos.boundingRect();
|
||||||
|
region.x -= fmax(2, region.width * 0.1);
|
||||||
|
region.y -= fmax(2, region.height * 0.05);
|
||||||
|
region.width += 2 * fmax(2, region.width * 0.1);
|
||||||
|
region.height += 2 * fmax(2, region.height * 0.05);
|
||||||
|
region &= cv::Rect(0, 0, src.cols, src.rows);
|
||||||
|
cv::Mat roi = src(region);
|
||||||
|
int red_cnt = 0, blue_cnt = 0;
|
||||||
|
for (int row = 0; row < roi.rows; row++) {
|
||||||
|
for (int col = 0; col < roi.cols; col++) {
|
||||||
|
red_cnt += roi.at<cv::Vec3b>(row, col)[2];
|
||||||
|
blue_cnt += roi.at<cv::Vec3b>(row, col)[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (red_cnt > blue_cnt) {
|
||||||
|
return BLOB_RED;
|
||||||
|
} else {
|
||||||
|
return BLOB_BLUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static float linePointX(const cv::Point2f &p1, const cv::Point2f &p2, int y) {
|
||||||
|
return (p2.x - p1.x) / (p2.y - p1.y) * (y - p1.y) + p1.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Todo:性能优化后的函数(还有点问题)
|
||||||
|
static double get_blob_color_opt(const cv::Mat &src, cv::RotatedRect blobPos) {
|
||||||
|
int blue_cnt=0, red_cnt=0;
|
||||||
|
blobPos.size.height *= 1.05;
|
||||||
|
blobPos.size.width *= 1.1;
|
||||||
|
cv::Point2f corners[4];
|
||||||
|
blobPos.points(corners);
|
||||||
|
sort(corners, &corners[4], [](cv::Point2f p1, cv::Point2f p2) {
|
||||||
|
return p1.y < p2.y;
|
||||||
|
});
|
||||||
|
for (int r = corners[0].y; r < corners[1].y; r++) {
|
||||||
|
auto start = min(linePointX(corners[0], corners[1], r), linePointX(corners[0], corners[2], r)) - 1;
|
||||||
|
auto end = max(linePointX(corners[0], corners[1], r), linePointX(corners[0], corners[2], r)) + 1;
|
||||||
|
if (start < 0 || end > 640) return 0;
|
||||||
|
for (int c = start; c < end; c++) {
|
||||||
|
red_cnt += src.at<cv::Vec3b>(r, c)[2];
|
||||||
|
blue_cnt += src.at<cv::Vec3b>(r, c)[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int r = corners[1].y; r < corners[2].y; r++) {
|
||||||
|
auto start = min(linePointX(corners[0], corners[2], r), linePointX(corners[1], corners[3], r)) - 1;
|
||||||
|
auto end = max(linePointX(corners[0], corners[2], r), linePointX(corners[1], corners[3], r)) + 1;
|
||||||
|
if (start < 0 || end > 640) return 0;
|
||||||
|
for (int c = start; c < end; c++) {
|
||||||
|
red_cnt += src.at<cv::Vec3b>(r, c)[2];
|
||||||
|
blue_cnt += src.at<cv::Vec3b>(r, c)[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int r = corners[2].y; r < corners[3].y; r++) {
|
||||||
|
auto start = min(linePointX(corners[1], corners[3], r), linePointX(corners[2], corners[3], r)) - 1;
|
||||||
|
auto end = max(linePointX(corners[1], corners[3], r), linePointX(corners[2], corners[3], r)) + 1;
|
||||||
|
if (start < 0 || end > 640) return 0;
|
||||||
|
for (int c = start; c < end; c++) {
|
||||||
|
red_cnt += src.at<cv::Vec3b>(r, c)[2];
|
||||||
|
blue_cnt += src.at<cv::Vec3b>(r, c)[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (red_cnt > blue_cnt) {
|
||||||
|
return BLOB_RED;
|
||||||
|
} else {
|
||||||
|
return BLOB_BLUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void imagePreProcess(cv::Mat &src) {
|
||||||
|
static cv::Mat kernel_erode = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 5));
|
||||||
|
erode(src, src, kernel_erode);
|
||||||
|
|
||||||
|
static cv::Mat kernel_dilate = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 5));
|
||||||
|
dilate(src, src, kernel_dilate);
|
||||||
|
|
||||||
|
static cv::Mat kernel_dilate2 = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 5));
|
||||||
|
dilate(src, src, kernel_dilate2);
|
||||||
|
|
||||||
|
static cv::Mat kernel_erode2 = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 5));
|
||||||
|
erode(src, src, kernel_erode2);
|
||||||
|
|
||||||
|
// float alpha = 1.5;
|
||||||
|
// int beta = 0;
|
||||||
|
// src.convertTo(src, -1, alpha, beta);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmorFinder::findLightBlobs(const cv::Mat &src, LightBlobs &light_blobs) {
|
||||||
|
cv::Mat color_channel;
|
||||||
|
cv::Mat src_bin_light, src_bin_dim;
|
||||||
|
std::vector<cv::Mat> channels; // 通道拆分
|
||||||
|
|
||||||
|
cv::split(src, channels); /************************/
|
||||||
|
if (enemy_color == ENEMY_BLUE){ /* */
|
||||||
|
color_channel = channels[0]; /* 根据目标颜色进行通道提取 */
|
||||||
|
}else if (enemy_color == ENEMY_RED){ /* */
|
||||||
|
color_channel = channels[2]; /************************/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cv::threshold(color_channel, src_bin_light, 200, 255, CV_THRESH_BINARY); // 二值化对应通道
|
||||||
|
imagePreProcess(src_bin_light); // 开闭运算
|
||||||
|
|
||||||
|
cv::threshold(color_channel, src_bin_dim, 160, 255, CV_THRESH_BINARY); // 二值化对应通道
|
||||||
|
imagePreProcess(src_bin_dim); // 开闭运算
|
||||||
|
|
||||||
|
if(src_bin_light.size() == cv::Size(640, 480) && show_light_blobs) {
|
||||||
|
imshow("bin_light", src_bin_light);
|
||||||
|
imshow("bin_dim", src_bin_dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::vector<cv::Point> > light_contours_light, light_contours_dim;
|
||||||
|
cv::findContours(src_bin_light, light_contours_light, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
|
||||||
|
cv::findContours(src_bin_dim, light_contours_dim, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
|
||||||
|
for (auto &light_contour : light_contours_light) {
|
||||||
|
cv::RotatedRect rect = cv::minAreaRect(light_contour);
|
||||||
|
if (isValidLightBlob(light_contour, rect)) {
|
||||||
|
light_blobs.emplace_back(rect, get_blob_color(src, rect));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto &light_contour : light_contours_dim) {
|
||||||
|
cv::RotatedRect rect = cv::minAreaRect(light_contour);
|
||||||
|
if (isValidLightBlob(light_contour, rect)) {
|
||||||
|
light_blobs.emplace_back(rect, get_blob_color(src, rect));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return light_blobs.size() >= 2;
|
||||||
|
}
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by xinyang on 19-7-10.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <armor_finder/armor_finder.h>
|
|
||||||
|
|
||||||
static bool angelJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
|
||||||
float angle_i = light_blob_i.rect.size.width > light_blob_i.rect.size.height ? light_blob_i.rect.angle :
|
|
||||||
light_blob_i.rect.angle - 90;
|
|
||||||
float angle_j = light_blob_j.rect.size.width > light_blob_j.rect.size.height ? light_blob_j.rect.angle :
|
|
||||||
light_blob_j.rect.angle - 90;
|
|
||||||
return abs(angle_i - angle_j) < 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool heightJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
|
||||||
cv::Point2f centers = light_blob_i.rect.center - light_blob_j.rect.center;
|
|
||||||
return abs(centers.y) < 30;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool lengthJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
|
||||||
double side_length;
|
|
||||||
cv::Point2f centers = light_blob_i.rect.center - light_blob_j.rect.center;
|
|
||||||
side_length = sqrt(centers.ddot(centers));
|
|
||||||
return (side_length / light_blob_i.length < 6 && side_length / light_blob_i.length > 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool lengthRatioJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
|
||||||
return (light_blob_i.length / light_blob_j.length < 2
|
|
||||||
&& light_blob_i.length / light_blob_j.length > 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 判断两个灯条的错位度,不知道英文是什么!!! */
|
|
||||||
static bool CuoWeiDuJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
|
||||||
float angle_i = light_blob_i.rect.size.width > light_blob_i.rect.size.height ? light_blob_i.rect.angle :
|
|
||||||
light_blob_i.rect.angle - 90;
|
|
||||||
float angle_j = light_blob_j.rect.size.width > light_blob_j.rect.size.height ? light_blob_j.rect.angle :
|
|
||||||
light_blob_j.rect.angle - 90;
|
|
||||||
float angle = (angle_i + angle_j) / 2.0 / 180.0 * 3.14159265459;
|
|
||||||
if (abs(angle_i - angle_j) > 90) {
|
|
||||||
angle += 3.14159265459 / 2;
|
|
||||||
}
|
|
||||||
Vector2f orientation(cos(angle), sin(angle));
|
|
||||||
Vector2f p2p(light_blob_j.rect.center.x - light_blob_i.rect.center.x,
|
|
||||||
light_blob_j.rect.center.y - light_blob_i.rect.center.y);
|
|
||||||
return abs(orientation.dot(p2p)) < 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool boxAngleJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
|
||||||
float angle_i = light_blob_i.rect.size.width > light_blob_i.rect.size.height ? light_blob_i.rect.angle :
|
|
||||||
light_blob_i.rect.angle - 90;
|
|
||||||
float angle_j = light_blob_j.rect.size.width > light_blob_j.rect.size.height ? light_blob_j.rect.angle :
|
|
||||||
light_blob_j.rect.angle - 90;
|
|
||||||
float angle = (angle_i + angle_j) / 2.0;
|
|
||||||
if (abs(angle_i - angle_j) > 90) {
|
|
||||||
angle += 90.0;
|
|
||||||
}
|
|
||||||
return (-120.0 < angle && angle < -60.0) || (60.0 < angle && angle < 120.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isCoupleLight(const LightBlob &light_blob_i, const LightBlob &light_blob_j, uint8_t enemy_color) {
|
|
||||||
return light_blob_i.BlobColor == enemy_color &&
|
|
||||||
light_blob_j.BlobColor == enemy_color &&
|
|
||||||
lengthRatioJudge(light_blob_i, light_blob_j) &&
|
|
||||||
lengthJudge(light_blob_i, light_blob_j) &&
|
|
||||||
// heightJudge(light_blob_i, light_blob_j) &&
|
|
||||||
angelJudge(light_blob_i, light_blob_j) &&
|
|
||||||
boxAngleJudge(light_blob_i, light_blob_j) &&
|
|
||||||
CuoWeiDuJudge(light_blob_i, light_blob_j);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static double centerDistance(const cv::Rect2d &box) {
|
|
||||||
double dx = box.x - box.width / 2 - 320;
|
|
||||||
double dy = box.y - box.height / 2 - 240;
|
|
||||||
return dx * dx + dy * dy;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ArmorFinder::findArmorBoxes(const LightBlobs &light_blobs, std::vector<cv::Rect2d> &armor_boxes) {
|
|
||||||
for (int i = 0; i < light_blobs.size() - 1; ++i) {
|
|
||||||
for (int j = i + 1; j < light_blobs.size(); ++j) {
|
|
||||||
if (!isCoupleLight(light_blobs.at(i), light_blobs.at(j), enemy_color)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cv::Rect2d rect_left = light_blobs.at(static_cast<unsigned long>(i)).rect.boundingRect();
|
|
||||||
cv::Rect2d rect_right = light_blobs.at(static_cast<unsigned long>(j)).rect.boundingRect();
|
|
||||||
double min_x, min_y, max_x, max_y;
|
|
||||||
min_x = fmin(rect_left.x, rect_right.x) - 4;
|
|
||||||
max_x = fmax(rect_left.x + rect_left.width, rect_right.x + rect_right.width) + 4;
|
|
||||||
min_y = fmin(rect_left.y, rect_right.y) - 0.5 * (rect_left.height + rect_right.height) / 2.0;
|
|
||||||
max_y = fmax(rect_left.y + rect_left.height, rect_right.y + rect_right.height) +
|
|
||||||
0.5 * (rect_left.height + rect_right.height) / 2.0;
|
|
||||||
if (min_x < 0 || max_x > 640 || min_y < 0 || max_y > 480) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
armor_boxes.emplace_back(cv::Rect2d(min_x, min_y, max_x - min_x, max_y - min_y));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (armor_boxes.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
sort(armor_boxes.begin(), armor_boxes.end(), [](cv::Rect2d box1, cv::Rect2d box2) -> bool {
|
|
||||||
return centerDistance(box1) < centerDistance(box2);
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by xinyang on 19-7-10.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <armor_finder/armor_finder.h>
|
|
||||||
|
|
||||||
static double lw_rate(const cv::RotatedRect &rect) {
|
|
||||||
return rect.size.height > rect.size.width ?
|
|
||||||
rect.size.height / rect.size.width :
|
|
||||||
rect.size.width / rect.size.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool rectangleContainPoint(cv::RotatedRect rectangle, cv::Point2f point) {
|
|
||||||
//转化为轮廓
|
|
||||||
cv::Point2f corners[4];
|
|
||||||
rectangle.points(corners);
|
|
||||||
cv::Point2f *lastItemPointer = (corners + sizeof corners / sizeof corners[0]);
|
|
||||||
vector<cv::Point2f> contour(corners, lastItemPointer);
|
|
||||||
//判断
|
|
||||||
double indicator = pointPolygonTest(contour, point, true);
|
|
||||||
return indicator >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 下面的函数可以有性能优化,暂时未做。
|
|
||||||
static double nonZeroRateOfRotateRect(const cv::Mat &bin, const cv::RotatedRect &rotrect) {
|
|
||||||
auto rect = rotrect.boundingRect();
|
|
||||||
if (rect.x < 0 || rect.y < 0 || rect.x + rect.width > bin.cols || rect.y + rect.height > bin.rows) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
auto roi = bin(rect);
|
|
||||||
int cnt = 0;
|
|
||||||
for (int r = 0; r < roi.rows; r++) {
|
|
||||||
for (int c = 0; c < roi.cols; c++) {
|
|
||||||
if (rectangleContainPoint(rotrect, cv::Point(c + rect.x, r + rect.y))) {
|
|
||||||
if (roi.at<uint8_t>(r, c)) {
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return double(cnt) / rotrect.size.area();
|
|
||||||
}
|
|
||||||
|
|
||||||
int linePointX(const cv::Point2f &p1, const cv::Point2f &p2, int y) {
|
|
||||||
return (p2.x - p1.x) / (p2.y - p1.y) * (y - p1.y) + p1.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 性能优化后的函数
|
|
||||||
static double nonZeroRateOfRotateRect_opt(const cv::Mat &bin, const cv::RotatedRect &rotrect) {
|
|
||||||
int cnt = 0;
|
|
||||||
cv::Point2f corners[4];
|
|
||||||
rotrect.points(corners);
|
|
||||||
sort(corners, &corners[4], [](cv::Point2f p1, cv::Point2f p2) {
|
|
||||||
return p1.y < p2.y;
|
|
||||||
});
|
|
||||||
for (int r = corners[0].y; r < corners[1].y; r++) {
|
|
||||||
auto start = min(linePointX(corners[0], corners[1], r), linePointX(corners[0], corners[2], r)) - 1;
|
|
||||||
auto end = max(linePointX(corners[0], corners[1], r), linePointX(corners[0], corners[2], r)) + 1;
|
|
||||||
if (start < 0 || end > 640) return 0;
|
|
||||||
for (int c = start; c < end; c++) {
|
|
||||||
if (bin.at<uint8_t>(r, c)) {
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int r = corners[1].y; r < corners[2].y; r++) {
|
|
||||||
auto start = min(linePointX(corners[0], corners[2], r), linePointX(corners[1], corners[3], r)) - 1;
|
|
||||||
auto end = max(linePointX(corners[0], corners[2], r), linePointX(corners[1], corners[3], r)) + 1;
|
|
||||||
if (start < 0 || end > 640) return 0;
|
|
||||||
for (int c = start; c < end; c++) {
|
|
||||||
if (bin.at<uint8_t>(r, c)) {
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int r = corners[2].y; r < corners[3].y; r++) {
|
|
||||||
auto start = min(linePointX(corners[1], corners[3], r), linePointX(corners[2], corners[3], r)) - 1;
|
|
||||||
auto end = max(linePointX(corners[1], corners[3], r), linePointX(corners[2], corners[3], r)) + 1;
|
|
||||||
if (start < 0 || end > 640) return 0;
|
|
||||||
for (int c = start; c < end; c++) {
|
|
||||||
if (bin.at<uint8_t>(r, c)) {
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return double(cnt) / rotrect.size.area();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isValidLightBlob(const cv::Mat &bin, const cv::RotatedRect &rect) {
|
|
||||||
return (lw_rate(rect) > 1.5) &&
|
|
||||||
// (rect.size.width*rect.size.height < 3000) &&
|
|
||||||
(rect.size.width * rect.size.height > 1) &&
|
|
||||||
(nonZeroRateOfRotateRect_opt(bin, rect) > 0.8);
|
|
||||||
// (nonZeroRateOfRotateRect(bin, rect) > 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_blob_color(const cv::Mat &src, std::vector<LightBlob> &blobs) {
|
|
||||||
for (auto &blob : blobs) {
|
|
||||||
auto region = blob.rect.boundingRect();
|
|
||||||
region.x -= fmax(2, region.width * 0.1);
|
|
||||||
region.y -= fmax(2, region.height * 0.05);
|
|
||||||
region.width += 2 * fmax(2, region.width * 0.1);
|
|
||||||
region.height += 2 * fmax(2, region.height * 0.05);
|
|
||||||
region &= cv::Rect(0, 0, 640, 480);
|
|
||||||
cv::Mat roi = src(region);
|
|
||||||
long long int red_cnt = 0, blue_cnt = 0;
|
|
||||||
for (int row = 0; row < roi.rows; row++) {
|
|
||||||
for (int col = 0; col < roi.cols; col++) {
|
|
||||||
red_cnt += roi.at<cv::Vec3b>(row, col)[2];
|
|
||||||
blue_cnt += roi.at<cv::Vec3b>(row, col)[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (red_cnt > blue_cnt) {
|
|
||||||
blob.BlobColor = BLOB_RED;
|
|
||||||
} else {
|
|
||||||
blob.BlobColor = BLOB_BLUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ArmorFinder::findLightBlobs(const cv::Mat &src_bin, LightBlobs &light_blobs) {
|
|
||||||
std::vector<std::vector<cv::Point> > light_contours;
|
|
||||||
cv::findContours(src_bin, light_contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
|
|
||||||
|
|
||||||
for (auto &light_contour : light_contours) {
|
|
||||||
cv::RotatedRect rect = cv::minAreaRect(light_contour);
|
|
||||||
if (isValidLightBlob(src_bin, rect)) {
|
|
||||||
light_blobs.emplace_back(rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
get_blob_color(src_raw, light_blobs);
|
|
||||||
return light_blobs.size() >= 2;
|
|
||||||
}
|
|
||||||
@@ -3,118 +3,15 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <armor_finder/armor_finder.h>
|
#include <armor_finder/armor_finder.h>
|
||||||
#include <opencv2/highgui.hpp>
|
|
||||||
#include <show_images/show_images.h>
|
#include <show_images/show_images.h>
|
||||||
#include <options/options.h>
|
#include <options/options.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
|
|
||||||
|
|
||||||
static string prior_blue[] = {
|
|
||||||
"B8", "B1", "B3", "B4", "B5", "B7", "B2",
|
|
||||||
"R8", "R1", "R3", "R4", "R5", "R7", "R2",
|
|
||||||
};
|
|
||||||
|
|
||||||
static string prior_red[] = {
|
|
||||||
"R8", "R1", "R3", "R4", "R5", "R7", "R2",
|
|
||||||
"B8", "B1", "B3", "B4", "B5", "B7", "B2",
|
|
||||||
};
|
|
||||||
|
|
||||||
void imagePreProcess(cv::Mat &src) {
|
|
||||||
static cv::Mat kernel_erode = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 5));
|
|
||||||
erode(src, src, kernel_erode);
|
|
||||||
|
|
||||||
static cv::Mat kernel_dilate = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 5));
|
|
||||||
dilate(src, src, kernel_dilate);
|
|
||||||
|
|
||||||
static cv::Mat kernel_dilate2 = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 5));
|
|
||||||
dilate(src, src, kernel_dilate2);
|
|
||||||
|
|
||||||
static cv::Mat kernel_erode2 = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 5));
|
|
||||||
erode(src, src, kernel_erode2);
|
|
||||||
|
|
||||||
float alpha = 1.5;
|
|
||||||
int beta = 0;
|
|
||||||
src.convertTo(src, -1, alpha, beta);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ArmorFinder::stateSearchingTarget(cv::Mat &src) {
|
bool ArmorFinder::stateSearchingTarget(cv::Mat &src) {
|
||||||
std::vector<cv::Mat> channels; // 通道拆分
|
if(findArmorBox(src, armor_box)){
|
||||||
cv::Mat src_bin, color; // 二值图和颜色通道图
|
return true;
|
||||||
LightBlobs light_blobs; // 存储所有可能的灯条
|
}else{
|
||||||
std::vector<cv::Rect2d> armor_boxes; // 装甲板候选区
|
armor_box = ArmorBox();
|
||||||
std::vector<cv::Rect2d> boxes_number[15]; // 装甲板候选区放置在对应id位置
|
|
||||||
|
|
||||||
armor_box = cv::Rect2d(0, 0, 0, 0); // 重置目标装甲板位置
|
|
||||||
boxid = -1; // 重置目标装甲板id
|
|
||||||
|
|
||||||
cv::split(src, channels); /************************/
|
|
||||||
if (enemy_color == ENEMY_BLUE) /* */
|
|
||||||
color = channels[0]; /* 根据目标颜色进行通道提取 */
|
|
||||||
else if (enemy_color == ENEMY_RED) /* */
|
|
||||||
color = channels[2]; /************************/
|
|
||||||
cv::threshold(color, src_bin, 170, 255, CV_THRESH_BINARY); // 二值化对应通道
|
|
||||||
imagePreProcess(src_bin); // 开闭运算
|
|
||||||
if (!findLightBlobs(src_bin, light_blobs)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (show_light_blobs) {
|
|
||||||
showContours("light_blobs", src, light_blobs);
|
|
||||||
cv::waitKey(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!findArmorBoxes(light_blobs, armor_boxes)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (show_armor_boxes) {
|
|
||||||
showArmorBoxVector("boxes", src, armor_boxes);
|
|
||||||
cv::waitKey(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (classifier && use_classifier) {
|
|
||||||
for (auto box : armor_boxes) {
|
|
||||||
cv::Mat roi = src(box).clone();
|
|
||||||
cv::resize(roi, roi, cv::Size(48, 36));
|
|
||||||
int c = classifier(roi);
|
|
||||||
boxes_number[c].emplace_back(box);
|
|
||||||
}
|
|
||||||
if (enemy_color == ENEMY_BLUE) {
|
|
||||||
for (auto name : prior_blue) {
|
|
||||||
if (!boxes_number[name2id[name]].empty()) {
|
|
||||||
armor_box = boxes_number[name2id[name]][0];
|
|
||||||
boxid = name2id[name];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (enemy_color == ENEMY_RED) {
|
|
||||||
for (auto name : prior_red) {
|
|
||||||
if (!boxes_number[name2id[name]].empty()) {
|
|
||||||
armor_box = boxes_number[name2id[name]][0];
|
|
||||||
boxid = name2id[name];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOGE_INFO("enemy_color ERROR!");
|
|
||||||
}
|
|
||||||
if (armor_box == cv::Rect2d(0, 0, 0, 0)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (show_armor_boxes) {
|
|
||||||
showArmorBoxClass("class", src, boxes_number);
|
|
||||||
}
|
|
||||||
if (save_labelled_boxes) {
|
|
||||||
for (int i = 0; i < sizeof(boxes_number) / sizeof(boxes_number[0]); i++) {
|
|
||||||
for (auto &box : boxes_number[i]) {
|
|
||||||
char filename[100];
|
|
||||||
sprintf(filename, PROJECT_DIR"/armor_box_photo/%s_%d.jpg", id2name[i].data(),
|
|
||||||
time(nullptr) + clock());
|
|
||||||
cv::imwrite(filename, src(box));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
armor_box = armor_boxes[0];
|
|
||||||
boxid = -1;
|
|
||||||
}
|
|
||||||
return sendBoxPosition();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,13 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <armor_finder/armor_finder.h>
|
#include <armor_finder/armor_finder.h>
|
||||||
|
#include<log.h>
|
||||||
|
|
||||||
static bool sendTarget(Serial &serial, double x, double y, double z) {
|
static bool sendTarget(Serial &serial, double x, double y, double z, uint16_t shoot_delay) {
|
||||||
static short x_tmp, y_tmp, z_tmp;
|
static short x_tmp, y_tmp, z_tmp;
|
||||||
static time_t last_time = time(nullptr);
|
static time_t last_time = time(nullptr);
|
||||||
static int fps;
|
static int fps;
|
||||||
uint8_t buff[8];
|
uint8_t buff[10];
|
||||||
|
|
||||||
time_t t = time(nullptr);
|
time_t t = time(nullptr);
|
||||||
if (last_time != t) {
|
if (last_time != t) {
|
||||||
@@ -29,19 +30,25 @@ static bool sendTarget(Serial &serial, double x, double y, double z) {
|
|||||||
buff[4] = static_cast<char>((y_tmp >> 0) & 0xFF);
|
buff[4] = static_cast<char>((y_tmp >> 0) & 0xFF);
|
||||||
buff[5] = static_cast<char>((z_tmp >> 8) & 0xFF);
|
buff[5] = static_cast<char>((z_tmp >> 8) & 0xFF);
|
||||||
buff[6] = static_cast<char>((z_tmp >> 0) & 0xFF);
|
buff[6] = static_cast<char>((z_tmp >> 0) & 0xFF);
|
||||||
buff[7] = 'e';
|
buff[7] = static_cast<char>((shoot_delay >> 8) & 0xFF);
|
||||||
|
buff[8] = static_cast<char>((shoot_delay >> 0) & 0xFF);
|
||||||
|
buff[9] = 'e';
|
||||||
|
// if(buff[7]<<8 | buff[8])
|
||||||
|
// cout << (buff[7]<<8 | buff[8]) << endl;
|
||||||
return serial.WriteData(buff, sizeof(buff));
|
return serial.WriteData(buff, sizeof(buff));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmorFinder::sendBoxPosition() {
|
bool ArmorFinder::sendBoxPosition(uint16_t shoot_delay) {
|
||||||
if(armor_box.rect == cv::Rect2d()) return false;
|
if(armor_box.rect == cv::Rect2d()) return false;
|
||||||
auto rect = armor_box;
|
if(shoot_delay){
|
||||||
|
LOGM(STR_CTR(WORD_BLUE, "shoot after %dms"), shoot_delay);
|
||||||
|
}
|
||||||
|
auto rect = armor_box.rect;
|
||||||
double dx = rect.x + rect.width / 2 - 320;
|
double dx = rect.x + rect.width / 2 - 320;
|
||||||
double dy = rect.y + rect.height / 2 - 240 - 20;
|
double dy = rect.y + rect.height / 2 - 240 - 20;
|
||||||
double yaw = atan(dx / FOCUS_PIXAL) * 180 / PI;
|
double yaw = atan(dx / FOCUS_PIXAL) * 180 / PI;
|
||||||
double pitch = atan(dy / FOCUS_PIXAL) * 180 / PI;
|
double pitch = atan(dy / FOCUS_PIXAL) * 180 / PI;
|
||||||
double dist = DISTANCE_HEIGHT / rect.height;
|
double dist = DISTANCE_HEIGHT / rect.height;
|
||||||
// cout << yaw << endl;
|
// cout << yaw << endl;
|
||||||
return sendTarget(serial, yaw, -pitch, dist);
|
return sendTarget(serial, yaw, -pitch, dist, shoot_delay);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,30 +2,76 @@
|
|||||||
// Created by xinyang on 19-3-27.
|
// Created by xinyang on 19-3-27.
|
||||||
//
|
//
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
|
#include <options/options.h>
|
||||||
#include <armor_finder/armor_finder.h>
|
#include <armor_finder/armor_finder.h>
|
||||||
|
#include <show_images/show_images.h>
|
||||||
|
|
||||||
bool ArmorFinder::stateTrackingTarget(cv::Mat &src) {
|
bool ArmorFinder::stateTrackingTarget(cv::Mat &src) {
|
||||||
if(!tracker->update(src, armor_box)){
|
auto pos = armor_box.rect;
|
||||||
|
if(!tracker->update(src, pos)){
|
||||||
|
armor_box = ArmorBox();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if((armor_box & cv::Rect2d(0, 0, 640, 480)) != armor_box){
|
if((pos & cv::Rect2d(0, 0, 640, 480)) != pos){
|
||||||
|
armor_box = ArmorBox();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat roi = src.clone()(armor_box);
|
cv::Rect2d bigger_rect;
|
||||||
if(classifier){
|
|
||||||
cv::resize(roi, roi, cv::Size(48, 36));
|
bigger_rect.x = pos.x - pos.width / 2.0;
|
||||||
if(classifier(roi) == 0){
|
bigger_rect.y = pos.y - pos.height / 2.0;
|
||||||
return false;
|
bigger_rect.height = pos.height * 2;
|
||||||
|
bigger_rect.width = pos.width * 2;
|
||||||
|
bigger_rect &= cv::Rect2d(0, 0, 640, 480);
|
||||||
|
|
||||||
|
if(show_armor_box)
|
||||||
|
showTrackSearchingPos("track", src, bigger_rect);
|
||||||
|
|
||||||
|
cv::Mat roi = src(bigger_rect).clone();
|
||||||
|
|
||||||
|
ArmorBox box;
|
||||||
|
if(findArmorBox(roi, box)) {
|
||||||
|
armor_box = box;
|
||||||
|
armor_box.rect.x += bigger_rect.x;
|
||||||
|
armor_box.rect.y += bigger_rect.y;
|
||||||
|
for(auto &blob : armor_box.light_blobs){
|
||||||
|
blob.rect.center.x += bigger_rect.x;
|
||||||
|
blob.rect.center.y += bigger_rect.y;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
cv::Mat roi_gray;
|
roi = src(pos).clone();
|
||||||
cv::cvtColor(roi, roi_gray, CV_RGB2GRAY);
|
if(classifier){
|
||||||
cv::threshold(roi_gray, roi_gray, 180, 255, cv::THRESH_BINARY);
|
cv::resize(roi, roi, cv::Size(48, 36));
|
||||||
contour_area = cv::countNonZero(roi_gray);
|
if(classifier(roi) == 0){
|
||||||
if(abs(cv::countNonZero(roi_gray) - contour_area) > contour_area * 0.3){
|
armor_box = ArmorBox();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
cv::Mat roi_gray;
|
||||||
|
cv::cvtColor(roi, roi_gray, CV_RGB2GRAY);
|
||||||
|
cv::threshold(roi_gray, roi_gray, 180, 255, cv::THRESH_BINARY);
|
||||||
|
contour_area = cv::countNonZero(roi_gray);
|
||||||
|
if(abs(cv::countNonZero(roi_gray) - contour_area) > contour_area * 0.3){
|
||||||
|
armor_box = ArmorBox();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
armor_box.rect = pos;
|
||||||
|
armor_box.light_blobs.clear();
|
||||||
}
|
}
|
||||||
return sendBoxPosition();
|
|
||||||
|
|
||||||
|
// armor_box.x -= armor_box.width / 4.0;
|
||||||
|
// armor_box.y -= armor_box.height / 4.0;
|
||||||
|
// armor_box.height *= 1.5;
|
||||||
|
// armor_box.width *= 1.5;
|
||||||
|
|
||||||
|
// roi = src(armor_box);
|
||||||
|
// if(findSearchingTarget(roi)){
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
// sendBoxPosition();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,30 @@
|
|||||||
#include <show_images/show_images.h>
|
#include <show_images/show_images.h>
|
||||||
#include <opencv2/highgui.hpp>
|
#include <opencv2/highgui.hpp>
|
||||||
|
#include <options/options.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
|
|
||||||
|
void drawLightBlobs(cv::Mat &src, const LightBlobs &blobs){
|
||||||
|
for (const auto &blob:blobs) {
|
||||||
|
Scalar color(0,255,0);
|
||||||
|
if (blob.blob_color == BLOB_RED)
|
||||||
|
color = Scalar(0, 0, 255);
|
||||||
|
else if (blob.blob_color == BLOB_BLUE)
|
||||||
|
color = Scalar(255, 0, 0);
|
||||||
|
cv::Point2f vertices[4];
|
||||||
|
blob.rect.points(vertices);
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
cv::line(src, vertices[j], vertices[(j + 1) % 4], color, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
* 显示多个装甲板区域 *
|
* 显示多个装甲板区域 *
|
||||||
**************************/
|
**************************/
|
||||||
void showArmorBoxVector(std::string windows_name, const cv::Mat &src, const std::vector<cv::Rect2d> &armor_box) {
|
void showArmorBoxes(std::string windows_name, const cv::Mat &src, const ArmorBoxes &armor_boxes) {
|
||||||
static Mat image2show;
|
static Mat image2show;
|
||||||
if (src.type() == CV_8UC1) {// 黑白图像
|
if (src.type() == CV_8UC1) {// 黑白图像
|
||||||
cvtColor(src, image2show, COLOR_GRAY2RGB);
|
cvtColor(src, image2show, COLOR_GRAY2RGB);
|
||||||
@@ -15,8 +32,15 @@ void showArmorBoxVector(std::string windows_name, const cv::Mat &src, const std:
|
|||||||
image2show = src.clone();
|
image2show = src.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &box:armor_box) {
|
for (auto &box:armor_boxes) {
|
||||||
rectangle(image2show, box, Scalar(0, 255, 0), 1);
|
if(box.box_color == BOX_BLUE) {
|
||||||
|
rectangle(image2show, box.rect, Scalar(0, 255, 0), 1);
|
||||||
|
drawLightBlobs(image2show, box.light_blobs);
|
||||||
|
}else if(box.box_color == BOX_RED){
|
||||||
|
rectangle(image2show, box.rect, Scalar(0, 255, 0), 1);
|
||||||
|
drawLightBlobs(image2show, box.light_blobs);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
imshow(windows_name, image2show);
|
imshow(windows_name, image2show);
|
||||||
}
|
}
|
||||||
@@ -24,25 +48,26 @@ void showArmorBoxVector(std::string windows_name, const cv::Mat &src, const std:
|
|||||||
/**************************
|
/**************************
|
||||||
* 显示多个装甲板区域及其类别 *
|
* 显示多个装甲板区域及其类别 *
|
||||||
**************************/
|
**************************/
|
||||||
void showArmorBoxClass(std::string window_names, const cv::Mat &src, vector<cv::Rect2d> boxes[10]) {
|
void showArmorBoxesClass(std::string window_names, const cv::Mat &src, const ArmorBoxes boxes[15]) {
|
||||||
static Mat image2show;
|
static Mat image2show;
|
||||||
if (src.type() == CV_8UC1) { // 黑白图像
|
if (src.type() == CV_8UC1) { // 黑白图像
|
||||||
cvtColor(src, image2show, COLOR_GRAY2RGB);
|
cvtColor(src, image2show, COLOR_GRAY2RGB);
|
||||||
} else if (src.type() == CV_8UC3) { //RGB 彩色
|
} else if (src.type() == CV_8UC3) { //RGB 彩色
|
||||||
image2show = src.clone();
|
image2show = src.clone();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 14; i++) {
|
for (int i = 1; i < 15; i++) {
|
||||||
if (!boxes[i].empty()) {
|
if (!boxes[i].empty()) {
|
||||||
for (auto box : boxes[i]) {
|
for (auto box : boxes[i]) {
|
||||||
rectangle(image2show, box, Scalar(0, 255, 0), 1);
|
rectangle(image2show, box.rect, Scalar(0, 255, 0), 1);
|
||||||
|
drawLightBlobs(image2show, box.light_blobs);
|
||||||
if (i == -1)
|
if (i == -1)
|
||||||
putText(image2show, id2name[i], Point(box.x + 2, box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
putText(image2show, id2name[i], Point(box.rect.x + 2, box.rect.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
||||||
Scalar(0, 255, 0));
|
Scalar(0, 255, 0));
|
||||||
else if (1 <= i && i < 8)
|
else if (1 <= i && i < 8)
|
||||||
putText(image2show, id2name[i], Point(box.x + 2, box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
putText(image2show, id2name[i], Point(box.rect.x + 2, box.rect.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
||||||
Scalar(255, 0, 0));
|
Scalar(255, 0, 0));
|
||||||
else if (8 <= i && i < 15)
|
else if (8 <= i && i < 15)
|
||||||
putText(image2show, id2name[i], Point(box.x + 2, box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
putText(image2show, id2name[i], Point(box.rect.x + 2, box.rect.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
||||||
Scalar(0, 0, 255));
|
Scalar(0, 0, 255));
|
||||||
else if (i != 0)
|
else if (i != 0)
|
||||||
LOGE_INFO("Invalid box id:%d!", i);
|
LOGE_INFO("Invalid box id:%d!", i);
|
||||||
@@ -55,34 +80,48 @@ void showArmorBoxClass(std::string window_names, const cv::Mat &src, vector<cv::
|
|||||||
/**************************
|
/**************************
|
||||||
* 显示单个装甲板区域及其类别 *
|
* 显示单个装甲板区域及其类别 *
|
||||||
**************************/
|
**************************/
|
||||||
void showArmorBox(std::string windows_name, const cv::Mat &src, cv::Rect2d armor_box, int boxid) {
|
void showArmorBox(std::string windows_name, const cv::Mat &src, const ArmorBox &box) {
|
||||||
static Mat image2show;
|
static Mat image2show;
|
||||||
|
if(box.rect == cv::Rect2d()){
|
||||||
|
imshow(windows_name, src);
|
||||||
|
}
|
||||||
if (src.type() == CV_8UC1) { // 黑白图像
|
if (src.type() == CV_8UC1) { // 黑白图像
|
||||||
cvtColor(src, image2show, COLOR_GRAY2RGB);
|
cvtColor(src, image2show, COLOR_GRAY2RGB);
|
||||||
} else if (src.type() == CV_8UC3) { //RGB 彩色
|
} else if (src.type() == CV_8UC3) { //RGB 彩色
|
||||||
image2show = src.clone();
|
image2show = src.clone();
|
||||||
}
|
}
|
||||||
rectangle(image2show, armor_box, Scalar(0, 255, 0), 1);
|
drawLightBlobs(image2show, box.light_blobs);
|
||||||
|
// static FILE *fp = fopen(PROJECT_DIR"/ratio.txt", "w");
|
||||||
|
// if(box.light_blobs.size() == 2)
|
||||||
|
// fprintf(fp, "%lf %lf %lf\n", box.light_blobs[0].length, box.light_blobs[1].length, box.blobsDistance())
|
||||||
|
// cout << box.lengthDistanceRatio() << endl;
|
||||||
|
|
||||||
|
if(box.getOrientation() == ArmorBox::FRONT){
|
||||||
|
rectangle(image2show, box.rect, Scalar(0, 255, 0), 3);
|
||||||
|
}else{
|
||||||
|
rectangle(image2show, box.rect, Scalar(0, 255, 0), 1);
|
||||||
|
};
|
||||||
|
|
||||||
char dist[5];
|
char dist[5];
|
||||||
// sprintf(dist, "%.1f", distance);
|
sprintf(dist, "%.1f", box.getDistance());
|
||||||
if (boxid == -1)
|
if (box.id == -1)
|
||||||
putText(image2show, id2name[boxid]+" "+dist, Point(armor_box.x + 2, armor_box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
putText(image2show, id2name[box.id]+" "+dist, Point(box.rect.x + 2, box.rect.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
||||||
Scalar(0, 255, 0));
|
Scalar(0, 255, 0));
|
||||||
else if (1 <= boxid && boxid < 8)
|
else if (1 <= box.id && box.id < 8)
|
||||||
putText(image2show, id2name[boxid]+" "+dist, Point(armor_box.x + 2, armor_box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
putText(image2show, id2name[box.id]+" "+dist, Point(box.rect.x + 2, box.rect.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
||||||
Scalar(255, 0, 0));
|
Scalar(255, 0, 0));
|
||||||
else if (8 <= boxid && boxid < 15)
|
else if (8 <= box.id && box.id < 15)
|
||||||
putText(image2show, id2name[boxid]+" "+dist, Point(armor_box.x + 2, armor_box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
putText(image2show, id2name[box.id]+" "+dist, Point(box.rect.x + 2, box.rect.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
|
||||||
Scalar(0, 0, 255));
|
Scalar(0, 0, 255));
|
||||||
else if (boxid != 0)
|
else if (box.id != 0)
|
||||||
LOGE_INFO("Invalid box id:%d!", boxid);
|
LOGE_INFO("Invalid box id:%d!", box.id);
|
||||||
imshow(windows_name, image2show);
|
imshow(windows_name, image2show);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
* 显示多个灯条区域 *
|
* 显示多个灯条区域 *
|
||||||
**************************/
|
**************************/
|
||||||
void showContours(std::string windows_name, const cv::Mat &src, const std::vector<LightBlob> &light_blobs) {
|
void showLightBlobs(std::string windows_name, const cv::Mat &src, const LightBlobs &light_blobs) {
|
||||||
static Mat image2show;
|
static Mat image2show;
|
||||||
|
|
||||||
if (src.type() == CV_8UC1) { // 黑白图像
|
if (src.type() == CV_8UC1) { // 黑白图像
|
||||||
@@ -92,13 +131,11 @@ void showContours(std::string windows_name, const cv::Mat &src, const std::vecto
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &light_blob:light_blobs) {
|
for (const auto &light_blob:light_blobs) {
|
||||||
Scalar color;
|
Scalar color(0, 255, 0);
|
||||||
if (light_blob.BlobColor == BLOB_RED)
|
if (light_blob.blob_color == BLOB_RED)
|
||||||
color = Scalar(0, 0, 255);
|
color = Scalar(0, 0, 255);
|
||||||
else if (light_blob.BlobColor == BLOB_BLUE)
|
else if (light_blob.blob_color == BLOB_BLUE)
|
||||||
color = Scalar(255, 0, 0);
|
color = Scalar(255, 0, 0);
|
||||||
else
|
|
||||||
color = Scalar(0, 255, 0);
|
|
||||||
cv::Point2f vertices[4];
|
cv::Point2f vertices[4];
|
||||||
light_blob.rect.points(vertices);
|
light_blob.rect.points(vertices);
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
@@ -107,3 +144,15 @@ void showContours(std::string windows_name, const cv::Mat &src, const std::vecto
|
|||||||
}
|
}
|
||||||
imshow(windows_name, image2show);
|
imshow(windows_name, image2show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void showTrackSearchingPos(std::string window_names, const cv::Mat &src, const cv::Rect2d pos){
|
||||||
|
static Mat image2show;
|
||||||
|
if (src.type() == CV_8UC1) { // 黑白图像
|
||||||
|
cvtColor(src, image2show, COLOR_GRAY2RGB);
|
||||||
|
} else if (src.type() == CV_8UC3) { //RGB 彩色
|
||||||
|
image2show = src.clone();
|
||||||
|
}
|
||||||
|
rectangle(image2show, pos, Scalar(0, 255, 0), 1);
|
||||||
|
imshow(window_names, image2show);
|
||||||
|
}
|
||||||
@@ -11,7 +11,8 @@ const int SRC_WIDTH = 320;
|
|||||||
const int SRC_HEIGHT = 240;
|
const int SRC_HEIGHT = 240;
|
||||||
const int CLOCKWISE = 1;
|
const int CLOCKWISE = 1;
|
||||||
const int ANTICLOCKWISE = -1;
|
const int ANTICLOCKWISE = -1;
|
||||||
const float ATTACK_DISTANCE = 718.0;//cm
|
//const float ATTACK_DISTANCE = 718.0;//cm
|
||||||
|
const float ATTACK_DISTANCE = 750.0;//cm
|
||||||
const double ARMOR_CENTER_TO_CYCLE_CENTER = 75.0;//cm
|
const double ARMOR_CENTER_TO_CYCLE_CENTER = 75.0;//cm
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,14 @@ public:
|
|||||||
Energy(Serial &u, uint8_t &color);//构造函数,参数为串口和敌方颜色
|
Energy(Serial &u, uint8_t &color);//构造函数,参数为串口和敌方颜色
|
||||||
~Energy();//默认析构函数
|
~Energy();//默认析构函数
|
||||||
|
|
||||||
void run(cv::Mat &gimbal_src, cv::Mat &chassis_src);
|
void runBig(cv::Mat &gimbal_src, cv::Mat &chassis_src);
|
||||||
void run(cv::Mat &gimbal_src);
|
void runBig(cv::Mat &gimbal_src);
|
||||||
|
void runSmall(cv::Mat &gimbal_src);
|
||||||
|
|
||||||
Serial &serial;//串口
|
Serial &serial;//串口
|
||||||
void setEnergyInit();//设置能量机关初始化
|
void setEnergyInit();//设置能量机关初始化
|
||||||
|
void setBigEnergyInit();//设置大能量机关初始化
|
||||||
|
void setSmallEnergyInit();//设置小能量机关初始化
|
||||||
void sendTarget(Serial &serial, float x, float y, float z);
|
void sendTarget(Serial &serial, float x, float y, float z);
|
||||||
|
|
||||||
|
|
||||||
@@ -51,7 +54,6 @@ private:
|
|||||||
bool energy_rotation_init;//若仍在判断风车旋转方向,则为true
|
bool energy_rotation_init;//若仍在判断风车旋转方向,则为true
|
||||||
bool manual_mark;//若操作手进行过手动标定,则为true
|
bool manual_mark;//若操作手进行过手动标定,则为true
|
||||||
bool auto_mark;//云台完成自动对心,则置为true
|
bool auto_mark;//云台完成自动对心,则置为true
|
||||||
bool shoot;//若为true,则要求主控板发弹
|
|
||||||
bool start_guess;//进入猜测状态的标志
|
bool start_guess;//进入猜测状态的标志
|
||||||
bool change_target;//目标切换的标志
|
bool change_target;//目标切换的标志
|
||||||
|
|
||||||
@@ -77,6 +79,8 @@ private:
|
|||||||
float center_delta_yaw, center_delta_pitch;//对心时相差的角度
|
float center_delta_yaw, center_delta_pitch;//对心时相差的角度
|
||||||
float yaw_rotation, pitch_rotation;//云台yaw轴和pitch轴应该转到的角度
|
float yaw_rotation, pitch_rotation;//云台yaw轴和pitch轴应该转到的角度
|
||||||
float origin_yaw, origin_pitch;//初始的云台角度设定值
|
float origin_yaw, origin_pitch;//初始的云台角度设定值
|
||||||
|
float shoot;//若为2,则要求主控板发弹
|
||||||
|
float sum_yaw, sum_pitch;//yaw和pitch的累计误差,即PID中积分项
|
||||||
|
|
||||||
timeval time_start_guess;
|
timeval time_start_guess;
|
||||||
|
|
||||||
@@ -158,8 +162,9 @@ private:
|
|||||||
void getAllTargetArmorCenters();//记录所有目标装甲板中心坐标
|
void getAllTargetArmorCenters();//记录所有目标装甲板中心坐标
|
||||||
void getRecentTargetArmorCenters();//记录近30帧目标装甲板中心坐标
|
void getRecentTargetArmorCenters();//记录近30帧目标装甲板中心坐标
|
||||||
|
|
||||||
void judgeShoot();//判断是否可以发弹
|
void judgeMode();//判断大符还是小符
|
||||||
void JudgeMode();//判断大符还是小符
|
void judgeShootInGimbal();//在云台坐标系中判断是否可以发弹
|
||||||
|
void judgeShootInWorld();//在世界坐标系中判断是否可以发弹
|
||||||
bool isGuessingTimeout();//判断猜测模式是否超时(没打中)
|
bool isGuessingTimeout();//判断猜测模式是否超时(没打中)
|
||||||
|
|
||||||
void splitBayerBG(cv::Mat src, cv::Mat &blue, cv::Mat &red);//拜耳阵列分离
|
void splitBayerBG(cv::Mat src, cv::Mat &blue, cv::Mat &red);//拜耳阵列分离
|
||||||
|
|||||||
@@ -61,3 +61,4 @@ void Energy::circleLeastFit()
|
|||||||
// cout << "The cycle center is: " << cycle_center << endl;
|
// cout << "The cycle center is: " << cycle_center << endl;
|
||||||
// cout << "The radius is: " << radius << endl;
|
// cout << "The radius is: " << radius << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ void Energy::FlowStripStruct(cv::Mat &src) {
|
|||||||
// 此函数对图像进行腐蚀与膨胀操作
|
// 此函数对图像进行腐蚀与膨胀操作
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
void Energy::CenterRStruct(cv::Mat &src) {
|
void Energy::CenterRStruct(cv::Mat &src) {
|
||||||
Mat element_dilate_1 = getStructuringElement(MORPH_RECT, Size(8, 6));
|
Mat element_dilate_1 = getStructuringElement(MORPH_RECT, Size(4, 4));
|
||||||
Mat element_erode_1 = getStructuringElement(MORPH_RECT, Size(2, 1));
|
Mat element_erode_1 = getStructuringElement(MORPH_RECT, Size(2, 1));
|
||||||
Mat element_dilate_2 = getStructuringElement(MORPH_RECT, Size(3, 3));
|
Mat element_dilate_2 = getStructuringElement(MORPH_RECT, Size(3, 3));
|
||||||
Mat element_erode_2 = getStructuringElement(MORPH_RECT, Size(4 , 4));
|
Mat element_erode_2 = getStructuringElement(MORPH_RECT, Size(4 , 4));
|
||||||
@@ -134,8 +134,8 @@ void Energy::CenterRStruct(cv::Mat &src) {
|
|||||||
// imshow("erode_1", src);
|
// imshow("erode_1", src);
|
||||||
dilate(src, src, element_dilate_1);
|
dilate(src, src, element_dilate_1);
|
||||||
// imshow("dilate_1", src);
|
// imshow("dilate_1", src);
|
||||||
dilate(src, src, element_dilate_2);
|
// dilate(src, src, element_dilate_2);
|
||||||
// imshow("dilate_2", src);
|
// imshow("dilate_2", src);
|
||||||
erode(src,src, element_erode_2);
|
// erode(src,src, element_erode_2);
|
||||||
// imshow("erode_2", src);
|
// imshow("erode_2", src);
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,6 @@ void Energy::clearAll(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
// 此函数用于图像预处理
|
// 此函数用于图像预处理
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ void Energy::initEnergy() {
|
|||||||
energy_rotation_init = true;
|
energy_rotation_init = true;
|
||||||
manual_mark = false;
|
manual_mark = false;
|
||||||
auto_mark = false;
|
auto_mark = false;
|
||||||
shoot = false;
|
|
||||||
start_guess = false;
|
start_guess = false;
|
||||||
change_target = false;
|
change_target = false;
|
||||||
|
|
||||||
@@ -41,14 +40,15 @@ void Energy::initEnergy() {
|
|||||||
last_target_polar_angle = -1000;
|
last_target_polar_angle = -1000;
|
||||||
guess_polar_angle = -1000;
|
guess_polar_angle = -1000;
|
||||||
last_base_angle = -1000;
|
last_base_angle = -1000;
|
||||||
predict_rad = 20;
|
predict_rad = 25;
|
||||||
attack_distance = ATTACK_DISTANCE;
|
attack_distance = ATTACK_DISTANCE;
|
||||||
center_delta_yaw = 1000;
|
center_delta_yaw = 1000;
|
||||||
center_delta_pitch = 1000;
|
center_delta_pitch = 1000;
|
||||||
yaw_rotation = 0;
|
yaw_rotation = 0;
|
||||||
pitch_rotation = 0;
|
pitch_rotation = 0;
|
||||||
origin_yaw = 0;
|
shoot = 0;
|
||||||
origin_pitch = 0;
|
sum_yaw = 0;
|
||||||
|
sum_pitch = 0;
|
||||||
|
|
||||||
circle_center_point = Point(0, 0);
|
circle_center_point = Point(0, 0);
|
||||||
target_point = Point(0, 0);
|
target_point = Point(0, 0);
|
||||||
@@ -69,7 +69,7 @@ void Energy::initEnergy() {
|
|||||||
// 此函数对能量机关参数进行初始化
|
// 此函数对能量机关参数进行初始化
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
void Energy::initEnergyPartParam() {
|
void Energy::initEnergyPartParam() {
|
||||||
gimbal_energy_part_param_.GRAY_THRESH = 120;//home
|
gimbal_energy_part_param_.GRAY_THRESH = 140;//home
|
||||||
// gimbal_energy_part_param_.GRAY_THRESH = 200;//official
|
// gimbal_energy_part_param_.GRAY_THRESH = 200;//official
|
||||||
// gimbal_energy_part_param_.GRAY_THRESH = 225;
|
// gimbal_energy_part_param_.GRAY_THRESH = 225;
|
||||||
gimbal_energy_part_param_.SPLIT_GRAY_THRESH = 230;
|
gimbal_energy_part_param_.SPLIT_GRAY_THRESH = 230;
|
||||||
@@ -81,7 +81,7 @@ void Energy::initEnergyPartParam() {
|
|||||||
gimbal_energy_part_param_.FAN_CONTOUR_LENGTH_MIN = 80;
|
gimbal_energy_part_param_.FAN_CONTOUR_LENGTH_MIN = 80;
|
||||||
gimbal_energy_part_param_.FAN_CONTOUR_LENGTH_MAX = 100;
|
gimbal_energy_part_param_.FAN_CONTOUR_LENGTH_MAX = 100;
|
||||||
gimbal_energy_part_param_.FAN_CONTOUR_WIDTH_MIN = 20;
|
gimbal_energy_part_param_.FAN_CONTOUR_WIDTH_MIN = 20;
|
||||||
gimbal_energy_part_param_.FAN_CONTOUR_WIDTH_MAX = 50;
|
gimbal_energy_part_param_.FAN_CONTOUR_WIDTH_MAX = 52;
|
||||||
gimbal_energy_part_param_.FAN_CONTOUR_HW_RATIO_MAX = 4;
|
gimbal_energy_part_param_.FAN_CONTOUR_HW_RATIO_MAX = 4;
|
||||||
gimbal_energy_part_param_.FAN_CONTOUR_HW_RATIO_MIN = 1;
|
gimbal_energy_part_param_.FAN_CONTOUR_HW_RATIO_MIN = 1;
|
||||||
gimbal_energy_part_param_.FAN_CONTOUR_AREA_RATIO_MIN = 0.65;
|
gimbal_energy_part_param_.FAN_CONTOUR_AREA_RATIO_MIN = 0.65;
|
||||||
@@ -107,20 +107,20 @@ void Energy::initEnergyPartParam() {
|
|||||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_WIDTH_MAX = 25;
|
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_MAX = 3;
|
||||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MIN = 1;
|
gimbal_energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MIN = 1;
|
||||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_AREA_RATIO_MIN = 0.7;
|
gimbal_energy_part_param_.CENTER_R_CONTOUR_AREA_RATIO_MIN = 0.5;
|
||||||
gimbal_energy_part_param_.CENTER_R_CONTOUR_INTERSETION_AREA_MIN = 10;
|
gimbal_energy_part_param_.CENTER_R_CONTOUR_INTERSETION_AREA_MIN = 10;
|
||||||
|
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MAX = 17000;
|
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MAX = 3000;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MIN = 0;
|
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MIN = 1000;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MIN = 60;
|
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_LENGTH_MAX = 100;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MIN = 20;
|
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_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_MAX = 3;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MIN = 1;
|
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MIN = 1;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MAX = 0.62;
|
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MAX = 0.65;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MIN = 0.34;
|
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_MAX = 0.65;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MIN = 0.34;
|
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_MAX = 0.2;
|
||||||
// gimbal_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MIN = 0.08;
|
// gimbal_energy_part_param_.FLOW_STRIP_FAN_NON_ZERO_RATE_MIN = 0.08;
|
||||||
@@ -130,19 +130,19 @@ void Energy::initEnergyPartParam() {
|
|||||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MIN = 38;
|
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MIN = 38;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MAX = 60;
|
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MAX = 60;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MIN = 8;
|
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MIN = 8;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MAX = 28;
|
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MAX = 32;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MAX = 12;
|
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 = 2.3;
|
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MIN = 1.8;
|
||||||
gimbal_energy_part_param_.FLOW_STRIP_CONTOUR_AREA_RATIO_MIN = 0.5;
|
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_.FLOW_STRIP_CONTOUR_INTERSETION_AREA_MIN = 100;
|
||||||
|
|
||||||
gimbal_energy_part_param_.TWIN_ANGEL_MAX = 10;
|
gimbal_energy_part_param_.TWIN_ANGEL_MAX = 10;
|
||||||
gimbal_energy_part_param_.TARGET_INTERSETION_CONTOUR_AREA_MIN = 40;
|
gimbal_energy_part_param_.TARGET_INTERSETION_CONTOUR_AREA_MIN = 40;
|
||||||
|
|
||||||
|
|
||||||
chassis_energy_part_param_.GRAY_THRESH = 120;//home_small
|
|
||||||
chassis_energy_part_param_.GRAY_THRESH = 230;//home_big
|
chassis_energy_part_param_.GRAY_THRESH = 120;//home
|
||||||
// chassis_energy_part_param_.GRAY_THRESH = 200;//official
|
// chassis_energy_part_param_.GRAY_THRESH = 200;//official
|
||||||
// chassis_energy_part_param_.GRAY_THRESH = 225;
|
// chassis_energy_part_param_.GRAY_THRESH = 225;
|
||||||
chassis_energy_part_param_.SPLIT_GRAY_THRESH = 230;
|
chassis_energy_part_param_.SPLIT_GRAY_THRESH = 230;
|
||||||
@@ -189,7 +189,7 @@ void Energy::initEnergyPartParam() {
|
|||||||
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MIN = 90;
|
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MIN = 90;
|
||||||
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MAX = 140;
|
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MAX = 140;
|
||||||
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MIN = 35;
|
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MIN = 35;
|
||||||
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MAX = 60;
|
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MAX = 65;
|
||||||
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MAX = 3;
|
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MAX = 3;
|
||||||
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MIN = 1;
|
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MIN = 1;
|
||||||
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MAX = 0.55;
|
chassis_energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MAX = 0.55;
|
||||||
@@ -231,11 +231,11 @@ void Energy::initRotation() {
|
|||||||
else if (target_polar_angle > last_target_polar_angle) anticlockwise_rotation_init_cnt++;
|
else if (target_polar_angle > last_target_polar_angle) anticlockwise_rotation_init_cnt++;
|
||||||
}
|
}
|
||||||
//由于刚开始圆心判断不准,角度变化可能计算有误,因此需要在角度正向或逆向变化足够大时才可确定是否为顺逆时针
|
//由于刚开始圆心判断不准,角度变化可能计算有误,因此需要在角度正向或逆向变化足够大时才可确定是否为顺逆时针
|
||||||
if (clockwise_rotation_init_cnt == 30) {
|
if (clockwise_rotation_init_cnt == 15) {
|
||||||
energy_rotation_direction = CLOCKWISE;//顺时针变化30次,确定为顺时针
|
energy_rotation_direction = CLOCKWISE;//顺时针变化30次,确定为顺时针
|
||||||
cout << "rotation: " << energy_rotation_direction << endl;
|
cout << "rotation: " << energy_rotation_direction << endl;
|
||||||
energy_rotation_init = false;
|
energy_rotation_init = false;
|
||||||
} else if (anticlockwise_rotation_init_cnt == 30) {
|
} else if (anticlockwise_rotation_init_cnt == 15) {
|
||||||
energy_rotation_direction = ANTICLOCKWISE;//逆时针变化30次,确定为顺时针
|
energy_rotation_direction = ANTICLOCKWISE;//逆时针变化30次,确定为顺时针
|
||||||
cout << "rotation: " << energy_rotation_direction << endl;
|
cout << "rotation: " << energy_rotation_direction << endl;
|
||||||
energy_rotation_init = false;
|
energy_rotation_init = false;
|
||||||
|
|||||||
@@ -44,4 +44,33 @@ void Energy::setEnergyInit() {
|
|||||||
is_small = false;
|
is_small = false;
|
||||||
is_gimbal = true;
|
is_gimbal = true;
|
||||||
is_chassis = false;
|
is_chassis = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// 此函数为大能量机关再初始化函数
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void Energy::setBigEnergyInit() {
|
||||||
|
initEnergy();
|
||||||
|
initEnergyPartParam();
|
||||||
|
|
||||||
|
is_big = true;
|
||||||
|
is_small = false;
|
||||||
|
is_gimbal = true;
|
||||||
|
is_chassis = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// 此函数为大能量机关再初始化函数
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void Energy::setSmallEnergyInit() {
|
||||||
|
initEnergy();
|
||||||
|
initEnergyPartParam();
|
||||||
|
|
||||||
|
is_big = false;
|
||||||
|
is_small = true;
|
||||||
|
is_gimbal = true;
|
||||||
|
is_chassis = false;
|
||||||
}
|
}
|
||||||
@@ -69,6 +69,7 @@ int Energy::findArmors(const cv::Mat src) {
|
|||||||
|
|
||||||
ArmorStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
|
ArmorStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
|
||||||
findContours(src_bin, armor_contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
|
findContours(src_bin, armor_contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
|
||||||
|
imshow("armor struct", src_bin);
|
||||||
// findContours(src_bin, armor_contours_external, CV_RETR_EXTERNAL, 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++)//去除外轮廓
|
// for (int i = 0; i < armor_contours_external.size(); i++)//去除外轮廓
|
||||||
@@ -132,7 +133,7 @@ bool Energy::findCenterR(const cv::Mat src) {
|
|||||||
circle_center_point = centerR.center;
|
circle_center_point = centerR.center;
|
||||||
circle_center_point.y += target_length / 7.5;//实际最小二乘得到的中心在R的下方
|
circle_center_point.y += target_length / 7.5;//实际最小二乘得到的中心在R的下方
|
||||||
|
|
||||||
// RotatedRect cur_rect = minAreaRect(center_R_contour);
|
RotatedRect cur_rect = minAreaRect(center_R_contour);
|
||||||
// Size2f cur_size = cur_rect.size;
|
// Size2f cur_size = cur_rect.size;
|
||||||
// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width;
|
// 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 width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;
|
||||||
@@ -147,10 +148,11 @@ bool Energy::findCenterR(const cv::Mat src) {
|
|||||||
// cout << "R intersection: " << contourArea(intersection) << endl;
|
// cout << "R intersection: " << contourArea(intersection) << endl;
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
|
// cout << cur_rect.center << endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
cout << "find center R false!" << endl;
|
cout << "find center R false!" << endl;
|
||||||
|
// cv::waitKey(0);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -159,7 +161,7 @@ bool Energy::findCenterR(const cv::Mat src) {
|
|||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
// 此函数用于判断找到的矩形候选区是否为含流动条的扇叶
|
// 此函数用于判断找到的矩形候选区是否为含流动条的扇叶
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
bool Energy:: findFlowStripFan(const cv::Mat src) {
|
bool Energy::findFlowStripFan(const cv::Mat src) {
|
||||||
if (src.empty())return false;
|
if (src.empty())return false;
|
||||||
static Mat src_bin;
|
static Mat src_bin;
|
||||||
static Mat src_copy;
|
static Mat src_copy;
|
||||||
@@ -170,25 +172,14 @@ bool Energy:: findFlowStripFan(const cv::Mat src) {
|
|||||||
}
|
}
|
||||||
std::vector<vector<Point> > flow_strip_fan_contours;
|
std::vector<vector<Point> > flow_strip_fan_contours;
|
||||||
FlowStripFanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
|
FlowStripFanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
|
||||||
// imshow("flow strip fan struct", src_bin);
|
imshow("flow strip fan struct", src_bin);
|
||||||
|
|
||||||
// vector<vector<Point>> contours;
|
|
||||||
// findContours(src_bin, flow_strip_fan_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
|
|
||||||
// for (auto &flow_strip_fan_contour : flow_strip_fan_contours) {
|
|
||||||
// if(contourArea(flow_strip_fan_contour)>1800&&contourArea(flow_strip_fan_contour)<2300)
|
|
||||||
// contours.push_back(flow_strip_fan_contour);
|
|
||||||
//// cout<<contourArea(flow_strip_fan_contour)<<endl;
|
|
||||||
// }
|
|
||||||
// Mat draw(src.size(),CV_8UC3,Scalar(0,0,0));
|
|
||||||
// drawContours(draw,contours,-1,Scalar(255,255,255),1);
|
|
||||||
// imshow("draw",draw);
|
|
||||||
// waitKey();
|
|
||||||
findContours(src_bin, flow_strip_fan_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
|
findContours(src_bin, flow_strip_fan_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
|
||||||
|
|
||||||
for (auto &flow_strip_fan_contour : flow_strip_fan_contours) {
|
for (auto &flow_strip_fan_contour : flow_strip_fan_contours) {
|
||||||
if (!isValidFlowStripFanContour(src_bin, flow_strip_fan_contour)) {
|
if (!isValidFlowStripFanContour(src_bin, flow_strip_fan_contour)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// cout<<contourArea(flow_strip_fan_contour)<<endl;
|
|
||||||
flow_strip_fan = cv::minAreaRect(flow_strip_fan_contour);
|
flow_strip_fan = cv::minAreaRect(flow_strip_fan_contour);
|
||||||
|
|
||||||
// RotatedRect cur_rect = minAreaRect(flow_strip_fan_contour);
|
// RotatedRect cur_rect = minAreaRect(flow_strip_fan_contour);
|
||||||
@@ -204,12 +195,12 @@ bool Energy:: findFlowStripFan(const cv::Mat src) {
|
|||||||
// cout << "non zero: " << non_zero_rate << endl;
|
// cout << "non zero: " << non_zero_rate << endl;
|
||||||
// cout<<cur_contour_area / cur_size.area()<<endl;
|
// cout<<cur_contour_area / cur_size.area()<<endl;
|
||||||
// }
|
// }
|
||||||
|
// cout << cur_rect.center << endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// showFlowStripFan("strip fan", src_bin);
|
// showFlowStripFan("strip fan", src_bin);
|
||||||
cout << "flow strip fan false!" << endl;
|
cout << "flow strip fan false!" << endl;
|
||||||
// waitKey();
|
// waitKey(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,21 +225,21 @@ bool Energy::findFlowStrip(const cv::Mat src) {
|
|||||||
if (!isValidFlowStripContour(flow_strip_contour)) {
|
if (!isValidFlowStripContour(flow_strip_contour)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// cout<<"size: "<<contourArea(flow_strip_contour)<<endl;
|
|
||||||
flow_strip = cv::minAreaRect(flow_strip_contour);
|
flow_strip = cv::minAreaRect(flow_strip_contour);
|
||||||
// RotatedRect cur_rect = minAreaRect(flow_strip_contour);
|
// RotatedRect cur_rect = minAreaRect(flow_strip_contour);
|
||||||
// Size2f cur_size = cur_rect.size;
|
// Size2f cur_size = cur_rect.size;
|
||||||
// float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width;
|
// 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 width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;
|
||||||
// if (length / width > 4 && width > 7 && width<30) {
|
// if (length / width > 2.5 && width > 7 && width<40) {
|
||||||
// cout << cur_rect.center << endl;
|
// cout << cur_rect.center << endl;
|
||||||
// flow_strip = cv::minAreaRect(flow_strip_contour);
|
// flow_strip = cv::minAreaRect(flow_strip_contour);
|
||||||
// cout << "flow strip area: " << length << '\t' << width << endl;
|
// cout << "flow strip area: " << length << '\t' << width << endl;
|
||||||
// }
|
// }
|
||||||
|
// cout << cur_rect.center << endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
cout << "flow strip false!" << endl;
|
cout << "flow strip false!" << endl;
|
||||||
// waitKey();
|
// waitKey(0);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -265,7 +256,7 @@ bool Energy::findCenterROI(const cv::Mat src) {
|
|||||||
vector<Point2f> mask_rect;
|
vector<Point2f> mask_rect;
|
||||||
target_armor.points(vertices); //计算矩形的4个顶点
|
target_armor.points(vertices); //计算矩形的4个顶点
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
line(src_mask, vertices[i], vertices[(i + 1) % 4], Scalar(0, 0, 0), 15);
|
line(src_mask, vertices[i], vertices[(i + 1) % 4], Scalar(0, 0, 0), 20);
|
||||||
// imshow("fill", src_mask);
|
// imshow("fill", src_mask);
|
||||||
if (!findFlowStrip(src_mask))return false;
|
if (!findFlowStrip(src_mask))return false;
|
||||||
float length = target_armor.size.height > target_armor.size.width ?
|
float length = target_armor.size.height > target_armor.size.width ?
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "energy/energy.h"
|
#include "energy/energy.h"
|
||||||
#include "energy/constant.h"
|
#include "energy/constant.h"
|
||||||
|
#include "config/setconfig.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
@@ -12,8 +13,13 @@ using namespace cv;
|
|||||||
// 此函数通过自瞄逻辑击打目标点,用于大符的自动对心和小符直接打击
|
// 此函数通过自瞄逻辑击打目标点,用于大符的自动对心和小符直接打击
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
void Energy::getAimPoint(cv::Point target_point) {
|
void Energy::getAimPoint(cv::Point target_point) {
|
||||||
double dx = -(target_point.x - 320 - 10);
|
//五号车
|
||||||
double dy = -(target_point.y - 240 - 22);
|
// double dx = -(target_point.x - 320 - 10);
|
||||||
|
// double dy = -(target_point.y - 240 - 22);
|
||||||
|
//四号车
|
||||||
|
double dx = -(target_point.x - 320 - COMPENSATE_YAW);
|
||||||
|
double dy = -(target_point.y - 240 - COMPENSATE_PITCH);
|
||||||
yaw_rotation = atan(dx / FOCUS_PIXAL) * 180 / PI;
|
yaw_rotation = atan(dx / FOCUS_PIXAL) * 180 / PI;
|
||||||
pitch_rotation = atan(dy / FOCUS_PIXAL) * 180 / PI;
|
pitch_rotation = atan(dy / FOCUS_PIXAL) * 180 / PI;
|
||||||
|
// cout << "yaw: " << yaw_rotation << '\t' << "pitch: " << pitch_rotation << endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,18 +13,24 @@ using namespace cv;
|
|||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
bool Energy::getOrigin() {
|
bool Energy::getOrigin() {
|
||||||
if (!auto_mark && !manual_mark) {
|
if (!auto_mark && !manual_mark) {
|
||||||
double dx = -(circle_center_point.x - 320);
|
//五号车
|
||||||
double dy = -(circle_center_point.y - 240);
|
// double dx = -(circle_center_point.x - 320 - 10);
|
||||||
center_delta_yaw = atan(dx / FOCUS_PIXAL) * 180 / PI;
|
// double dy = -(circle_center_point.y - 240 - 22);
|
||||||
center_delta_pitch = atan(dy / FOCUS_PIXAL) * 180 / PI;
|
//四号车
|
||||||
if (abs(center_delta_pitch) > 0.3 || abs(center_delta_pitch) > 0.3) {
|
double dx = -(circle_center_point.x - 320 - 7);
|
||||||
sendTarget(serial, center_delta_yaw, center_delta_pitch, false);
|
double dy = -(circle_center_point.y - 240 - 64);
|
||||||
|
center_delta_yaw = static_cast<float>(atan(dx / FOCUS_PIXAL) * 180 / PI);
|
||||||
|
center_delta_pitch = static_cast<float>(atan(dy / FOCUS_PIXAL) * 180 / PI);
|
||||||
|
if (abs(center_delta_yaw) > 0.3 || abs(center_delta_pitch) > 0.3) {
|
||||||
|
// cout << "origin not get!" << endl;
|
||||||
|
// cout << center_delta_yaw << '\t' << center_delta_pitch << endl;
|
||||||
|
sendTarget(serial, center_delta_yaw, center_delta_pitch, 0);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
origin_yaw = mcuData.curr_yaw;
|
origin_yaw = mcuData.curr_yaw;
|
||||||
origin_pitch = mcuData.curr_pitch;
|
origin_pitch = mcuData.curr_pitch;
|
||||||
auto_mark = true;
|
auto_mark = true;
|
||||||
sendTarget(serial, center_delta_yaw, center_delta_pitch, true);
|
sendTarget(serial, center_delta_yaw, center_delta_pitch, 1);
|
||||||
LOGM(STR_CTR(WORD_BLUE_CODE, "auto mark success!"));
|
LOGM(STR_CTR(WORD_BLUE_CODE, "auto mark success!"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ bool Energy::isValidFanContour(cv::Mat &src, const vector<cv::Point> &fan_contou
|
|||||||
if (length < energy_part_param_.FAN_CONTOUR_LENGTH_MIN || width < energy_part_param_.FAN_CONTOUR_WIDTH_MIN ||
|
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) {
|
length > energy_part_param_.FAN_CONTOUR_LENGTH_MAX || width > energy_part_param_.FAN_CONTOUR_WIDTH_MAX) {
|
||||||
//cout<<"length width fail."<<endl;
|
//cout<<"length width fail."<<endl;
|
||||||
|
// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl;
|
||||||
return false;
|
return false;
|
||||||
//矩形边长不合适
|
//矩形边长不合适
|
||||||
}
|
}
|
||||||
@@ -34,12 +35,14 @@ bool Energy::isValidFanContour(cv::Mat &src, const vector<cv::Point> &fan_contou
|
|||||||
if (length_width_ratio > energy_part_param_.FAN_CONTOUR_HW_RATIO_MAX ||
|
if (length_width_ratio > energy_part_param_.FAN_CONTOUR_HW_RATIO_MAX ||
|
||||||
length_width_ratio < energy_part_param_.FAN_CONTOUR_HW_RATIO_MIN) {
|
length_width_ratio < energy_part_param_.FAN_CONTOUR_HW_RATIO_MIN) {
|
||||||
//cout<<"length width ratio fail."<<endl;
|
//cout<<"length width ratio fail."<<endl;
|
||||||
|
// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl;
|
||||||
return false;
|
return false;
|
||||||
//长宽比不合适
|
//长宽比不合适
|
||||||
}
|
}
|
||||||
// cout << cur_contour_area / cur_size.area() << endl;
|
// cout << cur_contour_area / cur_size.area() << endl;
|
||||||
if (cur_contour_area / cur_size.area() < energy_part_param_.FAN_CONTOUR_AREA_RATIO_MIN) {
|
if (cur_contour_area / cur_size.area() < energy_part_param_.FAN_CONTOUR_AREA_RATIO_MIN) {
|
||||||
// cout << cur_contour_area / cur_size.area() << endl;
|
// cout << cur_contour_area / cur_size.area() << endl;
|
||||||
|
// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl;
|
||||||
return false;//轮廓对矩形的面积占有率不合适
|
return false;//轮廓对矩形的面积占有率不合适
|
||||||
}
|
}
|
||||||
double non_zero_rate = nonZeroRateOfRotateRect(src, cur_rect);
|
double non_zero_rate = nonZeroRateOfRotateRect(src, cur_rect);
|
||||||
@@ -71,6 +74,7 @@ bool Energy::isValidArmorContour(const vector<cv::Point> &armor_contour) {
|
|||||||
if (length < energy_part_param_.ARMOR_CONTOUR_LENGTH_MIN || width < energy_part_param_.ARMOR_CONTOUR_WIDTH_MIN ||
|
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) {
|
length > energy_part_param_.ARMOR_CONTOUR_LENGTH_MAX || width > energy_part_param_.ARMOR_CONTOUR_WIDTH_MAX) {
|
||||||
//cout<<"length width fail."<<endl;
|
//cout<<"length width fail."<<endl;
|
||||||
|
// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl;
|
||||||
return false;
|
return false;
|
||||||
//矩形边长不合适
|
//矩形边长不合适
|
||||||
}
|
}
|
||||||
@@ -79,11 +83,14 @@ bool Energy::isValidArmorContour(const vector<cv::Point> &armor_contour) {
|
|||||||
if (length_width_ratio > energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MAX ||
|
if (length_width_ratio > energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MAX ||
|
||||||
length_width_ratio < energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MIN) {
|
length_width_ratio < energy_part_param_.ARMOR_CONTOUR_HW_RATIO_MIN) {
|
||||||
//cout<<"length width ratio fail."<<endl;
|
//cout<<"length width ratio fail."<<endl;
|
||||||
|
// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl;
|
||||||
return false;
|
return false;
|
||||||
//长宽比不合适
|
//长宽比不合适
|
||||||
}
|
}
|
||||||
if (cur_contour_area / cur_size.area() < energy_part_param_.ARMOR_CONTOUR_AREA_RATIO_MIN)
|
if (cur_contour_area / cur_size.area() < energy_part_param_.ARMOR_CONTOUR_AREA_RATIO_MIN) {
|
||||||
|
// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl;
|
||||||
return false;//轮廓对矩形的面积占有率不合适
|
return false;//轮廓对矩形的面积占有率不合适
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +115,7 @@ bool Energy::isValidCenterRContour(const vector<cv::Point> ¢er_R_contour) {
|
|||||||
|| length > energy_part_param_.CENTER_R_CONTOUR_LENGTH_MAX ||
|
|| length > energy_part_param_.CENTER_R_CONTOUR_LENGTH_MAX ||
|
||||||
width > energy_part_param_.CENTER_R_CONTOUR_WIDTH_MAX) {
|
width > energy_part_param_.CENTER_R_CONTOUR_WIDTH_MAX) {
|
||||||
//cout<<"length width fail."<<endl;
|
//cout<<"length width fail."<<endl;
|
||||||
|
// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl;
|
||||||
return false;
|
return false;
|
||||||
//矩形边长不合适
|
//矩形边长不合适
|
||||||
}
|
}
|
||||||
@@ -115,16 +123,19 @@ bool Energy::isValidCenterRContour(const vector<cv::Point> ¢er_R_contour) {
|
|||||||
if (length_width_ratio > energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MAX ||
|
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) {
|
length_width_ratio < energy_part_param_.CENTER_R_CONTOUR_HW_RATIO_MIN) {
|
||||||
//cout<<"length width ratio fail."<<endl;
|
//cout<<"length width ratio fail."<<endl;
|
||||||
|
// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl;
|
||||||
return false;
|
return false;
|
||||||
//长宽比不合适
|
//长宽比不合适
|
||||||
}
|
}
|
||||||
if (cur_contour_area / cur_size.area() < energy_part_param_.CENTER_R_CONTOUR_AREA_RATIO_MIN)
|
if (cur_contour_area / cur_size.area() < energy_part_param_.CENTER_R_CONTOUR_AREA_RATIO_MIN) {
|
||||||
|
// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl;
|
||||||
return false;//轮廓对矩形的面积占有率不合适
|
return false;//轮廓对矩形的面积占有率不合适
|
||||||
|
}
|
||||||
std::vector<cv::Point2f> intersection;
|
std::vector<cv::Point2f> intersection;
|
||||||
if (rotatedRectangleIntersection(cur_rect, center_ROI, intersection) == 0) {
|
if (rotatedRectangleIntersection(cur_rect, center_ROI, intersection) == 0) {
|
||||||
return false;
|
return false;
|
||||||
} else if (contourArea(intersection) < energy_part_param_.CENTER_R_CONTOUR_INTERSETION_AREA_MIN) {
|
} else if (contourArea(intersection) < energy_part_param_.CENTER_R_CONTOUR_INTERSETION_AREA_MIN) {
|
||||||
cout << "R intersection: " << contourArea(intersection) << endl;
|
// cout << "R intersection: " << contourArea(intersection) << '\t' << cur_rect.center << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -138,12 +149,12 @@ bool Energy::isValidFlowStripFanContour(cv::Mat &src, const vector<cv::Point> &f
|
|||||||
double cur_contour_area = contourArea(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 ||
|
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) {
|
cur_contour_area < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_MIN) {
|
||||||
// cout<<"area fail."<<endl;
|
//cout<<"area fail."<<endl;
|
||||||
|
// cout << "area: " << cur_contour_area << '\t' << endl;
|
||||||
return false;
|
return false;
|
||||||
//选区面积大小不合适
|
//选区面积大小不合适
|
||||||
}
|
}
|
||||||
// cout<<cur_contour_area<<endl;
|
// cout << "area: " << cur_contour_area << endl;
|
||||||
|
|
||||||
RotatedRect cur_rect = minAreaRect(flow_strip_fan_contour);
|
RotatedRect cur_rect = minAreaRect(flow_strip_fan_contour);
|
||||||
Size2f cur_size = cur_rect.size;
|
Size2f cur_size = cur_rect.size;
|
||||||
float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长
|
float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长
|
||||||
@@ -152,24 +163,23 @@ bool Energy::isValidFlowStripFanContour(cv::Mat &src, const vector<cv::Point> &f
|
|||||||
|| width < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MIN
|
|| width < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MIN
|
||||||
|| length > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MAX
|
|| length > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_LENGTH_MAX
|
||||||
|| width > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MAX) {
|
|| width > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_WIDTH_MAX) {
|
||||||
// if(cur_contour_area>1600)
|
|
||||||
// cout<<"length: "<<length<<"width: "<<width<<endl;
|
|
||||||
// cout<<"length width fail."<<endl;
|
// cout<<"length width fail."<<endl;
|
||||||
|
// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl;
|
||||||
return false;
|
return false;
|
||||||
//矩形边长不合适
|
//矩形边长不合适
|
||||||
}
|
}
|
||||||
float length_width_ratio = length / width;//计算矩形长宽比
|
float length_width_ratio = length / width;//计算矩形长宽比
|
||||||
if (length_width_ratio > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MAX ||
|
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) {
|
length_width_ratio < energy_part_param_.FLOW_STRIP_FAN_CONTOUR_HW_RATIO_MIN) {
|
||||||
// cout<<"length width ratio fail."<<endl;
|
//cout<<"length width ratio fail."<<endl;
|
||||||
|
// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl;
|
||||||
return false;
|
return false;
|
||||||
//长宽比不合适
|
//长宽比不合适
|
||||||
}
|
}
|
||||||
// cout << cur_contour_area / cur_size.area() << endl;
|
// 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
|
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) {
|
|| cur_contour_area / cur_size.area() > energy_part_param_.FLOW_STRIP_FAN_CONTOUR_AREA_RATIO_MAX) {
|
||||||
// if(cur_contour_area>1900)
|
// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl;
|
||||||
// cout<<"size ratio: "<<cur_contour_area / cur_size.area()<<endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 轮廓对矩形的面积占有率不合适
|
// 轮廓对矩形的面积占有率不合适
|
||||||
@@ -193,19 +203,11 @@ bool Energy::isValidFlowStripContour(const vector<cv::Point> &flow_strip_contour
|
|||||||
if (cur_contour_area > energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MAX ||
|
if (cur_contour_area > energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MAX ||
|
||||||
cur_contour_area < energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MIN) {
|
cur_contour_area < energy_part_param_.FLOW_STRIP_CONTOUR_AREA_MIN) {
|
||||||
// cout<<"area fail."<<endl;
|
// cout<<"area fail."<<endl;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
//选区面积大小不合适
|
//选区面积大小不合适
|
||||||
}
|
}
|
||||||
|
|
||||||
RotatedRect cur_rect = minAreaRect(flow_strip_contour);
|
RotatedRect cur_rect = minAreaRect(flow_strip_contour);
|
||||||
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) {
|
|
||||||
// cout<<"Intersection false!"<<endl;
|
|
||||||
return false;
|
|
||||||
//面积占比不合适
|
|
||||||
}
|
|
||||||
|
|
||||||
Size2f cur_size = cur_rect.size;
|
Size2f cur_size = cur_rect.size;
|
||||||
float length = cur_size.height > cur_size.width ? cur_size.height : cur_size.width;//将矩形的长边设置为长
|
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 width = cur_size.height < cur_size.width ? cur_size.height : cur_size.width;//将矩形的短边设置为宽
|
||||||
@@ -213,23 +215,30 @@ bool Energy::isValidFlowStripContour(const vector<cv::Point> &flow_strip_contour
|
|||||||
width < energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MIN ||
|
width < energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MIN ||
|
||||||
length > energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MAX ||
|
length > energy_part_param_.FLOW_STRIP_CONTOUR_LENGTH_MAX ||
|
||||||
width > energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MAX) {
|
width > energy_part_param_.FLOW_STRIP_CONTOUR_WIDTH_MAX) {
|
||||||
// if(cur_contour_area>600&&cur_contour_area<900)
|
|
||||||
// cout<<"length: "<<length<<" width: "<<width<<endl;
|
|
||||||
// cout<<"length width fail."<<endl;
|
// cout<<"length width fail."<<endl;
|
||||||
|
// cout << "length: " << length << '\t' << "width: " << width << '\t' << cur_rect.center << endl;
|
||||||
return false;
|
return false;
|
||||||
//矩形边长不合适
|
//矩形边长不合适
|
||||||
}
|
}
|
||||||
|
// cout << length << '\t' << width << endl;
|
||||||
float length_width_ratio = length / width;//计算矩形长宽比
|
float length_width_ratio = length / width;//计算矩形长宽比
|
||||||
if (length_width_ratio > energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MAX ||
|
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) {
|
length_width_ratio < energy_part_param_.FLOW_STRIP_CONTOUR_HW_RATIO_MIN) {
|
||||||
// if(cur_contour_area>600&&cur_contour_area<900)
|
|
||||||
// cout<<"length: "<<length<<" width: "<<width<<" hw: "<<length_width_ratio<<endl;
|
|
||||||
// cout<<"hw fail."<<endl;
|
// cout<<"hw fail."<<endl;
|
||||||
|
// cout << "HW: " << length_width_ratio << '\t' << cur_rect.center << endl;
|
||||||
return false;
|
return false;
|
||||||
//长宽比不合适
|
//长宽比不合适
|
||||||
}
|
}
|
||||||
if (cur_contour_area / cur_size.area() < energy_part_param_.FLOW_STRIP_CONTOUR_AREA_RATIO_MIN)
|
if (cur_contour_area / cur_size.area() < energy_part_param_.FLOW_STRIP_CONTOUR_AREA_RATIO_MIN) {
|
||||||
|
// cout << "area ratio: " << cur_contour_area / cur_size.area() << '\t' << cur_rect.center << endl;
|
||||||
return false;//轮廓对矩形的面积占有率不合适
|
return false;//轮廓对矩形的面积占有率不合适
|
||||||
|
}
|
||||||
|
std::vector<cv::Point2f> intersection;
|
||||||
|
if (rotatedRectangleIntersection(cur_rect, flow_strip_fan, intersection) == 0) {
|
||||||
|
return false;
|
||||||
|
} else if (contourArea(intersection) < energy_part_param_.FLOW_STRIP_CONTOUR_INTERSETION_AREA_MIN) {
|
||||||
|
// cout << "intersection: " << contourArea(intersection) << '\t' << cur_rect.center << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ using namespace cv;
|
|||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
// 此函数用于判断大小符
|
// 此函数用于判断大小符
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
void Energy::JudgeMode() {
|
void Energy::judgeMode() {
|
||||||
getRecentTargetArmorCenters();
|
getRecentTargetArmorCenters();
|
||||||
if (recent_target_armor_centers.size() < 30) {
|
if (recent_target_armor_centers.size() < 30) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -4,23 +4,44 @@
|
|||||||
|
|
||||||
#include "energy/energy.h"
|
#include "energy/energy.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "config/setconfig.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
// 此函数用于判断是否可以发弹
|
// 此函数用于判断世界坐标系下是否可以发弹
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
void Energy::judgeShoot(){
|
void Energy::judgeShootInWorld(){
|
||||||
if (abs(yaw_rotation - mcuData.curr_yaw) < 0.3 && fabs(pitch_rotation - mcuData.curr_pitch) < 0.3) {
|
if (abs(yaw_rotation - mcuData.curr_yaw) < 0.8 && fabs(pitch_rotation - mcuData.curr_pitch) < 0.8) {
|
||||||
shoot = true;
|
shoot = 4;
|
||||||
is_predicting = false;
|
is_predicting = false;
|
||||||
is_guessing = true;
|
is_guessing = true;
|
||||||
start_guess = true;
|
start_guess = true;
|
||||||
gettimeofday(&time_start_guess, NULL);
|
gettimeofday(&time_start_guess, NULL);
|
||||||
LOGM(STR_CTR(WORD_LIGHT_RED, "Start Guessing!"));
|
LOGM(STR_CTR(WORD_LIGHT_RED, "Start Guessing!"));
|
||||||
} else
|
} else
|
||||||
shoot = false;
|
shoot = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// 此函数用于判断云台坐标系下是否可以发弹
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void Energy::judgeShootInGimbal(){
|
||||||
|
if (abs(yaw_rotation) < 0.5 && fabs(pitch_rotation) < 0.5) {
|
||||||
|
shoot = 4;
|
||||||
|
is_predicting = false;
|
||||||
|
is_guessing = true;
|
||||||
|
start_guess = true;
|
||||||
|
gettimeofday(&time_start_guess, NULL);
|
||||||
|
LOGM(STR_CTR(WORD_LIGHT_RED, "Start Guessing!"));
|
||||||
|
} else
|
||||||
|
shoot = 2;
|
||||||
|
|
||||||
|
sum_yaw += yaw_rotation;
|
||||||
|
sum_pitch += pitch_rotation;
|
||||||
|
yaw_rotation = AIM_KP * yaw_rotation + AIM_KI * sum_yaw;
|
||||||
|
pitch_rotation = AIM_KP * pitch_rotation + AIM_KI * sum_pitch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,5 +17,5 @@ bool Energy::isGuessingTimeout() {
|
|||||||
timeval cur_time;
|
timeval cur_time;
|
||||||
gettimeofday(&cur_time, NULL);
|
gettimeofday(&cur_time, NULL);
|
||||||
return (cur_time.tv_sec - time_start_guess.tv_sec) * 1000.0 +
|
return (cur_time.tv_sec - time_start_guess.tv_sec) * 1000.0 +
|
||||||
(cur_time.tv_usec - time_start_guess.tv_usec) / 1000.0 > 500;
|
(cur_time.tv_usec - time_start_guess.tv_usec) / 1000.0 > 1000;
|
||||||
};
|
};
|
||||||
@@ -12,16 +12,15 @@ using namespace cv;
|
|||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
// 此函数为能量机关模式主控制流函数,且步兵需要同时拥有云台摄像头和底盘摄像头
|
// 此函数为能量机关模式主控制流函数,且步兵需要同时拥有云台摄像头和底盘摄像头
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
void Energy::run(cv::Mat &gimbal_src, cv::Mat &chassis_src) {
|
void Energy::runBig(cv::Mat &gimbal_src, cv::Mat &chassis_src) {
|
||||||
if (chassis_src.empty())
|
if (chassis_src.empty())
|
||||||
run(gimbal_src);//仅拥有云台摄像头则调用单摄像头的run函数
|
runBig(gimbal_src);//仅拥有云台摄像头则调用单摄像头的run函数
|
||||||
else if (is_gimbal) {
|
else if (is_gimbal) {
|
||||||
// energy_part_param_ = chassis_energy_part_param_;
|
|
||||||
energy_part_param_ = gimbal_energy_part_param_;
|
energy_part_param_ = gimbal_energy_part_param_;
|
||||||
clearAll();
|
clearAll();
|
||||||
initImage(gimbal_src);
|
initImage(gimbal_src);
|
||||||
findFans(gimbal_src);
|
// findFans(gimbal_src);
|
||||||
showFans("fan",gimbal_src);
|
// showFans("fan",gimbal_src);
|
||||||
|
|
||||||
if (findArmors(gimbal_src) < 1)return;
|
if (findArmors(gimbal_src) < 1)return;
|
||||||
if (show_energy)showArmors("armor", gimbal_src);
|
if (show_energy)showArmors("armor", gimbal_src);
|
||||||
@@ -32,12 +31,11 @@ void Energy::run(cv::Mat &gimbal_src, cv::Mat &chassis_src) {
|
|||||||
if (!findCenterR(gimbal_src))return;
|
if (!findCenterR(gimbal_src))return;
|
||||||
if (show_energy)showCenterR("R", gimbal_src);
|
if (show_energy)showCenterR("R", gimbal_src);
|
||||||
|
|
||||||
if (!getOrigin())return;
|
// if (!getOrigin())return;
|
||||||
startChassis();
|
startChassis();
|
||||||
initEnergy();
|
initEnergy();
|
||||||
destroyAllWindows();
|
destroyAllWindows();
|
||||||
} else if (is_chassis) {
|
} else if (is_chassis) {
|
||||||
// energy_part_param_ = chassis_energy_part_param_;
|
|
||||||
energy_part_param_ = chassis_energy_part_param_;
|
energy_part_param_ = chassis_energy_part_param_;
|
||||||
clearAll();
|
clearAll();
|
||||||
initImage(chassis_src);
|
initImage(chassis_src);
|
||||||
@@ -47,35 +45,36 @@ void Energy::run(cv::Mat &gimbal_src, cv::Mat &chassis_src) {
|
|||||||
|
|
||||||
if (findArmors(chassis_src) < 1)return;
|
if (findArmors(chassis_src) < 1)return;
|
||||||
if (show_energy)showArmors("armor", chassis_src);
|
if (show_energy)showArmors("armor", chassis_src);
|
||||||
if (!findFlowStripFan(chassis_src)) return;
|
if (!findFlowStripFan(chassis_src))return;
|
||||||
if (!findTargetInFlowStripFan()) return;
|
if (!findTargetInFlowStripFan()) return;
|
||||||
if (!findCenterROI(chassis_src))return;
|
if (!findCenterROI(chassis_src))return;
|
||||||
if (show_energy)showFlowStripFan("strip", chassis_src);
|
if (show_energy)showFlowStripFan("strip", chassis_src);
|
||||||
if (!findCenterR(chassis_src))return;
|
if (!findCenterR(chassis_src))return;
|
||||||
if (show_energy)showCenterR("R", chassis_src);
|
if (show_energy)showCenterR("R", chassis_src);
|
||||||
getTargetPolarAngle();
|
getTargetPolarAngle();
|
||||||
|
|
||||||
changeTarget();
|
changeTarget();
|
||||||
JudgeMode();
|
// judgeMode();
|
||||||
if (energy_mode_init)return;
|
// if (energy_mode_init)return;
|
||||||
if (is_big && energy_rotation_init) {
|
if (is_big && energy_rotation_init) {
|
||||||
initRotation();
|
initRotation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (is_predicting) {
|
// if (is_predicting) {
|
||||||
getPredictPoint(target_point);
|
// getPredictPoint(target_point);
|
||||||
gimbalRotation();
|
// gimbalRotation();
|
||||||
judgeShoot();
|
// judgeShootInWorld();
|
||||||
sendTarget(serial, yaw_rotation, pitch_rotation, shoot);
|
// sendTarget(serial, yaw_rotation, pitch_rotation, shoot);
|
||||||
} else if (is_guessing && stayGuessing()) {
|
// } else if (is_guessing && stayGuessing()) {
|
||||||
findFans(chassis_src);
|
// findFans(chassis_src);
|
||||||
if (show_energy)showFans("fans", chassis_src);
|
// if (show_energy)showFans("fans", chassis_src);
|
||||||
if (save_mark)writeDownMark();
|
// if (save_mark)writeDownMark();
|
||||||
if (!guessTarget()) return;
|
// if (!guessTarget()) return;
|
||||||
if (show_energy)showGuessTarget("guess", chassis_src);
|
// if (show_energy)showGuessTarget("guess", chassis_src);
|
||||||
getPredictPoint(guess_point);
|
// getPredictPoint(guess_point);
|
||||||
gimbalRotation();
|
// gimbalRotation();
|
||||||
sendTarget(serial, yaw_rotation, pitch_rotation, false);
|
// sendTarget(serial, yaw_rotation, pitch_rotation, 5);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +82,7 @@ void Energy::run(cv::Mat &gimbal_src, cv::Mat &chassis_src) {
|
|||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
// 此函数为能量机关模式主控制流函数,且步兵仅拥有云台摄像头
|
// 此函数为能量机关模式主控制流函数,且步兵仅拥有云台摄像头
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
void Energy::run(cv::Mat &gimbal_src) {
|
void Energy::runBig(cv::Mat &gimbal_src) {
|
||||||
energy_part_param_ = gimbal_energy_part_param_;
|
energy_part_param_ = gimbal_energy_part_param_;
|
||||||
clearAll();
|
clearAll();
|
||||||
initImage(gimbal_src);
|
initImage(gimbal_src);
|
||||||
@@ -102,17 +101,24 @@ void Energy::run(cv::Mat &gimbal_src) {
|
|||||||
if (show_energy)showCenterR("R", gimbal_src);
|
if (show_energy)showCenterR("R", gimbal_src);
|
||||||
changeTarget();
|
changeTarget();
|
||||||
getTargetPolarAngle();
|
getTargetPolarAngle();
|
||||||
JudgeMode();
|
// cout<<circle_center_point<<endl;
|
||||||
if (energy_mode_init)return;
|
// cout << target_point << '\t' << target_polar_angle << endl;
|
||||||
if (!getOrigin())return;
|
// cout << circle_center_point<< endl;
|
||||||
if (is_big && energy_rotation_init) {
|
|
||||||
|
// judgeMode();
|
||||||
|
// if (energy_mode_init)return;
|
||||||
|
// if (!getOrigin())return;
|
||||||
|
if (energy_rotation_init) {
|
||||||
initRotation();
|
initRotation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (is_predicting) {
|
if (is_predicting) {
|
||||||
getPredictPoint(target_point);
|
getPredictPoint(target_point);
|
||||||
gimbalRotation();
|
getAimPoint(predict_point);
|
||||||
judgeShoot();
|
// cout << yaw_rotation << '\t' << pitch_rotation << endl;
|
||||||
|
judgeShootInGimbal();
|
||||||
sendTarget(serial, yaw_rotation, pitch_rotation, shoot);
|
sendTarget(serial, yaw_rotation, pitch_rotation, shoot);
|
||||||
} else if (is_guessing && stayGuessing()) {
|
} else if (is_guessing && stayGuessing()) {
|
||||||
findFans(gimbal_src);
|
findFans(gimbal_src);
|
||||||
@@ -121,7 +127,67 @@ void Energy::run(cv::Mat &gimbal_src) {
|
|||||||
guessTarget();
|
guessTarget();
|
||||||
if (show_energy)showGuessTarget("guess", gimbal_src);
|
if (show_energy)showGuessTarget("guess", gimbal_src);
|
||||||
getPredictPoint(guess_point);
|
getPredictPoint(guess_point);
|
||||||
gimbalRotation();
|
getAimPoint(predict_point);
|
||||||
sendTarget(serial, yaw_rotation, pitch_rotation, false);
|
sendTarget(serial, yaw_rotation, pitch_rotation, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// 此函数为小能量机关模式主控制流函数,击打小符只需要拥有云台摄像头
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void Energy::runSmall(cv::Mat &gimbal_src) {
|
||||||
|
energy_part_param_ = gimbal_energy_part_param_;
|
||||||
|
clearAll();
|
||||||
|
initImage(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 (!findCenterROI(gimbal_src))return;
|
||||||
|
// if (show_energy)showFlowStripFan("strip", gimbal_src);
|
||||||
|
// if (!findCenterR(gimbal_src))return;
|
||||||
|
// if (show_energy)showCenterR("R", gimbal_src);
|
||||||
|
|
||||||
|
changeTarget();
|
||||||
|
// cout << "target point: " << target_point << endl;
|
||||||
|
|
||||||
|
if (is_predicting) {
|
||||||
|
getAimPoint(target_point);
|
||||||
|
judgeShootInGimbal();
|
||||||
|
sendTarget(serial, yaw_rotation, pitch_rotation, shoot);
|
||||||
|
} else if (is_guessing && stayGuessing()) {
|
||||||
|
findFans(gimbal_src);
|
||||||
|
if (show_energy)showFans("fans", gimbal_src);
|
||||||
|
if (save_mark)writeDownMark();
|
||||||
|
guessTarget();
|
||||||
|
if (show_energy)showGuessTarget("guess", gimbal_src);
|
||||||
|
getAimPoint(guess_point);
|
||||||
|
sendTarget(serial, yaw_rotation, pitch_rotation, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//getPredictPoint(target_point);
|
||||||
|
//gimbalRotation();
|
||||||
|
//static bool k = false;
|
||||||
|
//cout<<"delta yaw: "<<abs(yaw_rotation - mcuData.curr_yaw)<<endl;
|
||||||
|
//cout<<"delta pitch: "<<abs(pitch_rotation - mcuData.curr_pitch)<<endl;
|
||||||
|
//cout << "origin_yaw: " << origin_yaw << '\t' << "origin_pitch: " << origin_pitch << endl;
|
||||||
|
//cout << "predict point: " << predict_point << endl;
|
||||||
|
//
|
||||||
|
//if (abs(yaw_rotation - mcuData.curr_yaw) < 0.8 && abs(pitch_rotation - mcuData.curr_pitch) < 0.6) {
|
||||||
|
//shoot = 4;
|
||||||
|
//if (!k) {
|
||||||
|
//sendTarget(serial, yaw_rotation, pitch_rotation, shoot);
|
||||||
|
//cout << "yaw: " << yaw_rotation << '\t' << "pitch: " << pitch_rotation << endl;
|
||||||
|
//k = false;
|
||||||
|
//}
|
||||||
|
//waitKey(400);
|
||||||
|
//} else {
|
||||||
|
//shoot = 2;
|
||||||
|
//sendTarget(serial, yaw_rotation, pitch_rotation, shoot);
|
||||||
|
//}
|
||||||
@@ -43,7 +43,6 @@ void Energy::stretch(cv::Point point_1, cv::Point2f &point_2) {
|
|||||||
double x_0 = point_1.x - circle_center_point.x;
|
double x_0 = point_1.x - circle_center_point.x;
|
||||||
double y_0 = point_1.y - circle_center_point.y;
|
double y_0 = point_1.y - circle_center_point.y;
|
||||||
double r_0 = sqrt(pow(x_0, 2) + pow(y_0, 2));
|
double r_0 = sqrt(pow(x_0, 2) + pow(y_0, 2));
|
||||||
|
|
||||||
point_2.x = static_cast<float >( ARMOR_CENTER_TO_CYCLE_CENTER * x_0 / r_0);
|
point_2.x = static_cast<float >( ARMOR_CENTER_TO_CYCLE_CENTER * x_0 / r_0);
|
||||||
point_2.y = static_cast<float >( ARMOR_CENTER_TO_CYCLE_CENTER * y_0 / r_0);
|
point_2.y = static_cast<float >( ARMOR_CENTER_TO_CYCLE_CENTER * y_0 / r_0);
|
||||||
}
|
}
|
||||||
|
|||||||
40
main.cpp
40
main.cpp
@@ -30,7 +30,7 @@ using namespace std;
|
|||||||
mcu_data mcuData = { // 单片机端回传结构体
|
mcu_data mcuData = { // 单片机端回传结构体
|
||||||
0, // 当前云台yaw角
|
0, // 当前云台yaw角
|
||||||
0, // 当前云台pitch角
|
0, // 当前云台pitch角
|
||||||
BIG_ENERGY_STATE, // 当前状态,自瞄-大符-小符
|
ARMOR_STATE, // 当前状态,自瞄-大符-小符
|
||||||
0, // 云台角度标记位
|
0, // 云台角度标记位
|
||||||
1, // 是否启用数字识别
|
1, // 是否启用数字识别
|
||||||
ENEMY_RED, // 敌方颜色
|
ENEMY_RED, // 敌方颜色
|
||||||
@@ -64,10 +64,8 @@ int main(int argc, char *argv[]) {
|
|||||||
video_gimbal = new CameraWrapper(0/*, "armor"*/);
|
video_gimbal = new CameraWrapper(0/*, "armor"*/);
|
||||||
video_chassis = new CameraWrapper(1/*, "energy"*/);
|
video_chassis = new CameraWrapper(1/*, "energy"*/);
|
||||||
} else {
|
} else {
|
||||||
video_gimbal = new VideoWrapper("/home/sjturm/Desktop/videos/gimbal84.avi");
|
video_gimbal = new VideoWrapper("/home/sun/项目/energy_video/gimbal132.avi");
|
||||||
video_chassis = new VideoWrapper("/home/sjturm/Desktop/videos/gimbal84.avi");
|
video_chassis = new VideoWrapper("/home/sun/项目/energy_video/gimbal132.avi");
|
||||||
// video_gimbal = new VideoWrapper("/home/sjturm/Desktop/dafu/gimble3.avi");
|
|
||||||
// video_chassis = new VideoWrapper("/home/sjturm/Desktop/dafu/chassis3.avi");
|
|
||||||
}
|
}
|
||||||
if (video_gimbal->init()) {
|
if (video_gimbal->init()) {
|
||||||
LOGM("video_gimbal source initialization successfully.");
|
LOGM("video_gimbal source initialization successfully.");
|
||||||
@@ -93,19 +91,18 @@ int main(int argc, char *argv[]) {
|
|||||||
bool ok = true;
|
bool ok = true;
|
||||||
cout << "start running" << endl;
|
cout << "start running" << endl;
|
||||||
do {
|
do {
|
||||||
CNT_TIME("Total", {
|
// CNT_TIME("Total", {
|
||||||
if (mcuData.state != ARMOR_STATE) {//能量机关模式
|
if (mcuData.state == BIG_ENERGY_STATE) {//大能量机关模式
|
||||||
if (last_state == ARMOR_STATE) {//若上一帧是自瞄模式,即刚往完成切换,则需要初始化
|
if (last_state != BIG_ENERGY_STATE) {//若上一帧不是大能量机关模式,即刚往完成切换,则需要初始化
|
||||||
destroyAllWindows();
|
destroyAllWindows();
|
||||||
((CameraWrapper *) video_gimbal)->changeBrightness(ENERGY_CAMERA_GAIN);
|
((CameraWrapper *) video_gimbal)->changeBrightness(ENERGY_CAMERA_GAIN);
|
||||||
energy.setEnergyInit();
|
energy.setBigEnergyInit();
|
||||||
checkReconnect(video_chassis->read(chassis_src));
|
checkReconnect(video_chassis->read(chassis_src));
|
||||||
#ifdef CHASSIS_FLIP_MODE
|
#ifdef CHASSIS_FLIP_MODE
|
||||||
flip(chassis_src, chassis_src, CHASSIS_FLIP_MODE);
|
flip(chassis_src, chassis_src, CHASSIS_FLIP_MODE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
ok = checkReconnect(video_gimbal->read(gimbal_src));
|
ok = checkReconnect(video_gimbal->read(gimbal_src));
|
||||||
video_gimbal->read(gimbal_src);
|
|
||||||
video_chassis->read(chassis_src);
|
video_chassis->read(chassis_src);
|
||||||
#ifdef GIMBAL_FLIP_MODE
|
#ifdef GIMBAL_FLIP_MODE
|
||||||
flip(gimbal_src, gimbal_src, GIMBAL_FLIP_MODE);
|
flip(gimbal_src, gimbal_src, GIMBAL_FLIP_MODE);
|
||||||
@@ -113,8 +110,23 @@ int main(int argc, char *argv[]) {
|
|||||||
if (!from_camera) extract(gimbal_src, chassis_src);
|
if (!from_camera) extract(gimbal_src, chassis_src);
|
||||||
if (save_video) saveVideos(gimbal_src, chassis_src);//保存视频
|
if (save_video) saveVideos(gimbal_src, chassis_src);//保存视频
|
||||||
if (show_origin) showOrigin(gimbal_src, chassis_src);//显示原始图像
|
if (show_origin) showOrigin(gimbal_src, chassis_src);//显示原始图像
|
||||||
// energy.run(gimbal_src, chassis_src);
|
// energy.runBig(gimbal_src, chassis_src);
|
||||||
energy.run(gimbal_src);
|
energy.runBig(gimbal_src);
|
||||||
|
last_state = mcuData.state;//更新上一帧状态
|
||||||
|
} else if (mcuData.state == SMALL_ENERGY_STATE) {
|
||||||
|
if (mcuData.state != SMALL_ENERGY_STATE) {
|
||||||
|
destroyAllWindows();
|
||||||
|
((CameraWrapper *) video_gimbal)->changeBrightness(ENERGY_CAMERA_GAIN);
|
||||||
|
energy.setSmallEnergyInit();
|
||||||
|
}
|
||||||
|
ok = checkReconnect(video_gimbal->read(gimbal_src));
|
||||||
|
#ifdef GIMBAL_FLIP_MODE
|
||||||
|
flip(gimbal_src, gimbal_src, GIMBAL_FLIP_MODE);
|
||||||
|
#endif
|
||||||
|
if (!from_camera) extract(gimbal_src);
|
||||||
|
if (save_video) saveVideos(gimbal_src);//保存视频
|
||||||
|
if (show_origin) showOrigin(gimbal_src);//显示原始图像
|
||||||
|
energy.runSmall(gimbal_src);
|
||||||
last_state = mcuData.state;//更新上一帧状态
|
last_state = mcuData.state;//更新上一帧状态
|
||||||
} else { // 自瞄模式
|
} else { // 自瞄模式
|
||||||
if (last_state != ARMOR_STATE) {
|
if (last_state != ARMOR_STATE) {
|
||||||
@@ -133,8 +145,8 @@ int main(int argc, char *argv[]) {
|
|||||||
armorFinder.run(gimbal_src);
|
armorFinder.run(gimbal_src);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
cv::waitKey(1);
|
// cv::waitKey(0);
|
||||||
});
|
// });
|
||||||
} while (ok);
|
} while (ok);
|
||||||
delete video_gimbal;
|
delete video_gimbal;
|
||||||
video_gimbal = nullptr;
|
video_gimbal = nullptr;
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public:
|
|||||||
bool readRaw(cv::Mat& src);
|
bool readRaw(cv::Mat& src);
|
||||||
bool readProcessed(cv::Mat& src);
|
bool readProcessed(cv::Mat& src);
|
||||||
bool changeBrightness(int brightness);
|
bool changeBrightness(int brightness);
|
||||||
|
// bool once
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,18 @@
|
|||||||
#ifndef ENERGY_CAMERA_GAIN
|
#ifndef ENERGY_CAMERA_GAIN
|
||||||
#define ENERGY_CAMERA_GAIN (20)
|
#define ENERGY_CAMERA_GAIN (20)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef AIM_KP
|
||||||
|
#define AIM_KP (6)
|
||||||
|
#endif
|
||||||
|
#ifndef AIM_KI
|
||||||
|
#define AIM_KI (0.1)
|
||||||
|
#endif
|
||||||
|
#ifndef COMPENSATE_YAW
|
||||||
|
#define COMPENSATE_YAW (5)
|
||||||
|
#endif
|
||||||
|
#ifndef COMPENSATE_PITCH
|
||||||
|
#define COMPENSATE_PITCH (74)
|
||||||
|
#endif
|
||||||
|
|
||||||
//#define GIMBAL_FLIP_MODE (-1)
|
//#define GIMBAL_FLIP_MODE (-1)
|
||||||
//#define CHASSIS_FLIP_MODE (-1)
|
//#define CHASSIS_FLIP_MODE (-1)
|
||||||
|
|||||||
@@ -30,27 +30,27 @@ extern ArmorFinder armorFinder;
|
|||||||
extern Energy energy;
|
extern Energy energy;
|
||||||
|
|
||||||
void uartReceive(Serial *pSerial) {
|
void uartReceive(Serial *pSerial) {
|
||||||
char buffer[20];
|
char buffer[30];
|
||||||
int cnt = 0;
|
|
||||||
LOGM(STR_CTR(WORD_LIGHT_WHITE, "data receive start!"));
|
LOGM(STR_CTR(WORD_LIGHT_WHITE, "data receive start!"));
|
||||||
while (true) {
|
while (true) {
|
||||||
char byte = 0;
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
while (pSerial->ReadData((uint8_t *) &byte, 1) && byte != '\n') {
|
pSerial->ReadData((uint8_t *) buffer, sizeof(mcuData)+1);
|
||||||
buffer[cnt++] = byte;
|
if (buffer[sizeof(mcuData)] == '\n') {
|
||||||
if (cnt >= sizeof(buffer)) {
|
|
||||||
// LOGE("data receive over flow!");
|
|
||||||
cnt = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cnt == 0 && byte == '\n') {
|
|
||||||
// LOGM("%d", cnt);
|
|
||||||
}
|
|
||||||
if (cnt == sizeof(mcuData)) {
|
|
||||||
memcpy(&mcuData, buffer, sizeof(mcuData));
|
memcpy(&mcuData, buffer, sizeof(mcuData));
|
||||||
// LOGM("Get, state:%c, mark:%d!", mcuData.state, (int) mcuData.mark);
|
// LOGM("Get, state:%c, mark:%d!", mcuData.state, (int) mcuData.mark);
|
||||||
|
// LOGM("Get yaw: %f, pitch: %f!", mcuData.curr_yaw, mcuData.curr_pitch);
|
||||||
|
// static int t = time(nullptr);
|
||||||
|
// static int cnt = 0;
|
||||||
|
// if(time(nullptr) > t){
|
||||||
|
// t = time(nullptr);
|
||||||
|
// LOGM("fps:%d", cnt);
|
||||||
|
// cnt = 0;
|
||||||
|
// }else{
|
||||||
|
// cnt++;
|
||||||
|
// }
|
||||||
|
}else{
|
||||||
|
// LOGW("corrupt data!");
|
||||||
}
|
}
|
||||||
cnt = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,12 +76,12 @@ cv::VideoWriter initVideoWriter(const std::string &filename_prefix) {
|
|||||||
bool checkReconnect(bool is_camera_0_connect, bool is_camera_1_connect) {
|
bool checkReconnect(bool is_camera_0_connect, bool is_camera_1_connect) {
|
||||||
if (!is_camera_0_connect) {
|
if (!is_camera_0_connect) {
|
||||||
delete video_gimbal;
|
delete video_gimbal;
|
||||||
video_gimbal = new CameraWrapper(0, "armor");
|
video_gimbal = new CameraWrapper(0/*, "armor"*/);
|
||||||
is_camera_0_connect = video_gimbal->init();
|
is_camera_0_connect = video_gimbal->init();
|
||||||
}
|
}
|
||||||
if (!is_camera_1_connect) {
|
if (!is_camera_1_connect) {
|
||||||
delete video_chassis;
|
delete video_chassis;
|
||||||
video_chassis = new CameraWrapper(1, "energy");
|
video_chassis = new CameraWrapper(1/*, "energy"*/);
|
||||||
is_camera_1_connect = video_chassis->init();
|
is_camera_1_connect = video_chassis->init();
|
||||||
}
|
}
|
||||||
return is_camera_0_connect && is_camera_1_connect;
|
return is_camera_0_connect && is_camera_1_connect;
|
||||||
@@ -90,7 +90,7 @@ bool checkReconnect(bool is_camera_0_connect, bool is_camera_1_connect) {
|
|||||||
bool checkReconnect(bool is_camera_connect) {
|
bool checkReconnect(bool is_camera_connect) {
|
||||||
if (!is_camera_connect) {
|
if (!is_camera_connect) {
|
||||||
delete video_gimbal;
|
delete video_gimbal;
|
||||||
video_gimbal = new CameraWrapper(0, "armor");
|
video_gimbal = new CameraWrapper(0/*, "armor"*/);
|
||||||
is_camera_connect = video_gimbal->init();
|
is_camera_connect = video_gimbal->init();
|
||||||
}
|
}
|
||||||
return is_camera_connect;
|
return is_camera_connect;
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ Serial::Serial(int nSpeed, char nEvent, int nBits, int nStop) :
|
|||||||
nSpeed(nSpeed), nEvent(nEvent), nBits(nBits), nStop(nStop) {
|
nSpeed(nSpeed), nEvent(nEvent), nBits(nBits), nStop(nStop) {
|
||||||
if (wait_uart) {
|
if (wait_uart) {
|
||||||
LOGM("Wait for serial be ready!");
|
LOGM("Wait for serial be ready!");
|
||||||
while (InitPort(nSpeed, nEvent, nBits, nStop) == false);
|
while (!InitPort(nSpeed, nEvent, nBits, nStop));
|
||||||
LOGM("Port set successfully!");
|
LOGM("Port set successfully!");
|
||||||
} else {
|
} else {
|
||||||
if (InitPort(nSpeed, nEvent, nBits, nStop)) {
|
if (InitPort(nSpeed, nEvent, nBits, nStop)) {
|
||||||
@@ -234,7 +234,7 @@ bool Serial::WriteData(const unsigned char *pData, unsigned int length) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while ((curr = write(fd, pData + cnt, length - cnt)) > 0 && (cnt += curr) < length);
|
while ((curr = write(fd, pData + cnt, length - cnt)) > 0 && (cnt += curr) < length);
|
||||||
if (cnt < 0) {
|
if (curr < 0) {
|
||||||
LOGE("Serial offline!");
|
LOGE("Serial offline!");
|
||||||
close(fd);
|
close(fd);
|
||||||
if (wait_uart) {
|
if (wait_uart) {
|
||||||
@@ -248,7 +248,7 @@ bool Serial::WriteData(const unsigned char *pData, unsigned int length) {
|
|||||||
bool Serial::ReadData(unsigned char *buffer, unsigned int length) {
|
bool Serial::ReadData(unsigned char *buffer, unsigned int length) {
|
||||||
int cnt = 0, curr = 0;
|
int cnt = 0, curr = 0;
|
||||||
while ((curr = read(fd, buffer + cnt, length - cnt)) > 0 && (cnt += curr) < length);
|
while ((curr = read(fd, buffer + cnt, length - cnt)) > 0 && (cnt += curr) < length);
|
||||||
if (cnt < 0) {
|
if (curr < 0) {
|
||||||
LOGE("Serial offline!");
|
LOGE("Serial offline!");
|
||||||
close(fd);
|
close(fd);
|
||||||
if (wait_uart) {
|
if (wait_uart) {
|
||||||
|
|||||||
@@ -54,16 +54,14 @@ def save_para(folder, paras):
|
|||||||
save_bias(fp, paras[7])
|
save_bias(fp, paras[7])
|
||||||
|
|
||||||
|
|
||||||
STEPS = 10000
|
STEPS = 100000
|
||||||
BATCH = 30
|
BATCH = 50
|
||||||
LEARNING_RATE_BASE = 0.005
|
LEARNING_RATE_BASE = 0.001
|
||||||
LEARNING_RATE_DECAY = 0.99
|
LEARNING_RATE_DECAY = 0.99
|
||||||
MOVING_AVERAGE_DECAY = 0.99
|
MOVING_AVERAGE_DECAY = 0.99
|
||||||
|
|
||||||
|
|
||||||
def train(dataset, show_bar=False):
|
def train(dataset, show_bar=False):
|
||||||
test_images, test_labels = dataset.all_test_sets()
|
|
||||||
|
|
||||||
x = tf.placeholder(tf.float32, [None, generate.SRC_ROWS, generate.SRC_COLS, generate.SRC_CHANNELS])
|
x = tf.placeholder(tf.float32, [None, generate.SRC_ROWS, generate.SRC_COLS, generate.SRC_CHANNELS])
|
||||||
y_= tf.placeholder(tf.float32, [None, forward.OUTPUT_NODES])
|
y_= tf.placeholder(tf.float32, [None, forward.OUTPUT_NODES])
|
||||||
keep_rate = tf.placeholder(tf.float32)
|
keep_rate = tf.placeholder(tf.float32)
|
||||||
@@ -103,11 +101,12 @@ def train(dataset, show_bar=False):
|
|||||||
|
|
||||||
_, loss_value, step = sess.run(
|
_, loss_value, step = sess.run(
|
||||||
[train_op, loss, global_step],
|
[train_op, loss, global_step],
|
||||||
feed_dict={x: images_samples, y_: labels_samples, keep_rate:0.5}
|
feed_dict={x: images_samples, y_: labels_samples, keep_rate:0.3}
|
||||||
)
|
)
|
||||||
|
|
||||||
if i % 100 == 0:
|
if i % 100 == 0:
|
||||||
if i % 1000 == 0:
|
if i % 500 == 0:
|
||||||
|
test_images, test_labels = dataset.sample_test_sets(10000)
|
||||||
acc = sess.run(accuracy, feed_dict={x: test_images, y_: test_labels, keep_rate:1.0})
|
acc = sess.run(accuracy, feed_dict={x: test_images, y_: test_labels, keep_rate:1.0})
|
||||||
bar.set_postfix({"loss": loss_value, "acc": acc})
|
bar.set_postfix({"loss": loss_value, "acc": acc})
|
||||||
|
|
||||||
@@ -116,6 +115,9 @@ def train(dataset, show_bar=False):
|
|||||||
vars_val = sess.run(vars)
|
vars_val = sess.run(vars)
|
||||||
save_para("/home/xinyang/Workspace/RM_auto-aim/tools/para", vars_val)
|
save_para("/home/xinyang/Workspace/RM_auto-aim/tools/para", vars_val)
|
||||||
print("save done!")
|
print("save done!")
|
||||||
|
|
||||||
|
# pred = sess.run(y, feed_dict={x: test_images, keep_rate:1.0})
|
||||||
|
|
||||||
# nodes_val = sess.run(nodes, feed_dict={x:test_images})
|
# nodes_val = sess.run(nodes, feed_dict={x:test_images})
|
||||||
# return vars_val, nodes_val
|
# return vars_val, nodes_val
|
||||||
DevList = mvsdk.CameraEnumerateDevice()
|
DevList = mvsdk.CameraEnumerateDevice()
|
||||||
|
|||||||
@@ -35,10 +35,10 @@ CONV1_OUTPUT_CHANNELS = 6
|
|||||||
CONV2_KERNAL_SIZE = 3
|
CONV2_KERNAL_SIZE = 3
|
||||||
|
|
||||||
# 第二层卷积输出通道数
|
# 第二层卷积输出通道数
|
||||||
CONV2_OUTPUT_CHANNELS = 10
|
CONV2_OUTPUT_CHANNELS = 12
|
||||||
|
|
||||||
# 第一层全连接宽度
|
# 第一层全连接宽度
|
||||||
FC1_OUTPUT_NODES = 16
|
FC1_OUTPUT_NODES = 30
|
||||||
|
|
||||||
# 第二层全连接宽度(输出标签类型数)
|
# 第二层全连接宽度(输出标签类型数)
|
||||||
FC2_OUTPUT_NODES = 15
|
FC2_OUTPUT_NODES = 15
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class DataSet:
|
|||||||
files = os.listdir(dir)
|
files = os.listdir(dir)
|
||||||
for file in tqdm(files, postfix={"loading id": i}, dynamic_ncols=True):
|
for file in tqdm(files, postfix={"loading id": i}, dynamic_ncols=True):
|
||||||
if file[-3:] == "jpg":
|
if file[-3:] == "jpg":
|
||||||
if random.random() > 0.2:
|
if random.random() > 0.7:
|
||||||
self.train_samples.append(self.file2nparray("%s/%s" % (dir, file)))
|
self.train_samples.append(self.file2nparray("%s/%s" % (dir, file)))
|
||||||
self.train_labels.append(self.id2label(i))
|
self.train_labels.append(self.id2label(i))
|
||||||
else:
|
else:
|
||||||
@@ -61,6 +61,15 @@ class DataSet:
|
|||||||
labels.append(self.train_labels[id])
|
labels.append(self.train_labels[id])
|
||||||
return np.array(samples), np.array(labels)
|
return np.array(samples), np.array(labels)
|
||||||
|
|
||||||
|
def sample_test_sets(self, length):
|
||||||
|
samples = []
|
||||||
|
labels = []
|
||||||
|
for i in range(length):
|
||||||
|
id = random.randint(0, len(self.test_samples)-1)
|
||||||
|
samples.append(self.test_samples[id])
|
||||||
|
labels.append(self.test_labels[id])
|
||||||
|
return np.array(samples), np.array(labels)
|
||||||
|
|
||||||
def all_train_sets(self):
|
def all_train_sets(self):
|
||||||
return self.train_samples[:], self.train_labels[:]
|
return self.train_samples[:], self.train_labels[:]
|
||||||
|
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
echo "#!/bin/bash" > $2/startup-run
|
echo "#!/bin/bash" > $2/startup-run
|
||||||
echo "$1/tools/auto-pull.sh" >> $2/startup-run
|
echo "$1/tools/auto-pull.sh" >> $2/startup-run
|
||||||
echo "gnome-terminal -- bash -c \"echo sjturm | sudo -S $1/tools/monitor.sh \\\"$2/run --run-with-camera --save-video --wait-uart --save-labelled-boxes --show-armor-box\\\"\"" >> $2/startup-run
|
echo "gnome-terminal -- bash -c \"echo sjturm | sudo -S $1/tools/monitor.sh \\\"$2/run --run-with-camera --save-video --wait-uart --save-labelled-boxes\\\"\"" >> $2/startup-run
|
||||||
chmod +x $2/startup-run
|
chmod +x $2/startup-run
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
6
|
6
|
||||||
-0.012731806
|
-0.20627302
|
||||||
-0.68924344
|
1.6024942
|
||||||
1.0428871
|
1.7967451
|
||||||
0.09240551
|
1.4466392
|
||||||
0.87806237
|
-0.098023266
|
||||||
-0.51778877
|
-0.006771178
|
||||||
|
|||||||
@@ -2,453 +2,453 @@
|
|||||||
6
|
6
|
||||||
5
|
5
|
||||||
5
|
5
|
||||||
-0.0705555
|
-0.10642219
|
||||||
0.086937346
|
0.54904705
|
||||||
0.297247
|
1.0220182
|
||||||
0.51908225
|
1.2654289
|
||||||
0.41566578
|
1.0080621
|
||||||
0.22415005
|
0.63893425
|
||||||
0.21470949
|
1.0596974
|
||||||
0.42054617
|
1.5017769
|
||||||
0.57512695
|
1.7486153
|
||||||
0.50255156
|
1.2255592
|
||||||
0.2663179
|
0.7572802
|
||||||
0.10764991
|
1.1565144
|
||||||
0.32504323
|
1.2662624
|
||||||
0.27210033
|
1.3252954
|
||||||
0.32694185
|
1.1559033
|
||||||
0.18968254
|
0.22455153
|
||||||
-0.03312495
|
0.46842065
|
||||||
-0.28554282
|
0.6101949
|
||||||
-0.27717206
|
0.6682584
|
||||||
0.010500877
|
0.1469474
|
||||||
-0.16386741
|
-0.19053003
|
||||||
-0.58856106
|
-0.30085373
|
||||||
-1.0167654
|
-0.505979
|
||||||
-0.59654444
|
-0.6151139
|
||||||
-0.07342564
|
-0.7488737
|
||||||
0.6650266
|
-0.67636555
|
||||||
0.6682501
|
-0.7467412
|
||||||
0.61575854
|
-0.7404055
|
||||||
0.20123789
|
-0.77479744
|
||||||
0.13246079
|
-0.75153095
|
||||||
0.9794644
|
-0.5121083
|
||||||
0.9181109
|
-0.580226
|
||||||
0.75080305
|
-0.57781655
|
||||||
0.5678118
|
-0.6191948
|
||||||
0.17880438
|
-0.4956569
|
||||||
0.8291312
|
-0.5530203
|
||||||
0.9157011
|
-0.54242903
|
||||||
0.8058578
|
-0.58190167
|
||||||
0.6174977
|
-0.808631
|
||||||
0.3349475
|
-0.5255669
|
||||||
0.93871576
|
-0.5567334
|
||||||
1.0840453
|
-0.65943664
|
||||||
0.9012157
|
-0.675188
|
||||||
0.6562343
|
-0.7753057
|
||||||
0.28151926
|
-0.5219072
|
||||||
0.8399793
|
-0.4224288
|
||||||
0.9920022
|
-0.4372446
|
||||||
0.64904636
|
-0.65674895
|
||||||
0.6055482
|
-0.88619053
|
||||||
0.15666491
|
-0.5918416
|
||||||
-0.8087083
|
0.45536855
|
||||||
-0.5565874
|
0.382092
|
||||||
-0.8960519
|
-0.017086059
|
||||||
-0.80074924
|
-0.4412066
|
||||||
-0.74640626
|
-0.32249
|
||||||
-0.2773623
|
0.5902474
|
||||||
-0.20795147
|
0.4910132
|
||||||
-0.1870408
|
0.02227385
|
||||||
-0.15045224
|
-0.4520488
|
||||||
-0.13983378
|
-0.6278883
|
||||||
-0.10816965
|
0.60164636
|
||||||
0.031628396
|
0.3453617
|
||||||
-0.116946414
|
0.16053873
|
||||||
-0.013991349
|
-0.39892384
|
||||||
0.21591163
|
-0.4782997
|
||||||
-0.18964738
|
0.56412727
|
||||||
0.0040286863
|
0.5470579
|
||||||
-0.30242768
|
0.33888572
|
||||||
-0.24229145
|
-0.025963284
|
||||||
0.23588136
|
0.010916833
|
||||||
-0.331128
|
0.7818745
|
||||||
-0.5470479
|
0.9463605
|
||||||
-0.7203085
|
0.72511697
|
||||||
-0.6601643
|
0.44537586
|
||||||
-0.05225026
|
0.35324848
|
||||||
0.45265025
|
-0.6419165
|
||||||
0.75259274
|
-0.347417
|
||||||
0.74857485
|
-0.40558645
|
||||||
0.7100708
|
-0.50654674
|
||||||
0.34476462
|
-0.44879192
|
||||||
0.46986035
|
-0.49447027
|
||||||
0.5765347
|
-0.31920582
|
||||||
0.6258838
|
-0.1661499
|
||||||
0.3804861
|
-0.4432326
|
||||||
0.3160558
|
-0.33963177
|
||||||
0.6183596
|
-0.38981852
|
||||||
0.59951615
|
-0.4906231
|
||||||
0.60037804
|
-0.45195618
|
||||||
0.6340707
|
-0.52474713
|
||||||
0.34009996
|
-0.39969632
|
||||||
0.7194144
|
-0.4819537
|
||||||
0.8571618
|
-0.71747667
|
||||||
0.94336456
|
-0.821255
|
||||||
0.90685135
|
-0.8445041
|
||||||
0.41317853
|
-0.89447993
|
||||||
1.0044444
|
-0.859059
|
||||||
1.0062212
|
-0.98320967
|
||||||
1.0895951
|
-1.0902424
|
||||||
0.92497915
|
-1.105878
|
||||||
0.7468299
|
-1.2187494
|
||||||
-1.2501324
|
0.67084956
|
||||||
-0.74794984
|
0.9035801
|
||||||
-0.047555014
|
1.2065095
|
||||||
0.49243745
|
1.3081064
|
||||||
0.8178278
|
1.2326727
|
||||||
-1.2034731
|
1.0170805
|
||||||
-0.49681732
|
1.0677104
|
||||||
0.015281494
|
1.5938762
|
||||||
0.60018766
|
1.4207084
|
||||||
0.713024
|
1.3485196
|
||||||
-0.84448695
|
1.0809016
|
||||||
-0.0899703
|
1.3998586
|
||||||
0.09781959
|
1.7368488
|
||||||
0.4817282
|
1.5395899
|
||||||
0.51024574
|
1.5694551
|
||||||
0.010328657
|
1.3630624
|
||||||
0.2768326
|
1.4492949
|
||||||
0.6458937
|
1.5428637
|
||||||
0.65859175
|
1.393225
|
||||||
0.39070535
|
1.4149159
|
||||||
0.60249025
|
1.1494107
|
||||||
1.1937758
|
1.2268404
|
||||||
0.9160051
|
1.2541622
|
||||||
0.8284883
|
0.96135026
|
||||||
0.53566974
|
0.90241027
|
||||||
-0.4362068
|
-0.31921467
|
||||||
-0.2836022
|
-0.110522695
|
||||||
-0.32180697
|
0.09325943
|
||||||
0.022249598
|
-0.0139649
|
||||||
0.29908466
|
-0.028535917
|
||||||
-0.5530434
|
-0.24136181
|
||||||
-0.4986115
|
0.03892438
|
||||||
-0.278484
|
0.20345062
|
||||||
-0.31018886
|
-0.074525945
|
||||||
-0.24363342
|
-0.029405555
|
||||||
-0.35979065
|
-0.07647651
|
||||||
-0.43008342
|
-0.15445644
|
||||||
-0.37437305
|
-0.058089375
|
||||||
-0.30203703
|
-0.40588626
|
||||||
-0.5734246
|
-0.27692583
|
||||||
0.02336341
|
-0.2698881
|
||||||
-0.25258422
|
-0.55068505
|
||||||
-0.3121478
|
-0.5919062
|
||||||
-0.6288646
|
-0.5438777
|
||||||
-0.4711073
|
-0.5993602
|
||||||
0.12114608
|
-0.7458306
|
||||||
-0.061813425
|
-0.81796175
|
||||||
-0.12937883
|
-0.94331497
|
||||||
-0.6477893
|
-1.0076928
|
||||||
-0.6810196
|
-0.8992378
|
||||||
1.8673725
|
1.9416478
|
||||||
2.8808968
|
3.2734282
|
||||||
3.1819828
|
4.160874
|
||||||
3.0621288
|
4.7219324
|
||||||
2.5003161
|
4.1175704
|
||||||
2.4616675
|
3.0404797
|
||||||
3.2074707
|
4.511751
|
||||||
3.5739362
|
5.663269
|
||||||
3.1081522
|
5.930972
|
||||||
2.4229178
|
4.7846756
|
||||||
2.4271266
|
3.3442042
|
||||||
3.280304
|
4.758655
|
||||||
3.0261867
|
5.6102233
|
||||||
2.3990371
|
5.5837803
|
||||||
1.8921077
|
4.3014107
|
||||||
2.005818
|
2.793397
|
||||||
2.4233122
|
3.7502306
|
||||||
2.1124473
|
4.3392096
|
||||||
1.5049059
|
4.142601
|
||||||
1.0315852
|
2.9172728
|
||||||
1.0267158
|
1.819791
|
||||||
0.8723091
|
2.428208
|
||||||
0.44316038
|
2.3962913
|
||||||
0.1576413
|
2.0173726
|
||||||
0.22018914
|
1.0743914
|
||||||
0.18436278
|
0.26512346
|
||||||
-0.04525133
|
0.3457875
|
||||||
-0.28330094
|
0.58334744
|
||||||
-0.50770444
|
0.40681112
|
||||||
-0.4281736
|
0.40550798
|
||||||
0.26419267
|
0.29478824
|
||||||
0.16408478
|
0.732128
|
||||||
0.19734842
|
0.8325436
|
||||||
-0.2016362
|
0.603493
|
||||||
-0.32106283
|
0.7258464
|
||||||
0.64052576
|
0.5068629
|
||||||
0.45036018
|
0.67576087
|
||||||
0.42224813
|
0.74854803
|
||||||
0.106944986
|
0.60851085
|
||||||
-0.15083833
|
0.77726454
|
||||||
0.9302013
|
0.3519754
|
||||||
0.7691678
|
0.468439
|
||||||
0.6336322
|
0.6548478
|
||||||
0.078011096
|
0.70905083
|
||||||
-0.031026825
|
0.3086395
|
||||||
0.80035543
|
0.4289891
|
||||||
0.60188663
|
0.47042668
|
||||||
0.38603687
|
0.37940606
|
||||||
-0.03504348
|
0.45548278
|
||||||
-0.19659142
|
0.14207979
|
||||||
0.61344516
|
0.71661115
|
||||||
0.8947993
|
0.09474261
|
||||||
0.97315925
|
-0.7471369
|
||||||
0.74691004
|
-1.7338398
|
||||||
0.49092364
|
-2.5905223
|
||||||
1.2537221
|
0.7082176
|
||||||
1.9796665
|
0.21243899
|
||||||
1.9934042
|
-0.6654869
|
||||||
1.6571536
|
-1.7607315
|
||||||
1.5510287
|
-2.7247927
|
||||||
1.7490395
|
0.6009304
|
||||||
2.4188108
|
0.10814533
|
||||||
2.487965
|
-0.6752587
|
||||||
2.0581145
|
-1.7909975
|
||||||
1.922978
|
-2.3464935
|
||||||
1.7984617
|
0.79290503
|
||||||
2.3430247
|
0.49252048
|
||||||
2.2450094
|
-0.43408415
|
||||||
1.9467311
|
-1.3109739
|
||||||
1.6972682
|
-1.9383324
|
||||||
1.2808937
|
0.9131795
|
||||||
1.5145483
|
0.58063436
|
||||||
1.4981558
|
-0.065964356
|
||||||
1.1744506
|
-0.84630096
|
||||||
1.2942766
|
-1.3107594
|
||||||
-0.028776312
|
0.9702296
|
||||||
0.08628688
|
1.7605543
|
||||||
0.14530973
|
1.9099594
|
||||||
0.060263254
|
1.8536079
|
||||||
-0.1992724
|
1.3434014
|
||||||
-0.3509845
|
1.1538997
|
||||||
-0.14943084
|
1.8189181
|
||||||
0.05269242
|
1.9872671
|
||||||
-0.047488246
|
2.0980296
|
||||||
-0.32251114
|
1.5539708
|
||||||
-0.055337034
|
0.9389947
|
||||||
-0.0606678
|
1.4959635
|
||||||
0.13780722
|
1.8016711
|
||||||
0.025866544
|
1.5903975
|
||||||
-0.2515092
|
1.2731018
|
||||||
0.36665168
|
0.78981453
|
||||||
0.4256815
|
1.0439569
|
||||||
0.44711438
|
1.3309318
|
||||||
0.45632693
|
1.2204188
|
||||||
0.18695426
|
0.78188473
|
||||||
0.83469534
|
0.41300166
|
||||||
0.73099476
|
0.4995686
|
||||||
0.90957487
|
0.52244127
|
||||||
0.7863896
|
0.5596004
|
||||||
0.60097635
|
0.21890602
|
||||||
-2.77742
|
0.30612093
|
||||||
-1.898205
|
0.85429645
|
||||||
-0.51413226
|
1.2398238
|
||||||
0.29049698
|
1.2750283
|
||||||
0.93399036
|
1.3086212
|
||||||
-2.6324046
|
1.0696554
|
||||||
-1.413464
|
1.3433759
|
||||||
-0.11643134
|
1.729579
|
||||||
0.7600749
|
1.7326889
|
||||||
1.0856903
|
1.7986484
|
||||||
-2.0343983
|
1.3991985
|
||||||
-0.7860615
|
1.7318608
|
||||||
0.3931903
|
2.0507987
|
||||||
1.0088302
|
1.941499
|
||||||
1.2542579
|
1.7631179
|
||||||
-1.0282527
|
1.4714234
|
||||||
0.00558986
|
1.8296314
|
||||||
0.7271341
|
1.9416764
|
||||||
1.2017635
|
1.8468171
|
||||||
0.9958149
|
1.6414593
|
||||||
0.2970806
|
1.4085735
|
||||||
1.2236876
|
1.5106102
|
||||||
1.36118
|
1.610607
|
||||||
1.3418391
|
1.5357318
|
||||||
0.8660408
|
1.1668565
|
||||||
-1.1435972
|
1.3847203
|
||||||
-0.83455884
|
1.9328053
|
||||||
-0.7378884
|
2.0932007
|
||||||
-0.20356347
|
1.6669843
|
||||||
0.21133415
|
1.3775337
|
||||||
-0.84094524
|
1.6736194
|
||||||
-1.1279244
|
2.307166
|
||||||
-0.6961366
|
2.3085163
|
||||||
-0.4854085
|
2.008549
|
||||||
-0.026166996
|
1.2341207
|
||||||
-0.54931265
|
1.6037624
|
||||||
-0.4710362
|
2.0786712
|
||||||
-0.7298363
|
1.9735341
|
||||||
-0.64001644
|
1.5647856
|
||||||
-0.62205493
|
1.02917
|
||||||
0.03693532
|
1.3709607
|
||||||
-0.40307578
|
1.4461753
|
||||||
-0.4964193
|
1.256765
|
||||||
-0.42969394
|
0.9555051
|
||||||
-0.5397872
|
0.36569837
|
||||||
0.3220369
|
0.7852095
|
||||||
0.14219745
|
0.7917901
|
||||||
-0.4169855
|
0.43664944
|
||||||
-0.48323318
|
0.2549527
|
||||||
-0.77415246
|
-0.067954175
|
||||||
-0.4052389
|
0.20057896
|
||||||
0.5951485
|
1.3856035
|
||||||
0.4901534
|
2.0629358
|
||||||
0.51781464
|
2.809679
|
||||||
0.026524775
|
2.3610249
|
||||||
0.19928466
|
0.83472407
|
||||||
0.8500332
|
2.064841
|
||||||
0.8974233
|
3.0214195
|
||||||
0.75791407
|
3.401786
|
||||||
0.29939106
|
2.7669187
|
||||||
0.1305985
|
1.1871954
|
||||||
0.94468176
|
2.2021434
|
||||||
0.8779284
|
2.9477324
|
||||||
0.47177282
|
3.2896252
|
||||||
0.018099217
|
2.3611999
|
||||||
-0.2669419
|
0.58470565
|
||||||
0.14852984
|
1.433704
|
||||||
0.17997491
|
1.8206064
|
||||||
-0.40414903
|
1.6048844
|
||||||
-0.57394934
|
1.0893
|
||||||
-0.8052322
|
0.079494156
|
||||||
-0.6834026
|
0.14756773
|
||||||
-0.9813351
|
0.21510047
|
||||||
-1.2330854
|
0.17841841
|
||||||
-1.1226501
|
-0.3402442
|
||||||
-0.2375166
|
0.82796144
|
||||||
-0.25760472
|
0.89763546
|
||||||
-0.6702083
|
0.9589713
|
||||||
-0.83058023
|
0.86110723
|
||||||
-0.845694
|
0.6416584
|
||||||
-0.035079293
|
1.0780864
|
||||||
0.15334488
|
1.2395475
|
||||||
-0.20645554
|
1.4097389
|
||||||
-0.6201716
|
1.1237956
|
||||||
-0.58026224
|
1.0438948
|
||||||
0.23743017
|
1.0541381
|
||||||
0.41283235
|
1.3774344
|
||||||
0.2761712
|
1.422105
|
||||||
-0.080429204
|
1.0753438
|
||||||
-0.5188592
|
0.956809
|
||||||
0.713986
|
0.99444
|
||||||
0.6536175
|
0.99848217
|
||||||
0.46903017
|
1.2054675
|
||||||
0.15473464
|
1.0716856
|
||||||
-0.28156337
|
0.8924131
|
||||||
0.5111026
|
0.67220867
|
||||||
0.42682606
|
0.89100254
|
||||||
0.4112979
|
0.7673037
|
||||||
0.07900778
|
0.74212146
|
||||||
-0.2720577
|
0.4557632
|
||||||
-0.4981358
|
1.4435326
|
||||||
-0.051663946
|
1.0917244
|
||||||
-0.023117686
|
0.5117782
|
||||||
-0.19846022
|
-0.042295564
|
||||||
-0.19126081
|
-0.3919759
|
||||||
0.29513282
|
1.3343437
|
||||||
0.93106616
|
1.0884248
|
||||||
0.9072645
|
0.5695666
|
||||||
0.5732627
|
0.095347434
|
||||||
0.26237917
|
-0.17561129
|
||||||
0.39974377
|
1.5594242
|
||||||
1.1159221
|
1.1927198
|
||||||
1.0814219
|
0.81222206
|
||||||
0.950581
|
0.10072425
|
||||||
0.671661
|
-0.01981995
|
||||||
0.48101172
|
1.4395866
|
||||||
1.0488389
|
1.4196151
|
||||||
1.003414
|
0.99251515
|
||||||
0.9169417
|
0.5299192
|
||||||
0.5284077
|
0.3711792
|
||||||
-0.20465238
|
1.7289668
|
||||||
0.40837994
|
1.5802932
|
||||||
0.26445296
|
1.4318615
|
||||||
0.16031574
|
0.9496403
|
||||||
0.18525025
|
0.90711755
|
||||||
-1.1795493
|
0.7756156
|
||||||
-1.0623146
|
1.6576271
|
||||||
-1.3544596
|
1.7558899
|
||||||
-1.3211613
|
1.423089
|
||||||
-1.4418778
|
1.063295
|
||||||
-1.2897592
|
0.9460997
|
||||||
-1.3648815
|
1.68862
|
||||||
-1.5633347
|
1.8560133
|
||||||
-1.4766223
|
1.7430701
|
||||||
-1.5375725
|
1.267287
|
||||||
-1.0636053
|
0.8309027
|
||||||
-1.0550519
|
1.4070404
|
||||||
-1.2028064
|
1.6903514
|
||||||
-1.3285335
|
1.5321271
|
||||||
-1.4901532
|
1.0099223
|
||||||
-0.59239966
|
0.26294753
|
||||||
-0.5102294
|
0.86975366
|
||||||
-0.7126663
|
0.8681627
|
||||||
-0.6390671
|
0.6666984
|
||||||
-0.88960606
|
0.39146528
|
||||||
0.11505768
|
-0.17483807
|
||||||
0.08690188
|
0.06906817
|
||||||
-0.012430734
|
0.0685056
|
||||||
-0.23703271
|
0.0048298114
|
||||||
-0.070601396
|
-0.29763746
|
||||||
-2.499217
|
-0.72470987
|
||||||
-1.5118762
|
-0.3025738
|
||||||
-0.63362616
|
0.1441088
|
||||||
0.34636214
|
0.6175989
|
||||||
0.80023897
|
0.71524495
|
||||||
-2.2490098
|
-0.08114317
|
||||||
-1.210647
|
0.23537244
|
||||||
-0.30495015
|
0.65833175
|
||||||
0.6582943
|
0.748487
|
||||||
0.92495674
|
0.7920688
|
||||||
-1.949688
|
0.08497454
|
||||||
-0.931986
|
0.5255702
|
||||||
0.08990933
|
0.82396054
|
||||||
0.8216611
|
1.130095
|
||||||
0.81956995
|
0.9759796
|
||||||
-1.0822672
|
0.31005707
|
||||||
-0.17065391
|
0.51547265
|
||||||
0.52672815
|
0.85156286
|
||||||
0.6972465
|
0.89206517
|
||||||
0.6062274
|
0.5910351
|
||||||
-0.1929201
|
0.28886735
|
||||||
0.5915268
|
0.5871289
|
||||||
0.72986585
|
0.55338776
|
||||||
0.88998604
|
0.54379845
|
||||||
0.5383484
|
0.27539033
|
||||||
0.69495237
|
1.3043873
|
||||||
0.8119897
|
2.1130838
|
||||||
1.0762402
|
2.00019
|
||||||
1.4192832
|
1.9147623
|
||||||
1.67176
|
1.2632021
|
||||||
0.63202345
|
1.6259333
|
||||||
0.958035
|
2.4304924
|
||||||
1.1269803
|
2.4733207
|
||||||
1.2325205
|
2.0936246
|
||||||
1.1469792
|
1.3039585
|
||||||
0.7853533
|
1.5398262
|
||||||
1.0906031
|
2.1048331
|
||||||
1.1132238
|
2.2389119
|
||||||
1.087981
|
1.5818008
|
||||||
1.0139153
|
0.94920427
|
||||||
1.3069341
|
1.1412464
|
||||||
1.2574402
|
1.5037223
|
||||||
1.2478752
|
1.2156814
|
||||||
1.1044679
|
1.0366565
|
||||||
0.7778477
|
0.3966581
|
||||||
1.4372398
|
0.37856415
|
||||||
1.3009509
|
0.6628915
|
||||||
1.2459791
|
0.5291198
|
||||||
0.84846544
|
0.11434809
|
||||||
0.73138183
|
-0.09481559
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
12
|
12
|
||||||
0.0336404
|
-0.6611704
|
||||||
0.81687707
|
1.472362
|
||||||
-0.088157885
|
-0.059240177
|
||||||
1.072176
|
0.6448027
|
||||||
-0.019678842
|
-0.09498331
|
||||||
-0.23005776
|
0.07005496
|
||||||
2.6509802
|
1.5227689
|
||||||
2.31109
|
1.6761788
|
||||||
2.8000503
|
1.3155555
|
||||||
-0.044337805
|
3.944478
|
||||||
-0.20568089
|
0.41402242
|
||||||
2.5650184
|
1.6400838
|
||||||
|
|||||||
1296
tools/para/conv2_w
1296
tools/para/conv2_w
File diff suppressed because it is too large
Load Diff
@@ -1,21 +1,31 @@
|
|||||||
20
|
30
|
||||||
-0.19178796
|
-0.7973528
|
||||||
-0.0275628
|
-0.16212165
|
||||||
0.45375344
|
-0.016621558
|
||||||
2.1090505
|
-0.010184621
|
||||||
-0.012145723
|
-0.02323284
|
||||||
0.2213703
|
-0.65347326
|
||||||
2.624133
|
0.3813474
|
||||||
-0.82816005
|
-0.01980829
|
||||||
0.25926802
|
0.014691165
|
||||||
-0.014570757
|
0.84623796
|
||||||
0.72068256
|
1.0044321
|
||||||
0.249013
|
0.9791296
|
||||||
2.195925
|
0.09865961
|
||||||
-0.014568891
|
0.32203308
|
||||||
-0.59766585
|
0.008520375
|
||||||
-0.020068042
|
-0.27646253
|
||||||
-0.05986349
|
-0.034938164
|
||||||
-1.3474371
|
-0.0024497542
|
||||||
-0.49981204
|
-0.035473134
|
||||||
0.6370428
|
0.28444487
|
||||||
|
-0.7223666
|
||||||
|
-0.43071944
|
||||||
|
-0.27131405
|
||||||
|
0.18943691
|
||||||
|
-0.7551859
|
||||||
|
0.22790527
|
||||||
|
-0.19145727
|
||||||
|
0.3364544
|
||||||
|
0.8732161
|
||||||
|
0.93184555
|
||||||
|
|||||||
42000
tools/para/fc1_w
42000
tools/para/fc1_w
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,16 @@
|
|||||||
15
|
15
|
||||||
1.8846483
|
0.74399966
|
||||||
0.426767
|
0.65725124
|
||||||
-0.43499732
|
0.28723997
|
||||||
-0.86950755
|
-0.28500625
|
||||||
-1.4404491
|
-0.6551816
|
||||||
-1.6620952
|
-0.5096106
|
||||||
0.43332458
|
0.6995224
|
||||||
-0.047994245
|
0.47489655
|
||||||
-0.8123727
|
-0.637414
|
||||||
0.097763464
|
-0.14589947
|
||||||
-0.61916274
|
-0.6946489
|
||||||
0.20783848
|
0.06361784
|
||||||
-1.0543438
|
-0.9587668
|
||||||
0.42724028
|
0.33230728
|
||||||
0.7927464
|
0.01565033
|
||||||
|
|||||||
752
tools/para/fc2_w
752
tools/para/fc2_w
@@ -1,302 +1,452 @@
|
|||||||
20
|
30
|
||||||
15
|
15
|
||||||
3.1785574e-34
|
0.01272495
|
||||||
1.5611281e-34
|
-0.10762496
|
||||||
-1.5863359e-34
|
0.029348347
|
||||||
-2.1766939e-34
|
0.043351036
|
||||||
-2.3130055e-34
|
0.014999958
|
||||||
-2.662751e-34
|
-0.06224802
|
||||||
-3.2626066e-34
|
-0.023997843
|
||||||
2.8627675e-34
|
0.02832638
|
||||||
2.7861122e-34
|
-0.041784886
|
||||||
-2.9668104e-34
|
0.0986206
|
||||||
3.0360296e-34
|
0.071423925
|
||||||
2.9419657e-34
|
0.071765825
|
||||||
3.1102713e-34
|
-0.0512679
|
||||||
-2.8726263e-34
|
-0.044301357
|
||||||
3.0484892e-34
|
-0.013093688
|
||||||
4.3197746e-34
|
-0.11556479
|
||||||
-1.8445088e-34
|
0.03982802
|
||||||
-3.530525e-34
|
0.09731361
|
||||||
-3.5233124e-34
|
0.00295955
|
||||||
2.2262768e-34
|
-0.03545694
|
||||||
1.2378974e-34
|
-0.006381662
|
||||||
3.7615624e-34
|
0.02806398
|
||||||
-2.2716454e-34
|
0.0045560263
|
||||||
2.5169786e-34
|
0.05397426
|
||||||
-3.353324e-34
|
0.03402133
|
||||||
3.5685113e-34
|
-0.036305163
|
||||||
-4.122433e-34
|
-0.043878928
|
||||||
1.7969215e-34
|
-0.0142929
|
||||||
5.2897058e-34
|
0.017667498
|
||||||
2.3318663e-34
|
-0.025763642
|
||||||
0.022835148
|
4.463302e-34
|
||||||
-0.029413782
|
7.2691345e-34
|
||||||
-0.12952074
|
8.845337e-34
|
||||||
0.18896067
|
1.0892352e-33
|
||||||
-0.06554771
|
4.7136717e-34
|
||||||
0.11628288
|
8.0413215e-35
|
||||||
-0.06948121
|
9.200099e-34
|
||||||
-0.025129182
|
-4.0106226e-36
|
||||||
0.009227986
|
4.1104475e-34
|
||||||
-0.10632306
|
5.224466e-35
|
||||||
0.21482462
|
2.8301181e-34
|
||||||
-0.09871392
|
-8.116642e-34
|
||||||
0.089015536
|
-3.1305442e-34
|
||||||
-0.008572652
|
-2.6887943e-34
|
||||||
-0.028414002
|
-2.190287e-34
|
||||||
0.08512151
|
-1.0852689e-33
|
||||||
-0.21057208
|
-3.8716697e-34
|
||||||
0.12899724
|
-3.4582993e-34
|
||||||
-0.121678144
|
4.0845394e-34
|
||||||
-0.044324484
|
-4.580933e-34
|
||||||
0.012617375
|
-5.545946e-34
|
||||||
0.23971003
|
-6.0027574e-34
|
||||||
-0.029345443
|
8.783881e-34
|
||||||
-0.10093057
|
1.1282351e-33
|
||||||
0.13569276
|
2.8688931e-34
|
||||||
-0.05262047
|
-6.931309e-34
|
||||||
-0.057448562
|
-7.412748e-34
|
||||||
-0.057186298
|
6.843897e-34
|
||||||
0.22441685
|
-1.07383705e-33
|
||||||
-0.09055193
|
-4.422186e-34
|
||||||
-2.5289643e-34
|
4.9493538e-34
|
||||||
1.7009551e-34
|
-3.3879648e-34
|
||||||
-3.9381888e-36
|
-2.5583285e-34
|
||||||
2.326881e-34
|
-9.684053e-38
|
||||||
-2.8111998e-34
|
1.1755804e-33
|
||||||
-3.5335243e-35
|
5.0118e-34
|
||||||
-1.1998445e-34
|
-6.8979133e-35
|
||||||
-3.4805974e-34
|
5.570329e-34
|
||||||
1.8599213e-34
|
2.0730477e-34
|
||||||
-1.7831123e-34
|
-6.9826827e-35
|
||||||
1.1460405e-34
|
1.7651477e-34
|
||||||
2.0934657e-34
|
6.505341e-34
|
||||||
1.563032e-34
|
1.1404848e-33
|
||||||
-1.0113456e-35
|
3.768194e-36
|
||||||
2.4719906e-35
|
-8.696617e-34
|
||||||
-0.12601055
|
1.6646721e-33
|
||||||
0.19141342
|
1.5833977e-33
|
||||||
-0.069146484
|
-1.16577035e-33
|
||||||
-0.0025679446
|
1.3946439e-33
|
||||||
-0.11021721
|
-1.6903357e-33
|
||||||
-0.047209635
|
1.18764e-33
|
||||||
0.121572815
|
-1.4414919e-33
|
||||||
-0.021320255
|
1.4874023e-33
|
||||||
0.17498343
|
-1.4271845e-33
|
||||||
-0.07666946
|
-1.5428872e-33
|
||||||
-0.03474931
|
-1.5855378e-33
|
||||||
-0.053848345
|
-1.5143901e-33
|
||||||
0.038261224
|
1.4189191e-33
|
||||||
0.09783123
|
-1.4440388e-33
|
||||||
-0.04364654
|
1.333818e-33
|
||||||
0.2465007
|
0.17302258
|
||||||
0.1849186
|
-0.027978221
|
||||||
-0.052974403
|
0.016748061
|
||||||
-0.064460956
|
-0.059101477
|
||||||
-0.0467655
|
-0.02370323
|
||||||
-0.036299426
|
0.055812847
|
||||||
-0.08964782
|
-0.027396126
|
||||||
-0.022229096
|
0.0083711
|
||||||
0.20783813
|
-0.019884026
|
||||||
-0.08701921
|
-0.02066343
|
||||||
-0.021651257
|
-0.005153278
|
||||||
-0.007302513
|
-0.010312685
|
||||||
-0.08308651
|
0.029041208
|
||||||
-0.07215878
|
-0.050187044
|
||||||
-0.0007826862
|
-0.024670767
|
||||||
-6.1247035e-34
|
-2.6037262e-33
|
||||||
4.463276e-34
|
-2.611591e-33
|
||||||
5.4647075e-34
|
2.4881792e-33
|
||||||
-5.3594374e-34
|
2.7212167e-33
|
||||||
-7.624689e-35
|
-2.5234833e-33
|
||||||
4.547081e-34
|
-2.2103461e-33
|
||||||
-4.9066397e-34
|
1.9122722e-33
|
||||||
-3.6748373e-34
|
9.588927e-34
|
||||||
-5.033634e-34
|
2.7108281e-33
|
||||||
5.2652385e-34
|
-2.3352854e-33
|
||||||
-5.817056e-34
|
-2.7606323e-33
|
||||||
-4.3149362e-34
|
-2.5427623e-33
|
||||||
5.304378e-34
|
2.6146137e-33
|
||||||
5.2734927e-34
|
2.4776098e-33
|
||||||
4.9347583e-34
|
2.5404514e-33
|
||||||
0.057774916
|
0.06246555
|
||||||
0.091525115
|
0.10426002
|
||||||
0.14736745
|
-0.052243777
|
||||||
0.13339345
|
0.017077662
|
||||||
0.15654251
|
-0.03715354
|
||||||
0.09139076
|
-0.018698398
|
||||||
0.12214476
|
-0.06796197
|
||||||
0.106167495
|
0.03528635
|
||||||
-0.1375304
|
0.06418046
|
||||||
-0.11402692
|
-0.000768907
|
||||||
-0.07316204
|
-0.026170308
|
||||||
-0.08932755
|
-0.019549962
|
||||||
-0.11316809
|
0.054662388
|
||||||
-0.10894508
|
-0.044521194
|
||||||
-0.12546284
|
-0.07334332
|
||||||
-3.2000347e-34
|
0.04758694
|
||||||
-2.36952e-34
|
-0.08954524
|
||||||
-2.2271435e-34
|
0.09964462
|
||||||
2.732874e-34
|
-0.031682633
|
||||||
-2.5469592e-34
|
-0.015182594
|
||||||
2.4332584e-34
|
-0.039172467
|
||||||
2.4015109e-34
|
0.07632043
|
||||||
2.305403e-34
|
-0.01974726
|
||||||
-1.0759744e-34
|
-0.08796382
|
||||||
1.7449821e-34
|
0.087372005
|
||||||
-2.3276338e-34
|
-0.016114255
|
||||||
-1.6425085e-34
|
-0.025341872
|
||||||
2.3379538e-34
|
-0.021241697
|
||||||
-1.2265797e-35
|
0.075716406
|
||||||
-2.2131944e-34
|
-0.027058382
|
||||||
-0.007536282
|
-0.015432766
|
||||||
-0.015670829
|
0.0073655327
|
||||||
-0.044145193
|
-0.01209919
|
||||||
-0.06925844
|
-0.041824125
|
||||||
-0.038289294
|
-0.006816338
|
||||||
0.04218386
|
0.0045526098
|
||||||
-0.028006999
|
-0.0005398891
|
||||||
0.19194373
|
0.13293515
|
||||||
-0.008162281
|
-0.014088044
|
||||||
-0.04310273
|
-0.04277335
|
||||||
-0.032295864
|
-0.046146225
|
||||||
-0.013634144
|
-0.011611434
|
||||||
0.012049367
|
-0.013375685
|
||||||
-0.04765994
|
-0.017687852
|
||||||
0.15002576
|
0.099150814
|
||||||
0.028484903
|
0.035996642
|
||||||
-0.12657242
|
0.016294181
|
||||||
-0.10019828
|
-0.08048032
|
||||||
-0.021912435
|
-0.041648608
|
||||||
-0.07220948
|
-0.012340834
|
||||||
-0.07850285
|
-0.024473786
|
||||||
-0.11347996
|
0.16153657
|
||||||
-0.084765114
|
-0.026676055
|
||||||
0.099906415
|
0.04658439
|
||||||
0.07358634
|
-0.052000005
|
||||||
0.085178904
|
-0.026849354
|
||||||
0.04134392
|
-0.03671153
|
||||||
0.09367139
|
-0.03710232
|
||||||
0.11517161
|
0.1337519
|
||||||
0.15800452
|
-0.031022256
|
||||||
0.2303931
|
-0.01850948
|
||||||
-0.04586972
|
0.01128599
|
||||||
-0.08725446
|
0.090702474
|
||||||
-0.033236336
|
-0.008731814
|
||||||
0.1308958
|
-0.00024545888
|
||||||
-0.036943685
|
-0.010025267
|
||||||
-0.014320934
|
-0.039491266
|
||||||
-0.0052397517
|
-0.020047752
|
||||||
-0.013388744
|
0.034077633
|
||||||
-0.024721963
|
0.019151518
|
||||||
-0.05172364
|
-0.017094668
|
||||||
0.03730736
|
-0.01866218
|
||||||
-0.02536234
|
-0.017035574
|
||||||
-0.04374987
|
0.005504165
|
||||||
-0.033061035
|
-0.0069074775
|
||||||
-0.0024779101
|
-0.00089758425
|
||||||
0.000728523
|
-0.0016957085
|
||||||
3.03098e-06
|
0.00025294858
|
||||||
-0.0006537406
|
-0.002470556
|
||||||
0.0014257621
|
-0.00253977
|
||||||
7.1307574e-07
|
-0.0026819948
|
||||||
2.82788e-05
|
-0.001282234
|
||||||
-1.4571673e-08
|
-0.0027133073
|
||||||
-9.1665876e-05
|
0.0060566748
|
||||||
-0.0005169288
|
-0.0017536315
|
||||||
-0.00088055246
|
-0.0004967247
|
||||||
0.0009669605
|
-0.004892902
|
||||||
0.0002642583
|
0.0044350573
|
||||||
7.58049e-06
|
-0.0026093745
|
||||||
5.0228886e-05
|
0.003550591
|
||||||
4.1370527e-34
|
0.04047877
|
||||||
-2.3665282e-34
|
0.05901869
|
||||||
2.6231246e-34
|
0.043092217
|
||||||
3.7994393e-34
|
0.08706535
|
||||||
4.0085556e-34
|
0.077308305
|
||||||
-2.6690339e-34
|
0.044446126
|
||||||
1.8781805e-34
|
0.051501554
|
||||||
-1.982984e-34
|
0.017045613
|
||||||
-3.0113217e-34
|
-0.056876663
|
||||||
-2.1200167e-34
|
-0.051144525
|
||||||
-2.0077406e-35
|
-0.050281346
|
||||||
3.0132427e-34
|
-0.011186705
|
||||||
-3.0806865e-34
|
-0.055486917
|
||||||
-1.9560212e-34
|
-0.0782539
|
||||||
1.2020748e-34
|
-0.0805333
|
||||||
4.1127485e-34
|
-0.043732617
|
||||||
-3.2173455e-34
|
-0.0068375436
|
||||||
4.0228943e-34
|
-0.03201547
|
||||||
-3.1162013e-34
|
-0.059948742
|
||||||
-5.1426757e-34
|
0.05957991
|
||||||
2.6755438e-34
|
0.067795284
|
||||||
3.6094879e-34
|
-0.04184092
|
||||||
-4.8759634e-34
|
0.004160195
|
||||||
3.4464383e-34
|
0.008685335
|
||||||
-2.8995517e-34
|
-0.054342967
|
||||||
-3.1393783e-34
|
-0.033768225
|
||||||
-2.2658088e-34
|
0.11686653
|
||||||
-3.3108237e-34
|
0.081372775
|
||||||
-1.3505708e-35
|
-0.017015154
|
||||||
2.4738205e-34
|
-0.023423227
|
||||||
3.783955e-34
|
8.78021e-34
|
||||||
3.6061226e-34
|
8.345785e-34
|
||||||
3.193828e-34
|
7.4883407e-34
|
||||||
3.7868991e-34
|
8.48771e-34
|
||||||
3.6567402e-34
|
8.274504e-34
|
||||||
-3.0349225e-34
|
8.027745e-34
|
||||||
3.3677782e-34
|
8.773579e-34
|
||||||
2.8857424e-34
|
8.519454e-34
|
||||||
2.5269046e-34
|
-8.11835e-34
|
||||||
2.2737943e-34
|
-7.688669e-34
|
||||||
-2.65504e-34
|
8.082543e-34
|
||||||
-2.732385e-34
|
-7.3258576e-34
|
||||||
2.6953094e-34
|
-8.51516e-34
|
||||||
2.9642443e-34
|
7.221161e-34
|
||||||
2.6588915e-34
|
7.827067e-34
|
||||||
-0.07233555
|
1.2615198e-33
|
||||||
-0.030644806
|
1.0976719e-33
|
||||||
0.014339875
|
1.1967251e-33
|
||||||
0.010646929
|
-1.0436973e-33
|
||||||
0.15107094
|
-8.499446e-34
|
||||||
-0.04039454
|
2.2683726e-34
|
||||||
-0.1018803
|
-1.3970104e-33
|
||||||
-0.024136122
|
1.5193663e-33
|
||||||
0.013392502
|
1.2094788e-33
|
||||||
-0.0011950728
|
-1.133173e-33
|
||||||
0.06232135
|
-1.2547036e-33
|
||||||
0.20024493
|
-1.4050951e-33
|
||||||
-0.06713317
|
-1.4054403e-33
|
||||||
-0.08364978
|
-1.142544e-33
|
||||||
-0.010007126
|
1.0450027e-33
|
||||||
0.073318966
|
7.6956433e-34
|
||||||
0.0020213877
|
8.744477e-34
|
||||||
0.015295026
|
-3.8514544e-35
|
||||||
-0.09381448
|
4.8746516e-34
|
||||||
0.018438634
|
-9.3443655e-34
|
||||||
0.15810835
|
-1.3859844e-34
|
||||||
-0.122952715
|
-1.2412909e-34
|
||||||
-0.06948898
|
-1.6619894e-34
|
||||||
-0.03245277
|
-1.0620242e-33
|
||||||
-0.07937658
|
1.4781585e-34
|
||||||
-0.074316666
|
-7.03722e-34
|
||||||
0.14917618
|
6.034873e-34
|
||||||
0.21517377
|
4.964442e-34
|
||||||
-0.07048892
|
6.136231e-34
|
||||||
-0.060168184
|
8.249319e-34
|
||||||
0.02568059
|
0.008318748
|
||||||
-0.04876075
|
0.041124124
|
||||||
0.19848819
|
-0.016857537
|
||||||
0.073280066
|
-0.04932119
|
||||||
-0.09127431
|
-0.0122754285
|
||||||
-0.040448762
|
0.10398687
|
||||||
-0.11075618
|
-0.015096632
|
||||||
-0.0018404849
|
-0.0022395186
|
||||||
-0.04922203
|
-0.015617358
|
||||||
0.22584344
|
0.036401253
|
||||||
0.08676703
|
-0.060664278
|
||||||
0.023621265
|
0.010920629
|
||||||
-0.02429366
|
0.053897887
|
||||||
-0.13942361
|
-0.030621164
|
||||||
-0.047222435
|
-0.030898456
|
||||||
|
-0.032895576
|
||||||
|
-0.102701336
|
||||||
|
-0.026651151
|
||||||
|
0.11469333
|
||||||
|
-0.063634604
|
||||||
|
0.06844623
|
||||||
|
-0.018467609
|
||||||
|
0.00821091
|
||||||
|
-0.07843062
|
||||||
|
-0.0055042044
|
||||||
|
0.090303816
|
||||||
|
-0.046396058
|
||||||
|
0.075963
|
||||||
|
0.03063942
|
||||||
|
0.020872513
|
||||||
|
-0.01299387
|
||||||
|
-0.0037207452
|
||||||
|
-0.0242024
|
||||||
|
0.06550928
|
||||||
|
-0.024706954
|
||||||
|
0.014491363
|
||||||
|
-0.011790568
|
||||||
|
-0.0025269324
|
||||||
|
-0.004879747
|
||||||
|
-0.030484857
|
||||||
|
0.0600873
|
||||||
|
-0.023517173
|
||||||
|
0.03269997
|
||||||
|
0.0051519005
|
||||||
|
-0.012163694
|
||||||
|
1.1904957e-33
|
||||||
|
1.0479699e-33
|
||||||
|
5.779416e-34
|
||||||
|
1.1540947e-33
|
||||||
|
-9.659636e-34
|
||||||
|
-1.0160334e-33
|
||||||
|
-8.223222e-34
|
||||||
|
8.918577e-34
|
||||||
|
1.0935816e-33
|
||||||
|
-9.294705e-34
|
||||||
|
-1.1592887e-33
|
||||||
|
9.246344e-34
|
||||||
|
1.180318e-33
|
||||||
|
-9.126836e-34
|
||||||
|
1.1287711e-33
|
||||||
|
0.026146693
|
||||||
|
0.09916242
|
||||||
|
-0.043090336
|
||||||
|
0.0017119434
|
||||||
|
0.0016878549
|
||||||
|
-0.017987054
|
||||||
|
-0.049805358
|
||||||
|
-0.022761522
|
||||||
|
0.092246346
|
||||||
|
-0.040928245
|
||||||
|
0.06459246
|
||||||
|
-0.017492786
|
||||||
|
-0.0049494132
|
||||||
|
-0.04219089
|
||||||
|
-0.03418938
|
||||||
|
-1.7006182e-33
|
||||||
|
-1.4530463e-33
|
||||||
|
1.42898475e-33
|
||||||
|
1.5074225e-33
|
||||||
|
-1.3642416e-33
|
||||||
|
-1.4290173e-33
|
||||||
|
1.4108531e-33
|
||||||
|
-1.2353524e-33
|
||||||
|
1.5234947e-33
|
||||||
|
-1.3775423e-33
|
||||||
|
1.4153025e-33
|
||||||
|
1.3714305e-33
|
||||||
|
-1.484371e-33
|
||||||
|
-1.44253985e-33
|
||||||
|
1.3046794e-33
|
||||||
|
0.044514116
|
||||||
|
-0.000882356
|
||||||
|
-0.0096916985
|
||||||
|
-0.04236413
|
||||||
|
0.091675386
|
||||||
|
-0.023483241
|
||||||
|
0.014011558
|
||||||
|
-0.004130279
|
||||||
|
-0.036856808
|
||||||
|
-0.033731807
|
||||||
|
-0.012403026
|
||||||
|
0.002606612
|
||||||
|
0.017260972
|
||||||
|
0.015992519
|
||||||
|
-0.015452466
|
||||||
|
0.07528171
|
||||||
|
-0.021592995
|
||||||
|
-0.06897829
|
||||||
|
0.0042408453
|
||||||
|
-0.027098294
|
||||||
|
-0.06743852
|
||||||
|
-0.09114424
|
||||||
|
-0.10261911
|
||||||
|
0.10710511
|
||||||
|
0.049893394
|
||||||
|
0.059722904
|
||||||
|
0.04513747
|
||||||
|
0.053101413
|
||||||
|
0.041433763
|
||||||
|
0.09596609
|
||||||
|
0.09589958
|
||||||
|
-0.025171956
|
||||||
|
-0.0013778559
|
||||||
|
-0.016897377
|
||||||
|
-0.022183804
|
||||||
|
-0.00023300173
|
||||||
|
-0.0065004122
|
||||||
|
0.0055662235
|
||||||
|
-0.014621925
|
||||||
|
0.0004447254
|
||||||
|
0.00226211
|
||||||
|
-0.011209562
|
||||||
|
-0.0183207
|
||||||
|
-0.011526959
|
||||||
|
0.005361926
|
||||||
|
0.17491823
|
||||||
|
-0.018875118
|
||||||
|
0.03126051
|
||||||
|
-0.039963342
|
||||||
|
-0.033307772
|
||||||
|
0.0015879893
|
||||||
|
-0.041357704
|
||||||
|
-0.0036194928
|
||||||
|
-0.03158664
|
||||||
|
-0.004237409
|
||||||
|
-0.034398682
|
||||||
|
-0.017561572
|
||||||
|
0.023918597
|
||||||
|
-0.0046276804
|
||||||
|
-0.011843316
|
||||||
|
0.023838982
|
||||||
|
0.11698544
|
||||||
|
-0.036167253
|
||||||
|
-0.019597769
|
||||||
|
-0.012699235
|
||||||
|
-0.012540517
|
||||||
|
-0.03393306
|
||||||
|
-0.0059446017
|
||||||
|
-0.00016750683
|
||||||
|
0.0014437584
|
||||||
|
-0.0015821535
|
||||||
|
-0.0019046782
|
||||||
|
-0.0021211132
|
||||||
|
-0.02051653
|
||||||
|
-0.008041249
|
||||||
|
|||||||
Reference in New Issue
Block a user