大版本更新。
This commit is contained in:
@@ -26,6 +26,7 @@ private:
|
||||
const uint8_t &enemy_color;
|
||||
State state;
|
||||
cv::Rect2d armor_box;
|
||||
int boxid;
|
||||
cv::Ptr<cv::Tracker> tracker;
|
||||
cv::Mat src_gray;
|
||||
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
#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);
|
||||
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_ */
|
||||
|
||||
@@ -14,7 +14,8 @@ ArmorFinder::ArmorFinder(uint8_t &color, Serial &u, string paras_folder, const u
|
||||
state(STANDBY_STATE),
|
||||
classifier(std::move(paras_folder)),
|
||||
contour_area(0),
|
||||
use_classifier(use)
|
||||
use_classifier(use),
|
||||
boxid(-1)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -25,11 +26,11 @@ void ArmorFinder::run(cv::Mat &src) {
|
||||
cv::cvtColor(src_use, src_gray, CV_RGB2GRAY);
|
||||
|
||||
if(show_armor_box){
|
||||
showArmorBox("box", src, 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)){
|
||||
|
||||
@@ -300,6 +300,7 @@ int Classifier::operator()(const cv::Mat &image) {
|
||||
vector<MatrixXd> sub = {b, g, r};
|
||||
vector<vector<MatrixXd>> in = {sub};
|
||||
MatrixXd result = calculate(in);
|
||||
// cout << result << "==============" <<endl;
|
||||
MatrixXd::Index minRow, minCol;
|
||||
result.maxCoeff(&minRow, &minCol);
|
||||
return minRow;
|
||||
|
||||
@@ -145,9 +145,9 @@ static bool findLightBlobs(const cv::Mat &src, LightBlobs &light_blobs) {
|
||||
}
|
||||
|
||||
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 :
|
||||
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 :
|
||||
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;
|
||||
}
|
||||
@@ -168,13 +168,42 @@ bool lengthRatioJudge(const LightBlob &light_blob_i, const LightBlob &light_blob
|
||||
&& 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);
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
@@ -195,8 +224,8 @@ static bool findArmorBoxes(LightBlobs &light_blobs, std::vector<cv::Rect2d> &arm
|
||||
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.3*(rect_left.height+rect_right.height)/2.0;
|
||||
max_y = fmax(rect_left.y + rect_left.height, rect_right.y + rect_right.height) + 0.3*(rect_left.height+rect_right.height)/2.0;
|
||||
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;
|
||||
}
|
||||
@@ -251,13 +280,13 @@ void get_blob_color(const cv::Mat &src, std::vector<LightBlob> &blobs) {
|
||||
}
|
||||
}
|
||||
|
||||
int prior_red[] = {0, 2, 3, 4, 1, 5, 7, 8, 9, 6};
|
||||
int prior_blue[]= {5, 7, 8, 9, 6, 0, 2, 3, 4, 1};
|
||||
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[10];
|
||||
std::vector<cv::Rect2d> armor_boxes, boxes_number[14];
|
||||
armor_box = cv::Rect2d(0,0,0,0);
|
||||
|
||||
cv::cvtColor(src, src_gray, CV_BGR2GRAY);
|
||||
@@ -295,7 +324,8 @@ bool ArmorFinder::stateSearchingTarget(cv::Mat &src) {
|
||||
light_blobs_real = light_blobs;
|
||||
get_blob_color(src, light_blobs_real);
|
||||
if(show_light_blobs){
|
||||
showContours("blobs_real", src, light_blobs_real);
|
||||
showContours("light_blobs", src, light_blobs_real);
|
||||
// showCuoWeiDu(src, light_blobs_real);
|
||||
cv::waitKey(1);
|
||||
}
|
||||
|
||||
@@ -319,6 +349,7 @@ bool ArmorFinder::stateSearchingTarget(cv::Mat &src) {
|
||||
for(auto id : prior_blue){
|
||||
if(!boxes_number[id].empty()){
|
||||
armor_box = boxes_number[id][0];
|
||||
boxid = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -326,6 +357,7 @@ bool ArmorFinder::stateSearchingTarget(cv::Mat &src) {
|
||||
for(auto id : prior_red){
|
||||
if(!boxes_number[id].empty()){
|
||||
armor_box = boxes_number[id][0];
|
||||
boxid = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -337,9 +369,17 @@ bool ArmorFinder::stateSearchingTarget(cv::Mat &src) {
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -1,7 +1,26 @@
|
||||
#include <show_images/show_images.h>
|
||||
#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) // 黑白图像
|
||||
@@ -27,20 +46,25 @@ void showArmorBoxClass(std::string window_names, const cv::Mat &src, vector<cv::
|
||||
{
|
||||
image2show = src.clone();
|
||||
}
|
||||
for(int i=0; i<10; i++){
|
||||
for(int i=0; i<14; i++){
|
||||
if(!boxes[i].empty()){
|
||||
for(auto box : boxes[i]){
|
||||
char buff[2] = {0};
|
||||
buff[0] = i + '0';
|
||||
rectangle(image2show, box, Scalar(0, 255, 0), 1);
|
||||
putText(image2show, buff, Point(box.x+2, box.y+2), cv::FONT_HERSHEY_TRIPLEX, 1, Scalar(255,0,0));
|
||||
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
|
||||
LOGE_INFO("Invalid box id:%d!", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
imshow(window_names, image2show);
|
||||
}
|
||||
|
||||
void showArmorBox(std::string windows_name, const cv::Mat &src, cv::Rect2d armor_box) {
|
||||
void showArmorBox(std::string windows_name, const cv::Mat &src, cv::Rect2d armor_box, int boxid) {
|
||||
static Mat image2show;
|
||||
if (src.type() == CV_8UC1) // 黑白图像
|
||||
{
|
||||
@@ -50,6 +74,14 @@ void showArmorBox(std::string windows_name, const cv::Mat &src, cv::Rect2d armor
|
||||
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
|
||||
LOGE_INFO("Invalid box id:%d!", boxid);
|
||||
imshow(windows_name, image2show);
|
||||
}
|
||||
|
||||
@@ -67,13 +99,49 @@ void showContours(std::string windows_name, const cv::Mat &src, const std::vecto
|
||||
|
||||
for(const auto &light_blob:light_blobs)
|
||||
{
|
||||
Scalar color;
|
||||
if(light_blob.BlobColor == BLOB_RED)
|
||||
rectangle(image2show, light_blob.rect.boundingRect(), Scalar(0,0,255), 3);
|
||||
if(light_blob.BlobColor == BLOB_BLUE)
|
||||
rectangle(image2show, light_blob.rect.boundingRect(), Scalar(255,0,0), 3);
|
||||
color = Scalar(0,0,255);
|
||||
else if(light_blob.BlobColor == BLOB_BLUE)
|
||||
color = Scalar(255,0,0);
|
||||
else
|
||||
rectangle(image2show, light_blob.rect.boundingRect(), Scalar(0,255,0), 3);
|
||||
color = Scalar(0,255,0);
|
||||
cv::Point2f vertices[4];
|
||||
light_blob.rect.points(vertices);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user