# Conflicts:
#	main.cpp
This commit is contained in:
sun
2019-07-09 13:59:02 +08:00
29 changed files with 12997 additions and 13089 deletions

View File

@@ -1,17 +1,11 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(AutoAim)
PROJECT(SJTU-RM-CV)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_BUILD_TYPE RELEASE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPATH=\"\\\"${PROJECT_SOURCE_DIR}\\\"\"")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${CMAKE_SYSTEM_NAME}")
# Todo
## 使用编译期固定选项,以略微提升性能。
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFIX_OPTIONS")
## 固定使用相机运行
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DRUN_WITH_CAMERA")
SET(BIN_NAME "run")
FIND_PROGRAM(CCACHE_FOUND ccache)
@@ -21,7 +15,6 @@ IF(CCACHE_FOUND)
MESSAGE("< Use ccache for compiler >")
ENDIF()
FIND_PACKAGE(Eigen3 REQUIRED)
FIND_PACKAGE(OpenCV 3 REQUIRED)
FIND_PACKAGE(Threads)
@@ -34,7 +27,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/armor/include)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/others/include)
FILE(GLOB_RECURSE sourcefiles "others/src/*.cpp" "energy/src/*cpp" "armor/src/*.cpp")
ADD_EXECUTABLE(${BIN_NAME} main.cpp ${sourcefiles} )
ADD_EXECUTABLE(${BIN_NAME} main.cpp ${sourcefiles} others/include/constants.h)
TARGET_LINK_LIBRARIES(${BIN_NAME} ${CMAKE_THREAD_LIBS_INIT})
TARGET_LINK_LIBRARIES(${BIN_NAME} ${OpenCV_LIBS})
@@ -51,4 +44,5 @@ ELSE ()
MESSAGE(STATUS "Unsupport platform: ${CMAKE_SYSTEM_NAME}")
ENDIF()
ADD_CUSTOM_TARGET(create-startup COMMAND "${PROJECT_SOURCE_DIR}/tools/create-startup.sh" "${PROJECT_SOURCE_DIR}" "${CMAKE_BINARY_DIR}")
ADD_CUSTOM_TARGET(create-startup COMMAND "${PROJECT_SOURCE_DIR}/tools/create-startup.sh" "${PROJECT_SOURCE_DIR}" "${CMAKE_BINARY_DIR}")
ADD_CUSTOM_TARGET(train-cnn COMMAND "gnome-terminal" "--" "bash" "-c" "${PROJECT_SOURCE_DIR}/tools/TrainCNN/backward.py")

View File

@@ -5,61 +5,62 @@
#ifndef _ARMOR_FINDER_H_
#define _ARMOR_FINDER_H_
#include <map>
#include <constants.h>
#include <opencv2/core.hpp>
#include <opencv2/tracking.hpp>
#include <serial/serial.h>
#include <armor_finder/classifier/classifier.h>
#include "additions/additions.h"
class ArmorFinder{
public:
ArmorFinder(uint8_t &color, Serial &u, string paras_folder, const uint8_t &use);
~ArmorFinder() = default;
private:
typedef cv::TrackerKCF TrackerToUse;
typedef enum{
SEARCHING_STATE, TRACKING_STATE, STANDBY_STATE
} State;
const uint8_t &enemy_color;
State state;
cv::Rect2d armor_box;
int boxid;
cv::Ptr<cv::Tracker> tracker;
cv::Mat src_gray;
Classifier classifier;
int contour_area;
Serial &serial;
const uint8_t &use_classifier;
bool stateSearchingTarget(cv::Mat &src);
bool stateTrackingTarget(cv::Mat &src);
bool stateStandBy();
public:
void run(cv::Mat &src);
bool sendBoxPosition();
};
#include <additions/additions.h>
#define BLOB_RED ENEMY_RED
#define BLOB_BLUE ENEMY_BLUE
extern std::map<int, string> id2name; //装甲板id到名称的map
extern std::map<string, int> name2id; //装甲板名称到id的map
/********************* 自瞄类定义 **********************/
class ArmorFinder{
public:
ArmorFinder(uint8_t &color, Serial &u, const string &paras_folder, const uint8_t &use);
~ArmorFinder() = default;
private:
typedef cv::TrackerKCF TrackerToUse; // Tracker类型定义
typedef enum{
SEARCHING_STATE, TRACKING_STATE, STANDBY_STATE
} State; // 自瞄状态枚举定义
const uint8_t &enemy_color; // 敌方颜色,引用外部变量,自动变化
State state; // 自瞄状态对象实例
cv::Rect2d armor_box; // 当前目标位置
int boxid; // 当前目标id
cv::Ptr<cv::Tracker> tracker; // tracker对象实例
Classifier classifier; // CNN分类器对象实例用于数字识别
int contour_area; // 装甲区域亮点个数,用于数字识别未启用时判断是否跟丢(已弃用)
Serial &serial; // 串口对象,引用外部变量,用于和能量机关共享同一个变量
const uint8_t &use_classifier; // 标记是否启用CNN分类器引用外部变量自动变化
bool stateSearchingTarget(cv::Mat &src); // searching state主函数
bool stateTrackingTarget(cv::Mat &src); // tracking state主函数
bool stateStandBy(); // stand by state主函数已弃用
public:
void run(cv::Mat &src); // 自瞄主函数
bool sendBoxPosition(); // 和主控板通讯
};
/******************* 灯条类定义 ***********************/
class LightBlob {
public:
cv::RotatedRect rect;
double length;
uint8_t BlobColor;
cv::RotatedRect rect; //灯条位置
double length; //灯条长度
uint8_t BlobColor; //灯条颜色
LightBlob(cv::RotatedRect &r) : rect(r) {
length = max(rect.size.height, rect.size.width);
};
bool operator<(LightBlob &l2) { return this->rect.center.x < l2.rect.center.x; }
bool operator<=(LightBlob &l2) { return this->rect.center.x <= l2.rect.center.x; }
bool operator>(LightBlob &l2) { return this->rect.center.x > l2.rect.center.x; }
bool operator>=(LightBlob &l2) { return this->rect.center.x >= l2.rect.center.x; }
};
#endif /* _ARMOR_FINDER_H_ */

View File

@@ -6,16 +6,12 @@
#define _SHOW_IMAGES_H_
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <armor_finder/armor_finder.h>
#include <map>
extern std::map<int, string> id2name;
//
void showArmorBoxVector(std::string windows_name, const cv::Mat &src, const std::vector<cv::Rect2d> &armor_box);
void showArmorBox(std::string windows_name, const cv::Mat &src, cv::Rect2d armor_box, int boxid);
void showContours(std::string windows_name, const cv::Mat &src, const std::vector<LightBlob> &light_blobs);
void showArmorBoxClass(std::string window_names, const cv::Mat &src, vector<cv::Rect2d> boxes[10]);
void showCuoWeiDu(const cv::Mat &src, const std::vector<LightBlob> &light_blobs);
#endif /* _SHOW_IMAGES_H_ */

View File

@@ -8,11 +8,23 @@
#include <opencv2/highgui.hpp>
#include <armor_finder/armor_finder.h>
ArmorFinder::ArmorFinder(uint8_t &color, Serial &u, string paras_folder, const uint8_t &use) :
std::map<int, string> id2name = {
{-1, "OO"},{ 0, "NO"},
{ 1, "B1"},{ 2, "B2"},{ 3, "B3"},{ 4, "B4"},{ 5, "B5"},{ 6, "B7"},{ 7, "B8"},
{ 8, "R1"},{ 9, "R2"},{10, "R3"},{11, "R4"},{12, "R5"},{13, "R7"},{14, "R8"},
}; //装甲板id到名称的map
std::map<string, int> name2id = {
{"OO", -1},{"NO", 0},
{"B1", 1},{"B2", 2},{"B3", 3},{"B4", 4},{"B5", 5},{"B7", 6},{"B8", 7},
{"R1", 8},{"R2", 9},{"R3", 10},{"R4", 11},{"R5", 12},{"R7", 13},{"R8", 14},
}; //装甲板名称到id的map
ArmorFinder::ArmorFinder(uint8_t &color, Serial &u, const string &paras_folder, const uint8_t &use) :
serial(u),
enemy_color(color),
state(STANDBY_STATE),
classifier(std::move(paras_folder)),
classifier(paras_folder),
contour_area(0),
use_classifier(use),
boxid(-1)
@@ -20,28 +32,26 @@ ArmorFinder::ArmorFinder(uint8_t &color, Serial &u, string paras_folder, const u
}
void ArmorFinder::run(cv::Mat &src) {
static int tracking_cnt = 0;
cv::Mat src_use;
src_use = src.clone();
cv::cvtColor(src_use, src_gray, CV_RGB2GRAY);
static int tracking_cnt = 0; // 记录追踪帧数,用于定时退出追踪
cv::Mat src_use = src.clone(); // 实际参与计算的图像对象
if(show_armor_box){
if(show_armor_box){ // 根据条件显示当前目标装甲板
showArmorBox("box", src, armor_box, boxid);
cv::waitKey(1);
}
stateSearchingTarget(src_use);
return;
// stateSearchingTarget(src_use);
// return;
switch (state){
case SEARCHING_STATE:
if(stateSearchingTarget(src_use)){
if((armor_box & cv::Rect2d(0, 0, 640, 480)) == armor_box) {
if(!classifier && use_classifier){
cv::Mat roi = src_use.clone()(armor_box), roi_gray;
if((armor_box & cv::Rect2d(0, 0, 640, 480)) == armor_box) { // 判断装甲板区域是否脱离图像区域
if(!classifier || !use_classifier){ /* 如果分类器不可用或者不使用分类器 */
cv::Mat roi = src_use.clone()(armor_box), 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);
}
tracker = TrackerToUse::create();
tracker = TrackerToUse::create(); // 成功搜寻到装甲板创建tracker对象
tracker->init(src_use, armor_box);
state = TRACKING_STATE;
tracking_cnt = 0;
@@ -50,7 +60,7 @@ void ArmorFinder::run(cv::Mat &src) {
}
break;
case TRACKING_STATE:
if(++tracking_cnt>100 || !stateTrackingTarget(src_use)){
if(++tracking_cnt>100 || !stateTrackingTarget(src_use)){ // 最多追踪100帧图像
state = SEARCHING_STATE;
LOGM(STR_CTR(WORD_LIGHT_YELLOW ,"into search!"));
}

View File

@@ -0,0 +1,341 @@
//
// Created by xinyang on 19-3-27.
//
#include <armor_finder/armor_finder.h>
#include <opencv2/highgui.hpp>
#include <show_images/show_images.h>
#include <options/options.h>
#include <log.h>
#include "image_process.h"
typedef std::vector<LightBlob> LightBlobs;
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;
}
/// Todo: 下面的函数可以有性能优化,暂时未做。
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;
}
///Todo: 性能优化后的函数。(暂时还有点问题)
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>(c, r)) {
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>(c, r)) {
cnt++;
}
}
}
return double(cnt) / rotrect.size.area();
}
static bool isValidLightBlob(const cv::Mat &bin, const cv::RotatedRect &rect) {
return (lw_rate(rect) > 1.8) &&
// (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);
}
static bool findLightBlobs(const cv::Mat &src, LightBlobs &light_blobs) {
static cv::Mat src_gray;
if (src.type() == CV_8UC3) {
cvtColor(src, src_gray, CV_BGR2GRAY);
} else if (src.type() == CV_8UC1) {
src_gray = src.clone();
}
std::vector<std::vector<cv::Point> > light_contours;
cv::findContours(src_gray, 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_gray, rect)) {
light_blobs.emplace_back(rect);
}
}
return light_blobs.size() >= 2;
}
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;
}
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;
}
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);
}
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);
}
/* 判断两个灯条的错位度,不知道英文是什么!!! */
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;
}
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);
}
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);
}
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;
}
static bool findArmorBoxes(LightBlobs &light_blobs, std::vector<cv::Rect2d> &armor_boxes, uint8_t enemy_color) {
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;
}
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;
}
}
}
static string prior_blue[] = {
"B8", "B1", "B3", "B4", "B5", "B7", "B2",
"R8", "R1", "R3", "R4", "R5", "R7", "R2",
};
static string prior_red[] = {
"B8", "B1", "B3", "B4", "B5", "B7", "B2",
"R8", "R1", "R3", "R4", "R5", "R7", "R2",
};
bool ArmorFinder::stateSearchingTarget(cv::Mat &src) {
std::vector<cv::Mat> channels; // 通道拆分
cv::Mat src_bin, color; // 二值图和颜色通道图
LightBlobs light_blobs; // 存储所有可能的灯条
std::vector<cv::Rect2d> armor_boxes; // 装甲板候选区
std::vector<cv::Rect2d> boxes_number[15]; // 装甲板候选区放置在对应id位置
armor_box = cv::Rect2d(0, 0, 0, 0); // 重置目标装甲板位置
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, 190, 255, CV_THRESH_BINARY); // 二值化对应通道
imagePreProcess(src_bin); // 开闭运算
if (!findLightBlobs(src_bin, light_blobs)) {
return false;
}
if (show_light_blobs) {
showContours("blobs_gray", src_bin, light_blobs);
cv::waitKey(1);
}
get_blob_color(src, light_blobs);
if (show_light_blobs) {
showContours("light_blobs", src, light_blobs);
cv::waitKey(1);
}
if (!findArmorBoxes(light_blobs, armor_boxes, enemy_color)) {
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("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();
}

View File

@@ -1,388 +0,0 @@
//
// Created by xinyang on 19-3-27.
//
#include <armor_finder/armor_finder.h>
#include <opencv2/highgui.hpp>
#include "image_process/image_process.h"
#include <log.h>
#include <show_images/show_images.h>
#include <options/options.h>
typedef std::vector<LightBlob> LightBlobs;
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;
}
/// Todo: 下面的函数可以有性能优化,暂时未做。
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;
}
///Todo: 性能优化后的函数。(暂时还有点问题)
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[3].y; r++){
// int val[]={
// linePointX(corners[0],corners[1], r),
// linePointX(corners[0],corners[2], r),
// linePointX(corners[1],corners[3], r),
// linePointX(corners[2],corners[3], r),
// };
// for(int c=val[1]; c<val[2]; c++){
// if(bin.at<uint8_t >(c, r)){
// cnt++;
// }
// }
// }
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 >(c, r)){
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 >(c, r)){
cnt++;
}
}
}
return double(cnt) / rotrect.size.area();
}
static bool isValidLightBlob(const cv::Mat &bin, const cv::RotatedRect &rect){
return (lw_rate(rect) > 1.8) &&
// (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);
}
static void pipelineLightBlobPreprocess(cv::Mat &src) {
src -= 150;
src *= 3.5;
src -= 150;
src *= 3.5;
}
static bool findLightBlobs(const cv::Mat &src, LightBlobs &light_blobs) {
static cv::Mat src_gray;
if(src.type() == CV_8UC3){
cvtColor(src, src_gray, CV_BGR2GRAY);
}else if(src.type() == CV_8UC1){
src_gray = src.clone();
}
std::vector<std::vector<cv::Point> > light_contours;
cv::findContours(src_gray, 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_gray, rect)){
light_blobs.emplace_back(rect);
}
}
return light_blobs.size() >= 2;
}
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;
}
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;
}
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);
}
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);
}
/* 判断两个灯条的错位度,不知道英文是什么!!! */
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;
}
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);
}
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);
}
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;
}
static bool findArmorBoxes(LightBlobs &light_blobs, std::vector<cv::Rect2d> &armor_boxes, uint8_t enemy_color) {
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;
}
bool judge_light_color(std::vector<LightBlob> &light, std::vector<LightBlob> &color, std::vector<LightBlob> &result) {
for (auto &i:color) {
for (auto &j:light) {
cv::Rect2d a = i.rect.boundingRect2f();
cv::Rect2d b = j.rect.boundingRect2f();
cv::Rect2d ab = a & b;
if (ab.area() / fmin(a.area(), b.area()) >= 0.2) {
result.emplace_back(j);
break;
}
}
}
return !result.empty();
}
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;
}
}
}
int prior_blue[] = {6, 0, 2, 3, 4, 5, 1, 13, 7, 9, 10, 11, 12, 8};
int prior_red[]= {13, 7, 9, 10, 11, 12, 8, 6, 0, 2, 3, 4, 5, 1};
bool ArmorFinder::stateSearchingTarget(cv::Mat &src) {
cv::Mat split, src_bin/*, edge*/;
LightBlobs light_blobs, light_blobs_, light_blobs_real;
std::vector<cv::Rect2d> armor_boxes, boxes_number[14];
armor_box = cv::Rect2d(0,0,0,0);
cv::cvtColor(src, src_gray, CV_BGR2GRAY);
// cv::Canny(src_gray, edge, 100, 150);
// src_gray -= edge;
// cv::imshow("minus", src_gray);
// pipelineLightBlobPreprocess(src_gray);
cv::threshold(src_gray, src_bin, 170, 255, CV_THRESH_BINARY);
imagePreProcess(src_bin);
// imshow("gray bin", src_bin);
if(!findLightBlobs(src_bin, light_blobs)){
return false;
}
if(show_light_blobs){
showContours("blobs_gray", src_bin, light_blobs);
cv::waitKey(1);
}
// imageColorSplit(src, split, enemy_color);
//// imshow("split123",split);
// imagePreProcess(split);
//// imshow("split",split);
// cv::threshold(split, src_bin, 170, 255, CV_THRESH_BINARY);
// if(!findLightBlobs(src_bin, light_blobs_)){
// return false;
// }
// if(show_light_blobs){
// showContours("blobs_split", src_bin, light_blobs_);
// cv::waitKey(1);
// }
//
// if(!judge_light_color(light_blobs, light_blobs_, light_blobs_real)){
// return false;
// }
light_blobs_real = light_blobs;
get_blob_color(src, light_blobs_real);
if(show_light_blobs){
showContours("light_blobs", src, light_blobs_real);
// showCuoWeiDu(src, light_blobs_real);
cv::waitKey(1);
}
if(!findArmorBoxes(light_blobs_real, armor_boxes, enemy_color)){
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);
if(c){
boxes_number[c-1].emplace_back(box);
}
}
if(enemy_color == ENEMY_BLUE) {
for(auto id : prior_blue){
if(!boxes_number[id].empty()){
armor_box = boxes_number[id][0];
boxid = id;
break;
}
}
}else if(enemy_color == ENEMY_RED) {
for(auto id : prior_red){
if(!boxes_number[id].empty()){
armor_box = boxes_number[id][0];
boxid = id;
break;
}
}
}else{
LOGE("enemy_color ERROR!");
}
if(armor_box == cv::Rect2d(0,0,0,0)){
return false;
}
if(show_armor_boxes){
showArmorBoxClass("class", src, boxes_number);
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;
}
if(split.size() == cv::Size(320, 240)){
armor_box.x *= 2;
armor_box.y *= 2;
armor_box.width *= 2;
armor_box.height *= 2;
}
return sendBoxPosition();
}

View File

@@ -1,33 +1,17 @@
#include <show_images/show_images.h>
#include <opencv2/highgui.hpp>
#include <log.h>
using namespace cv;
std::map<int, string> id2name = {
{-1, "NO"},
{ 0, "B1"},
{ 1, "B2"},
{ 2, "B3"},
{ 3, "B4"},
{ 4, "B5"},
{ 5, "B7"},
{ 6, "B8"},
{ 7, "R1"},
{ 8, "R2"},
{ 9, "R3"},
{10, "R4"},
{11, "R5"},
{12, "R7"},
{13, "R8"},
};
/**************************
* 显示多个装甲板区域 *
**************************/
void showArmorBoxVector(std::string windows_name, const cv::Mat &src, const std::vector<cv::Rect2d> &armor_box) {
static Mat image2show;
if (src.type() == CV_8UC1) // 黑白图像
{
if (src.type() == CV_8UC1) {// 黑白图像
cvtColor(src, image2show, COLOR_GRAY2RGB);
} else if(src.type() == CV_8UC3) //RGB 彩色
{
} else if (src.type() == CV_8UC3) { //RGB 彩色
image2show = src.clone();
}
@@ -37,26 +21,30 @@ void showArmorBoxVector(std::string windows_name, const cv::Mat &src, const std:
imshow(windows_name, image2show);
}
void showArmorBoxClass(std::string window_names, const cv::Mat &src, vector<cv::Rect2d> boxes[10]){
/**************************
* 显示多个装甲板区域及其类别 *
**************************/
void showArmorBoxClass(std::string window_names, const cv::Mat &src, vector<cv::Rect2d> boxes[10]) {
static Mat image2show;
if (src.type() == CV_8UC1) // 黑白图像
{
if (src.type() == CV_8UC1) { // 黑白图像
cvtColor(src, image2show, COLOR_GRAY2RGB);
} else if(src.type() == CV_8UC3) //RGB 彩色
{
} else if (src.type() == CV_8UC3) { //RGB 彩色
image2show = src.clone();
}
for(int i=0; i<14; i++){
if(!boxes[i].empty()){
for(auto box : boxes[i]){
for (int i = 0; i < 14; i++) {
if (!boxes[i].empty()) {
for (auto box : boxes[i]) {
rectangle(image2show, box, Scalar(0, 255, 0), 1);
if(i == -1)
putText(image2show, id2name[i], Point(box.x+2, box.y+2), cv::FONT_HERSHEY_TRIPLEX, 1, Scalar(0,255,0));
else if(0<=i && i<7)
putText(image2show, id2name[i], Point(box.x+2, box.y+2), cv::FONT_HERSHEY_TRIPLEX, 1, Scalar(255,0,0));
else if(7<=i && i<14)
putText(image2show, id2name[i], Point(box.x+2, box.y+2), cv::FONT_HERSHEY_TRIPLEX, 1, Scalar(0,0,255));
else
if (i == -1)
putText(image2show, id2name[i], Point(box.x + 2, box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
Scalar(0, 255, 0));
else if (1 <= i && i < 8)
putText(image2show, id2name[i], Point(box.x + 2, box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
Scalar(255, 0, 0));
else if (8 <= i && i < 15)
putText(image2show, id2name[i], Point(box.x + 2, box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
Scalar(0, 0, 255));
else if (i != 0)
LOGE_INFO("Invalid box id:%d!", i);
}
}
@@ -64,84 +52,56 @@ void showArmorBoxClass(std::string window_names, const cv::Mat &src, vector<cv::
imshow(window_names, image2show);
}
/**************************
* 显示多个装甲板区域及其类别 *
**************************/
void showArmorBox(std::string windows_name, const cv::Mat &src, cv::Rect2d armor_box, int boxid) {
static Mat image2show;
if (src.type() == CV_8UC1) // 黑白图像
{
if (src.type() == CV_8UC1) { // 黑白图像
cvtColor(src, image2show, COLOR_GRAY2RGB);
} else if(src.type() == CV_8UC3) //RGB 彩色
{
} else if (src.type() == CV_8UC3) { //RGB 彩色
image2show = src.clone();
}
rectangle(image2show, armor_box, Scalar(0, 255, 0), 1);
if(boxid == -1)
putText(image2show, id2name[boxid], Point(armor_box.x+2, armor_box.y+2), cv::FONT_HERSHEY_TRIPLEX, 1, Scalar(0,255,0));
else if(0<=boxid && boxid<7)
putText(image2show, id2name[boxid], Point(armor_box.x+2, armor_box.y+2), cv::FONT_HERSHEY_TRIPLEX, 1, Scalar(255,0,0));
else if(7<=boxid && boxid<14)
putText(image2show, id2name[boxid], Point(armor_box.x+2, armor_box.y+2), cv::FONT_HERSHEY_TRIPLEX, 1, Scalar(0,0,255));
else
if (boxid == -1)
putText(image2show, id2name[boxid], Point(armor_box.x + 2, armor_box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
Scalar(0, 255, 0));
else if (1 <= boxid && boxid < 8)
putText(image2show, id2name[boxid], Point(armor_box.x + 2, armor_box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
Scalar(255, 0, 0));
else if (8 <= boxid && boxid < 15)
putText(image2show, id2name[boxid], Point(armor_box.x + 2, armor_box.y + 2), cv::FONT_HERSHEY_TRIPLEX, 1,
Scalar(0, 0, 255));
else if (boxid != 0)
LOGE_INFO("Invalid box id:%d!", boxid);
imshow(windows_name, image2show);
}
/**************************
* 显示多个灯条区域 *
**************************/
void showContours(std::string windows_name, const cv::Mat &src, const std::vector<LightBlob> &light_blobs) {
static Mat image2show;
if(src.type() == CV_8UC1) // 黑白图像
{
if (src.type() == CV_8UC1) { // 黑白图像
cvtColor(src, image2show, COLOR_GRAY2RGB);
}
else if(src.type() == CV_8UC3) //RGB 彩色
{
} else if (src.type() == CV_8UC3) { //RGB 彩色
image2show = src.clone();
}
for(const auto &light_blob:light_blobs)
{
for (const auto &light_blob:light_blobs) {
Scalar color;
if(light_blob.BlobColor == BLOB_RED)
color = Scalar(0,0,255);
else if(light_blob.BlobColor == BLOB_BLUE)
color = Scalar(255,0,0);
if (light_blob.BlobColor == BLOB_RED)
color = Scalar(0, 0, 255);
else if (light_blob.BlobColor == BLOB_BLUE)
color = Scalar(255, 0, 0);
else
color = Scalar(0,255,0);
color = Scalar(0, 255, 0);
cv::Point2f vertices[4];
light_blob.rect.points(vertices);
for (int j = 0; j < 4; j++){
for (int j = 0; j < 4; j++) {
cv::line(image2show, vertices[j], vertices[(j + 1) % 4], color, 2);
}
}
imshow(windows_name, image2show);
}
void drawCuoWeiDu(cv::Mat &src, 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;
}
Point2f orientation(cos(angle), sin(angle));
Vector2f p2p(light_blob_j.rect.center.x-light_blob_i.rect.center.x, light_blob_i.rect.center.y-light_blob_j.rect.center.y);
cv::line(
src,
(light_blob_j.rect.center+light_blob_i.rect.center)/2.0,
(light_blob_j.rect.center+light_blob_i.rect.center)/2.0 + 100*orientation,
Scalar(0,255,0),
2
);
}
void showCuoWeiDu(const cv::Mat &src, const std::vector<LightBlob> &light_blobs){
Mat image2show = src.clone();
for (int i = 0; i < light_blobs.size() - 1; ++i) {
for (int j = i + 1; j < light_blobs.size(); ++j) {
drawCuoWeiDu(image2show, light_blobs[i], light_blobs[j]);
}
}
imshow("CuoWeiDu", image2show);
}

View File

@@ -14,7 +14,6 @@ const int SRC_WIDTH_CAMERA = 640;
const int SRC_HEIGHT_CAMERA = 480;
const int SRC_WIDTH = 320;
const int SRC_HEIGHT = 240;
const double PI = 3.1415926;
const int CLOCKWISE = 1;
const int ANTICLOCKWISE = -1;
const float ATTACK_DISTANCE = 718;//cm

View File

@@ -9,6 +9,7 @@
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <constants.h>
#include <stdio.h>
#include <time.h>
#include <sys/timeb.h>

View File

@@ -2,61 +2,58 @@
// Created by xixiliadorabarry on 1/24/19.
//
#include <iostream>
#include <thread>
#include <opencv2/core/core.hpp>
#include <fstream>
#include <energy/energy.h>
#include <serial/serial.h>
#include <energy/param_struct_define.h>
#include <energy/constant.h>
#include <camera/camera_wrapper.h>
#include <camera/video_wrapper.h>
#include <camera/wrapper_head.h>
#include <energy/energy.h>
#include <armor_finder/armor_finder.h>
#include <options/options.h>
#include <additions/additions.h>
#include <thread>
#define DO_NOT_CNT_TIME
#include <log.h>
using namespace cv;
using namespace std;
mcu_data mcuData = {
0,
0,
SMALL_ENERGY_STATE,
0,
1,
ENEMY_BLUE,
mcu_data mcuData = { // 单片机端回传结构体
0, // 当前云台yaw角
0, // 当前云台pitch角
ARMOR_STATE, // 当前状态,自瞄-大符-小符
0, // 云台角度标记位
1, // 是否启用数字识别
ENEMY_RED, // 敌方颜色
};
WrapperHead *video_gimble = nullptr;
WrapperHead *video_chassis = nullptr;
Serial serial(115200);
uint8_t last_state = mcuData.state;
WrapperHead *video_gimble = nullptr; // 云台摄像头视频源
WrapperHead *video_chassis = nullptr; // 底盘摄像头视频源
Serial serial(115200); // 串口对象
uint8_t last_state = mcuData.state; // 上次状态,用于初始化
// 自瞄主程序对象
ArmorFinder armorFinder(mcuData.enemy_color, serial, PROJECT_DIR"/tools/para/", mcuData.use_classifier);
// 能量机关主程序对象
Energy energy(serial, mcuData.enemy_color);
int main(int argc, char *argv[]) {
process_options(argc, argv);
thread receive(uartReceive, &serial);
process_options(argc, argv); // 处理命令行参数
thread receive(uartReceive, &serial); // 开启串口接收线程
int from_camera = 1;
int from_camera = 1; // 根据条件选择视频源
if (!run_with_camera) {
cout << "Input 1 for camera, 0 for video files" << endl;
cin >> from_camera;
}
while (true) {
// 打开视频源
if (from_camera) {
video_gimble = new CameraWrapper(0/*, "armor"*/);
video_chassis = new CameraWrapper(1/*, "energy"*/);
} else {
video_gimble = new VideoWrapper("/home/sun/项目/energy_video/energy_test.avi");
video_gimble = new VideoWrapper("/home/sun/项目/energy_video/official_r_l.mp4");
video_chassis = new VideoWrapper("/home/sun/项目/energy_video/energy_test.avi");
}
if (video_gimble->init()) {
@@ -74,6 +71,7 @@ int main(int argc, char *argv[]) {
video_chassis = nullptr;
}
// 跳过前10帧噪声图像。
Mat gimble_src, chassis_src;
for (int i = 0; i < 10; i++) {
if (video_gimble) {
@@ -84,7 +82,7 @@ int main(int argc, char *argv[]) {
}
}
bool ok = true;
cout<<"start running"<<endl;
cout << "start running" << endl;
do {
CNT_TIME("Total", {
if (mcuData.state == BIG_ENERGY_STATE) {//大符模式
@@ -102,23 +100,20 @@ int main(int argc, char *argv[]) {
}
energy.runBig(gimble_src, chassis_src);//击打大符
last_state = mcuData.state;//更新上一帧状态
}
else if (mcuData.state != BIG_ENERGY_STATE) {//自瞄或小符模式
} else if (mcuData.state != BIG_ENERGY_STATE) {//自瞄或小符模式
last_state = mcuData.state;
ok = checkReconnect(video_gimble->read(gimble_src));
if (save_video) saveVideos(gimble_src);
if (show_origin) showOrigin(gimble_src);
if (mcuData.state == ARMOR_STATE){
if (mcuData.state == ARMOR_STATE) {
CNT_TIME("Armor Time", {
armorFinder.run(gimble_src);
});
}
else if(mcuData.state == SMALL_ENERGY_STATE){
} else if (mcuData.state == SMALL_ENERGY_STATE) {
// energy.runSmall(gimble_src);
energy.runBig(gimble_src);
}
}
cv::waitKey(3);
});
} while (ok);

View File

@@ -7,15 +7,6 @@
#include <stdint.h>
#include <serial/serial.h>
#include <opencv2/videoio.hpp>
#include <camera/wrapper_head.h>
#define ENEMY_BLUE 0
#define ENEMY_RED 1
#define BIG_ENERGY_STATE 'b'
#define SMALL_ENERGY_STATE 's'
#define ARMOR_STATE 'a'
struct mcu_data{
float curr_yaw;

View File

@@ -0,0 +1,17 @@
//
// Created by xinyang on 19-7-8.
//
#ifndef _CONSTANTS_H_
#define _CONSTANTS_H_
#define PI (3.14159265459)
#define ENEMY_BLUE 0
#define ENEMY_RED 1
#define BIG_ENERGY_STATE 'b'
#define SMALL_ENERGY_STATE 's'
#define ARMOR_STATE 'a'
#endif /* _CONSTANTS_H */

View File

@@ -11,11 +11,10 @@ extern bool show_armor_box;
extern bool show_armor_boxes;
extern bool show_light_blobs;
extern bool show_origin;
extern bool save_labelled;
extern bool run_with_camera;
extern bool save_video;
extern bool collect_data;
extern bool wait_uart;
extern bool save_labelled_boxes;
void process_options(int argc, char *argv[]);

View File

@@ -3,17 +3,17 @@
//
#include <cstring>
#include <iostream>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/videoio/videoio_c.h>
#include <additions/additions.h>
#include <camera/camera_wrapper.h>
#include <log.h>
#include <opencv2/videoio/videoio_c.h>
#include <iostream>
#include <energy/energy.h>
#include <armor_finder/armor_finder.h>
#include <log.h>
#define RECEIVE_LOG_LEVEL LOG_MSG

View File

@@ -76,7 +76,7 @@ bool CameraWrapper::init() {
#elif defined(Linux)
CameraSetAeState(h_camera, false);
CameraSetExposureTime(h_camera, 10*1000);
CameraSetAnalogGain(h_camera, 30);
CameraSetAnalogGain(h_camera, 50);
if(mode == 0){
CameraSetGain(h_camera, 100, 100, 100);
CameraSetLutMode(h_camera, LUTMODE_PRESET);
@@ -111,11 +111,8 @@ bool CameraWrapper::init() {
bool CameraWrapper::read(cv::Mat& src) {
// return readRaw(src); //suit for using bayer hacking in armor_finder to replace process, fast and it can filter red and blue.
if(mode==0)return readProcessed(src); // processed color image, but this runs slowly, about half fps of previous one.
if(mode==0)return readProcessed(src);
if(mode==1)return readRaw(src);
}
bool CameraWrapper::readRaw(cv::Mat &src) {

View File

@@ -10,11 +10,10 @@ bool show_armor_box = false;
bool show_armor_boxes = false;
bool show_light_blobs = false;
bool show_origin = false;
bool save_labelled = false;
bool run_with_camera = false;
bool save_video = false;
bool collect_data = false;
bool wait_uart = false;
bool save_labelled_boxes = false;
void process_options(int argc, char *argv[]){
if(argc >= 2){
@@ -24,10 +23,9 @@ void process_options(int argc, char *argv[]){
LOGM("--show-armor-boxes: show the candidate aim boxes.");
LOGM("--show-light-blobs: show the candidate light blobs.");
LOGM("--show-origin: show the origin image.");
LOGM("--save-label: save the image when box found.");
LOGM("--run-with-camera: start the program with camera directly without asking.");
LOGM("--save-video: save the video.");
LOGM("--collect-data: collect data sent from mcu.");
LOGM("--save-labelled-boxes: save labelled armor boxes.");
}else if(strcmp(argv[i], "--show-armor-box") == 0){
show_armor_box = true;
LOGM("Enable show armor box");
@@ -49,21 +47,18 @@ void process_options(int argc, char *argv[]){
LOGM("Enable show light blobs");
show_origin = true;
LOGM("Enable show origin");
}else if(strcmp(argv[i], "--save-labeled") == 0){
save_labelled = true;
LOGM("Enable save labeled");
}else if(strcmp(argv[i], "--run-with-camera") == 0){
run_with_camera = true;
LOGM("Run with camera!");
}else if(strcmp(argv[i], "--save-video") == 0){
save_video = true;
LOGM("Save video!");
}else if(strcmp(argv[i], "--collect-data") == 0){
collect_data = true;
LOGM("Enable data collection!");
}else if(strcmp(argv[i], "--wait-uart") == 0){
wait_uart = true;
LOGM("Wait uart until available!");
}else if(strcmp(argv[i], "--save-labelled-boxes") == 0){
save_labelled_boxes = true;
LOGM("labelled armor boxes will be saved!");
}else{
LOGW("Unknown option: %s. Use --help to see options.", argv[i]);
}

View File

@@ -70,8 +70,8 @@ def train(dataset, show_bar=False):
nodes, vars = forward.forward(x, 0.01)
y = nodes[-1]
# ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))
ce = tf.nn.weighted_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1), pos_weight=1)
ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))
# ce = tf.nn.weighted_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1), pos_weight=1)
cem = tf.reduce_mean(ce)
loss= cem + tf.add_n(tf.get_collection("losses"))
@@ -114,7 +114,7 @@ def train(dataset, show_bar=False):
vars_val = sess.run(vars)
save_para("/home/xinyang/Desktop/RM_auto-aim/tools/para", vars_val)
save_para("/home/xinyang/Workspace/RM_auto-aim/tools/para", vars_val)
print("save done!")
# nodes_val = sess.run(nodes, feed_dict={x:test_images})
# return vars_val, nodes_val
@@ -204,5 +204,5 @@ def train(dataset, show_bar=False):
if __name__ == "__main__":
dataset = generate.DataSet("/home/xinyang/Desktop/box_cut")
dataset = generate.DataSet("/home/xinyang/Workspace/dataset/box_cut")
train(dataset, show_bar=True)

View File

@@ -1,7 +1,7 @@
6
2.196893
0.07216131
0.30069783
-0.4587247
0.25476167
-0.07236218
1.0992107
-0.074966855
0.6112759
0.15176532
0.7093666
0.0066502886

View File

@@ -2,453 +2,453 @@
6
5
5
0.44015908
-0.2615819
-0.7202753
-0.6970971
-1.4688265
0.041381914
-0.4771021
-0.66656536
-0.48385224
-1.4722625
-0.27656743
-0.9269907
-0.67948955
-0.25132853
-0.9113727
-0.2557801
-0.60230213
-0.1460812
0.27652547
0.05081466
-0.041295715
0.12629044
0.6560201
1.2785738
1.2724568
0.96436024
0.8186016
0.88649714
0.75382483
0.73065615
0.6149405
0.60412383
0.6761081
0.57785183
0.76593316
0.038173575
0.34317255
0.4631205
0.47925335
0.563723
-0.111236684
-0.02848622
0.10297996
0.30407003
0.248617
-0.27458128
-0.39390934
-0.14871475
0.16967124
0.24545498
-1.029415
-0.29149657
0.04355961
0.0037662752
0.29983765
-0.77363306
-0.16461371
0.12952146
0.24172097
0.57778966
-0.59511507
-0.09913258
0.42451194
0.28742495
0.40570587
-0.6389509
-0.26765737
-0.008538765
-0.16448489
-0.108952306
-1.0954283
-0.7077157
-0.51456565
-0.8886615
-0.9622352
0.60970205
0.76268256
0.55864525
0.55142695
0.20495823
0.6414269
0.6300521
0.65805984
0.44780147
0.3747945
0.5441177
0.5725899
0.4964406
0.45946532
0.43612415
0.3597355
0.37553644
0.44157314
0.387358
0.40075454
0.17919225
0.15043777
0.40608513
0.5315383
0.70023865
-0.39882216
-0.22897638
0.07692382
0.46537802
0.2471119
-0.28952354
-0.18228096
0.17880945
0.25431904
0.3143998
-0.39884818
-0.15753536
0.06485958
-0.2133111
-0.05121911
-0.61350924
-0.5361917
-0.37863305
-0.66671985
-0.5644232
-0.6748531
-1.03323
-1.2689675
-1.4129945
-1.1743933
-0.06001543
-0.14319007
-0.16163512
-0.0396769
-0.1525588
-0.072800726
-0.13891631
-0.19958425
-0.11522951
-0.021397796
-0.13518313
-0.06954514
-0.074013405
-0.25381202
-0.074712805
-0.14324121
-0.13240005
0.03974622
0.0386375
0.0858599
-0.1719485
0.07882476
-0.082135156
-0.041621048
-0.094962135
1.2879299
0.3068063
-1.1773561
-1.5354381
-2.1768477
0.66036284
-0.49844337
-1.782708
-1.9710878
-2.462608
0.17707823
-0.87392896
-2.051351
-1.6899666
-1.6679516
0.022324406
-0.8198553
-1.4777138
-1.1360523
-0.08169238
0.36327407
-0.19396476
-0.38634166
0.5004826
2.1292248
0.772124
0.6520143
0.6104394
0.54212964
0.49670208
0.3376192
0.37325495
0.4384262
0.49389806
0.5105715
-0.21768741
-0.2625075
0.021104362
0.014687131
0.007237775
-0.7143952
-0.56526405
-0.3097984
-0.26630577
-0.048004664
-0.9913299
-0.654891
-0.3763111
-0.044422667
-0.4123894
0.16750373
0.61826766
0.91776484
1.0351493
1.0686466
0.5438755
1.3297509
1.6691188
1.5771018
1.6140286
0.8386884
1.4914865
1.7180405
1.553264
1.6037419
0.87034816
1.3344289
1.475369
1.0393218
0.99507225
0.43426043
0.76878655
0.83099675
0.4372083
-0.03305005
0.45626023
0.50493777
0.39258057
0.15306357
-0.05358956
0.28183588
0.2819697
0.26767746
0.3076198
-0.0959618
0.103274405
0.052774247
0.10074409
0.2757665
-0.010733735
-0.024759881
0.08207693
0.1011946
0.028895097
0.019118605
-0.11530524
-0.24842119
-0.07197208
0.13267942
0.020294672
0.4588099
0.41810644
0.88007724
0.9788357
0.9979609
0.6985352
0.9033048
1.3437003
1.3382984
1.0678436
0.9530294
0.9335025
1.0252684
0.9498762
0.6784468
0.76646155
0.7713496
0.66539836
0.3956565
-0.0023110735
0.36541164
0.056837842
-0.1294126
-0.64489746
-0.7045176
0.012467409
-0.06926388
0.12865426
-0.19156362
-0.0143867675
-0.14750443
-0.17903289
-0.12134483
-0.09849269
-0.1265138
-0.121945545
-0.016874207
-0.09141961
-0.03623762
-0.14140157
-0.032881275
-0.11026187
0.0100520095
-0.115708
-0.14582232
-0.20724125
-0.10650144
0.05327495
-0.14452165
-0.18657139
0.9759488
0.06797629
-0.6424526
-0.7295271
-2.1513712
0.51016515
-0.5012981
-1.2636292
-1.0931056
-2.8768973
0.11379174
-0.7858709
-1.2452412
-0.99758494
-2.3904347
-0.075892836
-0.6556771
-0.82328016
-0.48217687
-0.77905804
0.3033478
-0.060466953
0.072058916
0.86042064
1.3924751
0.67556983
0.1908398
0.09444006
0.06265686
-0.28131226
0.073449805
-0.13604718
-0.3139295
-0.37795955
-0.47380728
-0.43103498
-0.804617
-0.70013463
-0.61713195
-0.60528046
-0.89829373
-1.1529391
-1.0678611
-0.8617194
-0.90371394
-1.1109782
-1.2232842
-1.1584836
-1.0506513
-0.95515406
-0.7661839
-0.5776984
-0.4494758
-0.60188085
-0.29663667
-0.49400347
-0.276762
-0.19688497
-0.19068864
-0.101883315
-0.44627395
0.023737198
-0.002635871
-0.14802596
-0.0777249
-0.52466774
-0.5440437
-0.437515
-0.87626624
-0.9086201
-0.9667058
-1.0027927
-1.23929
-1.513544
-1.5482179
-0.07866849
-0.22657336
-0.4241554
-0.6561498
-0.8929337
-0.31690583
-0.42029023
-0.6620226
-0.53444666
-0.8224304
-0.5535824
-0.72263557
-0.7589949
-0.7107847
-0.79393065
-0.7419499
-0.9067372
-0.8085271
-0.7942699
-0.8814587
-0.8113622
-0.816829
-0.59503084
-0.6020855
-0.59153247
0.2328816
0.058455627
0.35925868
0.93043673
0.96835476
0.55263966
0.550377
0.6435757
0.8017134
0.9625085
0.51592493
0.47526795
0.3429181
0.3358717
0.3496695
0.39214912
0.13631415
-0.2063166
-0.37639305
-0.24261068
-0.0990127
-0.73492914
-1.2090002
-1.3132827
-1.1944927
-0.11983766
-0.05122047
-0.25813514
0.030627063
-0.09024451
0.0011977615
-0.03363351
-0.098981306
-0.020513052
-0.16713202
0.059736907
-0.19797234
-0.04968633
-0.06846121
0.06014312
-0.15752262
0.05522959
0.0477386
-0.18798226
0.034906518
-0.12586041
-0.034278292
-0.20553574
-0.017096782
-0.18171601
-0.5127243
-0.35076743
-0.94582695
-1.1496089
-0.21747248
-0.697151
-0.31303257
-0.84063727
-0.60029787
-0.08752324
-0.6912181
-0.48108417
-0.877474
-0.56862247
0.15221412
-0.80212265
-0.460906
-0.67574793
-0.573153
-0.20908366
-0.6616608
-0.30440795
-0.55335987
-0.72610176
-0.6385564
0.76122427
0.81860757
0.5464134
0.58383447
0.4142986
0.77620906
0.9103861
0.6147042
0.6851236
0.5385627
0.72658443
0.7194319
0.7030224
0.5585485
0.36230496
0.51258016
0.6475413
0.48098332
0.35653463
0.42475638
0.26459572
0.30253762
0.2607581
0.083096296
0.26166555
-0.9131472
-1.5060923
-1.3316747
-0.8584581
-0.4393547
-0.51872504
-0.93602306
-0.7819688
-0.4840393
-0.27869374
0.11241833
-0.22918689
-0.23048288
-0.050663527
-0.17580733
0.57349825
0.5720818
0.55744994
0.12896755
0.007070846
1.2535337
1.1082574
0.83476424
0.28564626
-0.05619757
-0.681288
-0.680671
-0.8557866
-0.5097621
-0.23541005
-0.49887782
-0.64544016
-0.6693754
-0.47900042
-0.30171666
-0.29214832
-0.5003537
-0.58870244
-0.51416445
-0.23301734
-0.53337747
-0.4110472
-0.5953254
-0.53674793
-0.3959848
-0.7821416
-0.59215885
-0.7776034
-0.63905334
-0.2501917
-0.731315
-0.7205139
-0.73552233
-0.8656195
-0.6493437
-0.48103082
-0.64334613
-0.43961945
-0.6016135
-0.40041798
-0.27768084
-0.2570607
-0.2724738
-0.2884815
-0.14519088
-0.47138828
-0.3118455
-0.3317675
-0.4970204
-0.17755331
-0.61731154
-0.7118463
-0.6186997
-0.41463384
-0.27342835
0.11280696
-0.027138332
-0.6500771
-1.3383414
-1.6513624
0.15870772
0.10310151
-0.4998225
-1.3604605
-1.8239882
0.41981518
0.23697153
-0.1876976
-0.75823486
-1.4496676
0.7480236
0.53772146
0.32832542
-0.20044523
-0.744269
0.5854269
0.7915991
0.46373495
0.19664662
-0.24780232
0.6508635
0.577399
-0.7515515
-2.703382
-3.039032
0.8525215
0.6836974
-0.3311209
-1.7767388
-2.5821877
0.8349875
0.798852
0.086425625
-0.67867047
-1.8428398
1.2035539
1.1889999
0.7316317
-0.3872895
-1.4929688
1.2547168
1.3532602
0.7932933
-0.62973267
-1.9478854
0.21208195
0.18403792
0.054463003
-0.15276414
0.20949952
0.23891807
0.17854711
-0.06374925
0.1451161
0.034864046
0.26884222
0.21525136
-0.06312853
0.0147968
0.11538528
0.056850336
-0.0066543873
-0.11392982
-0.39074197
-0.009082649
-0.07041612
-0.27938405
-0.53290427
-0.46564633
-0.1038565
-2.7360635
-2.2902381
-1.5043008
-0.47565868
0.43513355
-1.887743
-1.3883648
-0.72364897
0.2942578
0.5935792
-0.80072504
-0.3620903
0.30662987
0.6962239
0.8277674
0.31633973
0.69582015
1.1589135
1.0656666
0.8970892
0.8714312
1.6066691
1.6423852
1.3843498
0.70298105
0.16647044
-0.19141927
0.06161116
-0.13610205
0.022933247
0.3518144
0.22493687
0.3335425
0.17380953
0.489461
0.29505125
0.23336394
0.3280449
0.48822153
0.6122305
0.40447977
0.27890772
0.3578474
0.52127045
0.38970685
0.18272732
0.18300931
0.2970602
0.13007997
0.3009802
0.21420936
0.18111303
-0.006488328
0.0036541307
0.009143832
0.5293987
0.61027414
0.5113341
0.4642546
0.35471886
0.84580845
0.703846
0.7211845
0.97343826
0.768236
0.92116314
0.91014177
0.8906536
0.7103699
0.81534237
0.59721285
0.76894915
0.9786482
0.56162304
0.58830947
1.4212193
1.2045107
0.12655553
-1.0669162
-2.0093904
1.4223398
1.0714712
-0.052089177
-1.0957986
-2.114745
1.5610827
1.0007412
0.30377847
-0.59364986
-1.6301248
1.5753381
1.3631456
0.9847575
0.09240083
-1.071189
1.6423446
1.5190983
1.1077387
0.34539416
-0.61813635
-0.7005647
-0.54221815
-1.5592585
-2.4405499
-2.1811392
-0.627011
-0.31241018
-1.1484959
-1.7542328
-1.6388324
-0.45500362
-0.024473518
-0.3944269
-0.75780237
-1.0935078
-0.2103359
0.38125098
0.00046585256
-0.36479756
-1.1601311
0.19282074
0.4312236
0.252357
-0.33207127
-1.2589971
-0.7244115
-0.7344274
-0.5687022
-0.37509185
0.13250336
-0.6894008
-0.3669812
-0.43533182
-0.2783045
-0.11804902
-0.68226725
-0.6880633
-0.57178533
-0.5920177
-0.09155524
-0.7462904
-0.8839723
-0.7533695
-0.6023744
-0.37469205
-1.085584
-1.1513206
-1.1520022
-0.87824655
-0.5624067
-1.6576195
-1.4470688
-0.8884038
-0.2505403
0.17347772
-1.1138643
-1.0841924
-0.5865495
0.029103624
0.34480488
-0.4835728
-0.3733231
0.13488956
0.30707127
0.51268774
0.035971884
0.3245176
0.60676646
0.69677067
0.41149148
0.5813579
1.0202353
1.03151
0.7790667
0.46908122
0.36013788
0.27479073
0.2624006
-0.020600509
0.35767564
0.64802307
0.50982404
0.6158538
0.38689435
0.3291019
0.8272585
0.69756824
0.63423824
0.65290684
0.5858387
0.6370019
0.6784572
0.43127632
0.44825375
0.46886912
0.5687188
0.45616633
0.37996903
0.29647112
0.2043913
-0.24145731
-0.46544155
-0.62147945
-0.8826915
-0.7966154
0.08726857
0.09046432
-0.29822
-0.37579864
-0.52853876
0.32306126
0.15829168
0.10857028
-0.013951714
-0.35195756
0.23894385
0.18110916
0.12564722
0.065700814
0.0819493
0.07809689
0.1876159
-0.16780216
-0.24810323
-0.29170018
-0.14610599
0.34555063
0.058622867
-0.59602225
-0.95331144
-0.033994026
0.20366722
0.035348356
-0.65933955
-0.6995426
0.1555722
0.6422814
0.52531075
0.0053241914
-0.25184304
0.39133748
0.9488818
0.8056857
0.71539056
0.30902287
0.46792307
0.96752924
1.2117271
0.8794963
0.6939028

View File

@@ -1,11 +1,11 @@
10
-0.20609309
-0.22031759
0.1367356
0.3687642
0.41563538
0.56676525
-0.18027179
0.23183917
-0.42312288
-0.071102634
0.14412592
-0.07423735
-0.049142662
0.19558677
0.12699787
0.10220198
1.1084645
-0.102667846
0.9059092
0.65017

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,17 @@
16
0.58729273
-0.46309644
-0.16430101
0.43460655
-0.12165885
-0.23968913
2.1033192
-0.19900312
-0.0075173783
0.05968375
-0.13455966
-0.203078
3.4187536
-0.17911159
0.2670588
-0.58640796
0.25629708
-0.032522578
-0.14084667
0.5625487
1.7736332
-0.89979994
-0.8327153
-0.0015706721
1.0403447
0.21188897
-0.21003345
-0.123272754
-0.15712602
2.9992483
0.9306246
-0.21879409

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,16 @@
15
3.3147552
0.06590654
-0.37396204
-0.22522521
-0.9601034
-0.9866448
-0.091494516
0.08088531
-0.87962383
-0.5273214
-0.18194006
-0.035499398
-1.7873636
0.48932117
0.20472674
2.9608855
0.48027807
0.6098448
0.6845462
-2.3924253
-0.51168174
0.11268586
0.605966
-1.7118223
-0.9332867
-0.60581064
0.47835764
-1.8917097
-0.15730774
-0.5549108

View File

@@ -1,242 +1,242 @@
16
15
0.032564595
0.2617493
-0.32648245
-0.09931708
-0.24592394
-0.046472594
0.33926198
-0.12294629
0.35003394
-0.21551898
-0.017696692
-0.14498983
-0.1035376
0.38845813
-0.025425002
0.009146354
-0.10837719
-0.26169685
0.24757256
0.12278806
0.173229
-0.13405079
-0.12579814
-0.055770937
-0.18405183
0.28358203
0.07445254
0.23714246
-0.13335316
0.010074598
8.8978056e-36
-3.2673058e-35
-5.345727e-35
-1.2187582e-35
2.1464323e-35
6.242724e-35
-1.5923025e-35
8.5710344e-35
-1.0859142e-34
3.2036078e-35
9.889982e-35
9.5151974e-35
-2.9864197e-35
4.3109238e-35
-3.5075268e-35
0.056317
-0.041549474
-0.07867665
-0.18685594
0.0036230602
0.26440525
-0.040618088
-0.011269322
-0.037696317
0.01897098
-0.12073718
0.017303245
0.33418366
0.0023682562
0.02849121
5.652079e-35
-2.3405746e-35
7.754459e-35
-7.9132345e-35
-3.652418e-35
2.7482412e-35
-5.490258e-35
-4.0657551e-35
-8.77158e-35
-1.6310674e-35
6.9110407e-35
2.8374646e-35
7.249574e-35
-8.326536e-36
-4.2208914e-35
3.380163e-07
0.00018250165
-4.091571e-13
-5.742375e-20
1.9097627e-29
-1.0989738e-34
4.988384e-06
-6.4157313e-25
0.0046886215
-4.15727e-06
8.565781e-06
1.3159001e-08
-6.0661813e-27
0.003999361
4.6603424e-12
0.05875436
0.1978433
0.2357523
0.26039347
0.29742035
0.23000301
0.22130986
0.32969925
-0.25387922
-0.21843708
-0.35505614
-0.18760061
-0.26636004
-0.3437664
-0.31676972
-2.9646424e-21
1.6212045e-32
-4.972171e-35
3.321333e-35
-3.0660306e-36
-1.2462985e-35
-6.15827e-35
-7.708171e-35
-8.6527984e-35
-9.63909e-35
-4.329017e-36
-1.6798441e-35
6.4576066e-36
1.0103299e-34
5.888647e-35
-7.013437e-07
-4.0569785e-06
-1.6326982e-07
-5.024649e-09
1.0218174e-08
-5.870887e-17
2.4735778e-05
-1.8678125e-28
-5.81377e-18
4.2194547e-08
-8.974654e-09
-8.819107e-18
-4.0505355e-36
1.4275389e-15
2.5213077e-35
0.0455311
-0.16154826
-0.12516226
-0.15351692
-0.15327676
-0.101601385
-0.09675424
-0.009882243
0.14380045
0.17609678
0.15136641
0.18814708
0.14553012
0.08837449
-0.033248488
-5.5479194e-13
-1.301003e-35
6.407329e-35
1.9132001e-35
9.564731e-15
-4.683806e-19
1.8975264e-24
2.1182613e-16
-3.6244807e-35
8.7545505e-28
6.0832183e-21
-8.545767e-31
5.2584422e-14
2.1925994e-22
-3.8261837e-20
-1.0880043e-34
-6.6652585e-35
-6.389439e-35
3.2505208e-35
-4.973718e-35
-3.3143227e-35
-8.6873607e-35
-7.993331e-35
-7.852833e-36
-6.3270696e-35
5.258114e-35
2.1151958e-35
7.3324824e-35
7.1793427e-35
-9.0051764e-35
0.3847243
-0.008498104
0.030268772
-0.13264672
0.030948505
-0.07938414
-0.04668712
-0.16404602
0.07313376
0.1522345
0.00048681977
0.01413009
-0.09327267
-0.055540953
-0.100918815
-0.06997617
-0.100417346
-0.11185439
-0.108010836
-0.1542093
-0.026418801
-0.0976361
0.2631115
0.110037416
-0.038920112
0.03310242
-0.07849237
0.087744445
-0.016706102
0.42764086
-0.063509755
-0.20127158
0.3405362
0.10242782
-0.25828084
-0.18461828
0.18166192
-0.13771532
-0.14198124
0.4270196
0.16850737
-0.13088605
-0.18872121
0.22758731
-0.07991603
-0.06114433
0.22688313
0.013428835
-0.12416983
0.32349384
-0.081210054
-0.33148897
-0.1045747
0.20436902
0.018065251
-0.15008682
0.3795789
-0.022265602
-0.2928385
0.012199368
0.067641154
0.10578058
0.16411996
0.20287563
0.24025424
0.109507106
0.12222239
0.071233526
-0.2886257
-0.10079892
-0.06812541
-0.16702725
-0.15010971
-0.19164395
-0.07202363
-0.035642263
-0.05917981
0.0028539933
-0.05592549
0.075735435
0.025915435
-0.04963067
-0.026535112
-0.020446347
-0.011010364
0.023280753
0.26113504
-0.012730428
-0.017266534
-0.02555099
6.6849823e-28
-4.636168e-36
-2.6241106e-35
-1.4760121e-35
-6.7957636e-35
-1.0416158e-34
1.6918945e-35
-4.6718995e-36
-4.7667602e-35
1.041564e-21
8.2043017e-32
5.477604e-35
-3.8711388e-35
6.7359426e-33
6.3444426e-35
0.14113876
-0.010778272
0.22688301
-0.09793554
-0.00012759774
-0.05420959
-0.10284228
-0.0711143
-0.019644944
0.33476868
-0.026679255
0.017077312
-0.08714616
-0.18292294
-0.008373551
0.010505794
0.37707043
-0.18333085
-0.08041537
-0.2416076
-0.1522789
0.43256167
-0.0788787
0.34045488
-0.18690895
-0.14016004
-0.17618605
-0.05683832
0.24356408
-0.16643535
-0.10966306
-0.06567155
-0.15500161
0.3614948
-0.09623325
0.21963693
-0.04084352
-0.075387344
-0.10502286
-0.0677372
0.27728274
-0.07640978
0.104514964
-0.10400845
-0.12442972
-0.036030225
0.25929874
-0.059436407
-0.10930109
0.3742339
-0.05711202
-0.40452525
0.11595321
0.17990495
-0.035048593
-0.15141624
0.30273277
-0.011792107
-0.4227198
0.053774044
1.1876719e-34
3.7372937e-35
-5.644917e-35
1.4523778e-35
-1.6516261e-35
-1.368295e-35
6.519924e-36
-1.058873e-34
7.093214e-35
-7.7837143e-35
-8.806991e-35
4.964243e-35
9.1717344e-35
9.3002685e-35
-2.2625807e-35
-0.062388267
0.009545127
-0.025250942
0.015120846
-0.053508114
-0.09033931
-0.00907598
0.42657125
0.020611048
-0.056661103
-0.13732637
-0.24770766
0.005481845
-0.07748723
0.34712294
-0.11283319
-0.16540128
0.29195973
-0.029924994
-0.058724944
-0.10992806
0.197207
-0.07528951
-0.19605869
0.27547538
-0.013697551
-0.055077918
-0.07406024
0.22788925
-0.081390664
0.12524118
-0.31053254
-0.13906848
-0.20176046
-0.14459138
-0.3867697
-0.3457261
-0.3772227
0.23137245
0.25195408
0.3451284
0.16130213
0.23533006
0.23638043
0.2719846
1.8297665e-07
3.360339e-23
-1.284517e-14
1.0518133e-13
-2.2031767e-08
-4.546128e-36
1.2173993e-14
-6.947489e-35
-8.3585253e-35
6.3733985e-36
4.228411e-37
-5.4181e-35
-6.841722e-35
5.6347666e-35
-4.7285032e-35
-6.334689e-35
1.7633159e-35
6.9929964e-35
7.5054075e-35
6.711354e-35
4.832629e-35
5.29919e-35
-4.058533e-35
2.0259362e-36
6.813992e-35
-2.0522695e-35
1.0627943e-34
8.187743e-35
7.9783384e-35
-9.2240445e-35
0.51590675
-0.05236788
-0.07348578
-0.07904794
0.036673676
-0.047585975
0.010659185
-0.05747693
-0.1176608
0.005955786
-0.04482761
-0.06267186
0.029963115
0.035390142
-0.16633497
0.04267569
0.06314773
-0.011022474
-0.17234531
-0.014564765
0.44928247
-0.06437395
0.021410124
-0.073853776
-0.14323992
-0.20758016
-0.08453873
0.37983018
-0.045325596
-0.08424267
-2.2948552e-16
1.0171164e-21
5.3094257e-22
1.1943568e-14
-7.934534e-14
-4.1972283e-35
-6.0988935e-31
8.206015e-32
1.8966156e-15
2.540294e-17
-9.855207e-18
1.5472988e-13
-9.217107e-35
-2.7734643e-16
-4.306558e-35