计算速度优化,摄像头读取逻辑改变,分类器更新。
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <show_images/show_images.h>
|
||||
#include <options/options.h>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#define DO_NOT_CNT_TIME
|
||||
#include <log.h>
|
||||
|
||||
|
||||
@@ -27,7 +28,7 @@ static bool lengthJudge(const LightBlob &light_blob_i, const LightBlob &light_bl
|
||||
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);
|
||||
return (side_length / light_blob_i.length < 10 && side_length / light_blob_i.length > 0.5);
|
||||
}
|
||||
|
||||
static bool lengthRatioJudge(const LightBlob &light_blob_i, const LightBlob &light_blob_j) {
|
||||
@@ -99,6 +100,7 @@ bool matchArmorBoxes(const cv::Mat &src, const LightBlobs &light_blobs, ArmorBox
|
||||
if (min_x < 0 || max_x > src.cols || min_y < 0 || max_y > src.rows) {
|
||||
continue;
|
||||
}
|
||||
if((max_x-min_x)/(max_y-min_y) < 0.8) 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),
|
||||
@@ -116,31 +118,35 @@ bool ArmorFinder::findArmorBox(const cv::Mat &src, ArmorBox &box) {
|
||||
|
||||
box.rect = cv::Rect2d(0, 0, 0, 0);
|
||||
box.id = -1;
|
||||
|
||||
if (!findLightBlobs(src, light_blobs)) {
|
||||
return false;
|
||||
}
|
||||
CNT_TIME("blob", {
|
||||
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;
|
||||
}
|
||||
CNT_TIME("boxes",{
|
||||
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;
|
||||
}
|
||||
CNT_TIME("classify: %d", {
|
||||
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;
|
||||
}
|
||||
}, armor_boxes.size());
|
||||
sort(armor_boxes.begin(), armor_boxes.end());
|
||||
if(armor_boxes[0].id != 0){
|
||||
box = armor_boxes[0];
|
||||
|
||||
@@ -13,14 +13,14 @@ static double lw_rate(const cv::RotatedRect &rect) {
|
||||
}
|
||||
|
||||
|
||||
static double areaRatio(const std::vector<cv::Point> &contour, const cv::RotatedRect &rect){
|
||||
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() < 3000) &&
|
||||
((rect.size.area() < 50 && areaRatio(contour, rect) > 0.4) ||
|
||||
(rect.size.area() >= 50 && areaRatio(contour, rect) > 0.6));
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ static float linePointX(const cv::Point2f &p1, const cv::Point2f &p2, int y) {
|
||||
|
||||
/// Todo:性能优化后的函数(还有点问题)
|
||||
static double get_blob_color_opt(const cv::Mat &src, cv::RotatedRect blobPos) {
|
||||
int blue_cnt=0, red_cnt=0;
|
||||
int blue_cnt = 0, red_cnt = 0;
|
||||
blobPos.size.height *= 1.05;
|
||||
blobPos.size.width *= 1.1;
|
||||
cv::Point2f corners[4];
|
||||
@@ -95,6 +95,11 @@ static double get_blob_color_opt(const cv::Mat &src, cv::RotatedRect blobPos) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool isSameBlob(LightBlob blob1, LightBlob blob2) {
|
||||
auto dist = blob1.rect.center - blob2.rect.center;
|
||||
return (dist.x * dist.x + dist.y * dist.y) < 9;
|
||||
}
|
||||
|
||||
static void imagePreProcess(cv::Mat &src) {
|
||||
static cv::Mat kernel_erode = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 5));
|
||||
erode(src, src, kernel_erode);
|
||||
@@ -119,41 +124,76 @@ bool ArmorFinder::findLightBlobs(const cv::Mat &src, LightBlobs &light_blobs) {
|
||||
std::vector<cv::Mat> channels; // 通道拆分
|
||||
|
||||
cv::split(src, channels); /************************/
|
||||
if (enemy_color == ENEMY_BLUE){ /* */
|
||||
if (enemy_color == ENEMY_BLUE) { /* */
|
||||
color_channel = channels[0]; /* 根据目标颜色进行通道提取 */
|
||||
}else if (enemy_color == ENEMY_RED){ /* */
|
||||
} else if (enemy_color == ENEMY_RED) { /* */
|
||||
color_channel = channels[2]; /************************/
|
||||
}
|
||||
|
||||
|
||||
|
||||
cv::threshold(color_channel, src_bin_light, 200, 255, CV_THRESH_BINARY); // 二值化对应通道
|
||||
if(src_bin_light.empty()) return false;
|
||||
if (src_bin_light.empty()) return false;
|
||||
imagePreProcess(src_bin_light); // 开闭运算
|
||||
|
||||
cv::threshold(color_channel, src_bin_dim, 140, 255, CV_THRESH_BINARY); // 二值化对应通道
|
||||
if(src_bin_dim.empty()) return false;
|
||||
if (src_bin_dim.empty()) return false;
|
||||
imagePreProcess(src_bin_dim); // 开闭运算
|
||||
|
||||
if(src_bin_light.size() == cv::Size(640, 480) && show_light_blobs) {
|
||||
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));
|
||||
std::vector<std::vector<cv::Point>> light_contours_light, light_contours_dim;
|
||||
LightBlobs light_blobs_light, light_blobs_dim;
|
||||
std::vector<cv::Vec4i> hierarchy_light, hierarchy_dim;
|
||||
cv::findContours(src_bin_light, light_contours_light, hierarchy_light, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);
|
||||
cv::findContours(src_bin_dim, light_contours_dim, hierarchy_dim, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);
|
||||
for (int i = 0; i < light_contours_light.size(); i++) {
|
||||
if (hierarchy_light[i][2] == -1) {
|
||||
cv::RotatedRect rect = cv::minAreaRect(light_contours_light[i]);
|
||||
if (isValidLightBlob(light_contours_light[i], rect)) {
|
||||
light_blobs_light.emplace_back(
|
||||
rect, areaRatio(light_contours_light[i], 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));
|
||||
for (int i = 0; i < light_contours_dim.size(); i++) {
|
||||
if (hierarchy_dim[i][2] == -1) {
|
||||
cv::RotatedRect rect = cv::minAreaRect(light_contours_dim[i]);
|
||||
if (isValidLightBlob(light_contours_dim[i], rect)) {
|
||||
light_blobs_dim.emplace_back(
|
||||
rect, areaRatio(light_contours_dim[i], rect), get_blob_color(src, rect)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
vector<int> light_to_remove, dim_to_remove;
|
||||
for (int l = 0; l != light_blobs_light.size(); l++) {
|
||||
for (int d = 0; d != light_blobs_dim.size(); d++) {
|
||||
if (isSameBlob(light_blobs_light[l], light_blobs_dim[d])) {
|
||||
if (light_blobs_light[l].areaRatio > light_blobs_dim[d].areaRatio) {
|
||||
dim_to_remove.emplace_back(d);
|
||||
} else {
|
||||
light_to_remove.emplace_back(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sort(light_to_remove.begin(), light_to_remove.end(), [](int a, int b) { return a > b; });
|
||||
sort(dim_to_remove.begin(), dim_to_remove.end(), [](int a, int b) { return a > b; });
|
||||
for (auto x : light_to_remove) {
|
||||
light_blobs_light.erase(light_blobs_light.begin() + x);
|
||||
}
|
||||
for (auto x : dim_to_remove) {
|
||||
light_blobs_dim.erase(light_blobs_dim.begin() + x);
|
||||
}
|
||||
for (const auto &light : light_blobs_light) {
|
||||
light_blobs.emplace_back(light);
|
||||
}
|
||||
for (const auto &dim : light_blobs_dim) {
|
||||
light_blobs.emplace_back(dim);
|
||||
}
|
||||
return light_blobs.size() >= 2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user