| | |
| | | enable_language(CUDA) |
| | | |
| | | set(CMAKE_CXX_COMPILIER "/usr/bin/g++") |
| | | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3 -Wno-write-strings") |
| | | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,$ORIGIN") |
| | | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3 -DS_DEBUG -Wno-write-strings") |
| | | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -DS_DEBUG -Wl,-rpath -Wl,$ORIGIN") |
| | | |
| | | set(CUDA_Path /usr/local/cuda) |
| | | find_package(OpenCV REQUIRED PATHS "/data/disk2/opt/01_opencv/opencv4.5.2") |
| | |
| | | set( |
| | | CUDA_NVCC_FLAGS |
| | | ${CUDA_NVCC_FLAGS}; |
| | | -gencode arch=compute_61,code=sm_61 -std=c++14# 不同GPU有不同的算力指数,可查看算力表 |
| | | -gencode arch=compute_80,code=sm_80 -std=c++14# 不同GPU有不同的算力指数,可查看算力表 |
| | | -gencode arch=compute_72,code=sm_72 -std=c++14# 不同GPU有不同的算力指数,可查看算力表 |
| | | -gencode arch=compute_75,code=sm_75 -std=c++14# 不同GPU有不同的算力指数,可查看算力表 |
| | | -gencode arch=compute_61,code=sm_61 -std=c++14 |
| | | -gencode arch=compute_80,code=sm_80 -std=c++14 |
| | | -gencode arch=compute_72,code=sm_72 -std=c++14 |
| | | -gencode arch=compute_75,code=sm_75 -std=c++14 |
| | | ) |
| | | set(CUDA_NVCC_FLAGS_RELWITHDEBINFO "--device-debug;-lineinfo") |
| | | #find_package(OpenCV REQUIRED) # 查找系统的默认opencv环境 |
| | |
| | | |
| | | |
| | | cuda_add_library(${PROJECT_NAME} SHARED ${sources}) |
| | | target_include_directories(${PROJECT_NAME} PRIVATE ${OpenCV_INCLUDE_DIRS} src/ src/core src/utils/ src/detecter_tools/) |
| | | target_include_directories(${PROJECT_NAME} PRIVATE ${OpenCV_INCLUDE_DIRS} src/ src/core src/utils/ src/tracker_tools/ src/Munkers_assign/ src/detecter_tools/ src/additional/) |
| | | target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS} ${LIBS}) |
| | | |
| | | add_executable(demo demo.cpp) |
| | | target_include_directories(demo PRIVATE src/ src/core src/utils/ src/detecter_tools/) |
| | | target_include_directories(demo PRIVATE src/ src/core src/utils/ src/detecter_tools/ src/tracker_tools/ src/Munkers_assign/ src/additional/) |
| | | target_link_libraries(demo ${PROJECT_NAME}) |
| | | |
| | | # add_executable(demo demo.cpp ${sources}) |
| | |
| | | "param": {
|
| | | "model_path": "/data/disk1/project/model_dump/02_yolo/baseDetect-kFLOAT-batch1.engine", // para里边自己算法可能用到的参数
|
| | | //"model_path": "/data/disk1/project/model_dump/02_yolo/baseDetetor_small.bin", // para里边自己算法可能用到的参数
|
| | | "type":1
|
| | | "type":1,
|
| | | "max_cam_num": 8,
|
| | | "wander_time": 5,
|
| | | "mv_velocity": 10.0,
|
| | | "fall_rate":1.3,
|
| | | "isTrack":false
|
| | | }
|
| | | }
|
| | |
| | | using namespace std; |
| | | using namespace cv; |
| | | void* handle; |
| | | bool do_frame(Mat frame, TImage *img, void *sr, void* handle, int cam_id) |
| | | { |
| | | if(!frame.empty()) |
| | | { |
| | | img->width = frame.cols; |
| | | img->height = frame.rows; |
| | | img->channel = frame.channels(); |
| | | img->data = frame.data; |
| | | const char * img_time = fa_getSysTime(); |
| | | const char* mode = "video"; |
| | | // printf("===%s\n",img_time); |
| | | std::cout<< "===%s:" << img_time << std::endl; |
| | | |
| | | sr = get_result2(handle, img, cam_id, img_time, mode); |
| | | TResult * t_result = (TResult*) sr; |
| | | cout << "=======t_result->count==" << t_result->count << endl; |
| | | for (int i=0; i<t_result->count; i++) |
| | | { |
| | | cout << "====1111111111===confidence:" << t_result->targets[i].confidence << endl; |
| | | cout << "====1111111111===attri:" << t_result->targets[i].attribute << endl; |
| | | } |
| | | |
| | | return true; |
| | | }else{ |
| | | cout << "-----------------------over--" << endl; |
| | | release(handle); |
| | | release_result(sr); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | int main(int argc, char *argv[]) |
| | | { |
| | |
| | | cap >> frame; |
| | | if(!frame.empty()) |
| | | { |
| | | img->width = frame.cols; |
| | | img->height = frame.rows; |
| | | img->channel = frame.channels(); |
| | | img->data = frame.data; |
| | | sr = get_result(handle, img, 0); |
| | | TResult * t_result = (TResult*) sr; |
| | | cout << "t_result->count==" << t_result->count << endl; |
| | | for (int i=0; i<t_result->count; i++) |
| | | { |
| | | cout << "confidence:" << t_result->targets[i].confidence << endl; |
| | | // draw_SDK_result(frame, t_result->targets[i]); |
| | | } |
| | | // std::clock_t t_strat2 = std::clock(); |
| | | if(!do_frame(frame, img, sr, handle, i)) |
| | | return 0; |
| | | cout << "-------------" << endl; |
| | | }else{ |
| | | cout << "------------over--" << endl; |
| | | release(handle); |
| New file |
| | |
| | | #include "hungarianoper.h"
|
| | |
|
| | | Eigen::Matrix<float, -1, 2, Eigen::RowMajor> HungarianOper::Solve(const DYNAMICM &cost_matrix)
|
| | | {
|
| | | int rows = cost_matrix.rows();
|
| | | int cols = cost_matrix.cols();
|
| | | Matrix<double> matrix(rows, cols);
|
| | | for (int row = 0; row < rows; row++) {
|
| | | for (int col = 0; col < cols; col++) {
|
| | | matrix(row, col) = cost_matrix(row, col);
|
| | | }
|
| | | }
|
| | | //Munkres get matrix;
|
| | | Munkres<double> m;
|
| | | m.solve(matrix);
|
| | |
|
| | | //
|
| | | std::vector<std::pair<int, int>> pairs;
|
| | | for (int row = 0; row < rows; row++) {
|
| | | for (int col = 0; col < cols; col++) {
|
| | | int tmp = (int)matrix(row, col);
|
| | | if (tmp == 0) pairs.push_back(std::make_pair(row, col));
|
| | | }
|
| | | }
|
| | | //
|
| | | int count = pairs.size();
|
| | | Eigen::Matrix<float, -1, 2, Eigen::RowMajor> re(count, 2);
|
| | | for (int i = 0; i < count; i++) {
|
| | | re(i, 0) = pairs[i].first;
|
| | | re(i, 1) = pairs[i].second;
|
| | | }
|
| | | return re;
|
| | | }//end Solve;
|
| New file |
| | |
| | | #ifndef HUNGARIANOPER_H
|
| | | #define HUNGARIANOPER_H
|
| | | #include "munkres/munkres.h"
|
| | | //#include "munkres/adapters/boostmatrixadapter.h"
|
| | | #include "../tracker_tools/dataType.h"
|
| | |
|
| | | class HungarianOper {
|
| | | public:
|
| | | static Eigen::Matrix<float, -1, 2, Eigen::RowMajor> Solve(const DYNAMICM &cost_matrix);
|
| | | };
|
| | |
|
| | | #endif // HUNGARIANOPER_H
|
| New file |
| | |
| | | /*
|
| | | * Copyright (c) 2007 John Weaver
|
| | | *
|
| | | * This program is free software; you can redistribute it and/or modify
|
| | | * it under the terms of the GNU General Public License as published by
|
| | | * the Free Software Foundation; either version 2 of the License, or
|
| | | * (at your option) any later version.
|
| | | *
|
| | | * This program is distributed in the hope that it will be useful,
|
| | | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| | | * GNU General Public License for more details.
|
| | | *
|
| | | * You should have received a copy of the GNU General Public License
|
| | | * along with this program; if not, write to the Free Software
|
| | | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
| | | */
|
| | |
|
| | | #ifndef _MATRIX_H_
|
| | | #define _MATRIX_H_
|
| | |
|
| | | #include <initializer_list>
|
| | | #include <cstdlib>
|
| | | #include <ostream>
|
| | | #include <cassert>
|
| | | #include <cstdlib>
|
| | | #include <algorithm>
|
| | |
|
| | | #define XYZMIN(x, y) (x)<(y)?(x):(y)
|
| | | #define XYZMAX(x, y) (x)>(y)?(x):(y)
|
| | |
|
| | | template <class T>
|
| | | class Matrix {
|
| | | public:
|
| | | Matrix(){
|
| | | m_rows = 0;
|
| | | m_columns = 0;
|
| | | m_matrix = nullptr;
|
| | | }
|
| | | Matrix(const size_t rows, const size_t columns) {
|
| | | m_matrix = nullptr;
|
| | | resize(rows, columns);
|
| | | }
|
| | | Matrix(const std::initializer_list<std::initializer_list<T>> init) {
|
| | | m_matrix = nullptr;
|
| | | m_rows = init.size();
|
| | | if ( m_rows == 0 ) {
|
| | | m_columns = 0;
|
| | | } else {
|
| | | m_columns = init.begin()->size();
|
| | | if ( m_columns > 0 ) {
|
| | | resize(m_rows, m_columns);
|
| | | }
|
| | | }
|
| | |
|
| | | size_t i = 0, j;
|
| | | for ( auto row = init.begin() ; row != init.end() ; ++row, ++i ) {
|
| | | assert ( row->size() == m_columns && "All rows must have the same number of columns." );
|
| | | j = 0;
|
| | | for ( auto value = row->begin() ; value != row->end() ; ++value, ++j ) {
|
| | | m_matrix[i][j] = *value;
|
| | | }
|
| | | }
|
| | | }
|
| | | Matrix(const Matrix<T> &other) {
|
| | | if ( other.m_matrix != nullptr ) {
|
| | | // copy arrays
|
| | | m_matrix = nullptr;
|
| | | resize(other.m_rows, other.m_columns);
|
| | | for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
| | | for ( size_t j = 0 ; j < m_columns ; j++ ) {
|
| | | m_matrix[i][j] = other.m_matrix[i][j];
|
| | | }
|
| | | }
|
| | | } else {
|
| | | m_matrix = nullptr;
|
| | | m_rows = 0;
|
| | | m_columns = 0;
|
| | | }
|
| | | }
|
| | | Matrix<T> & operator= (const Matrix<T> &other){
|
| | | if ( other.m_matrix != nullptr ) {
|
| | | // copy arrays
|
| | | resize(other.m_rows, other.m_columns);
|
| | | for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
| | | for ( size_t j = 0 ; j < m_columns ; j++ ) {
|
| | | m_matrix[i][j] = other.m_matrix[i][j];
|
| | | }
|
| | | }
|
| | | } else {
|
| | | // free arrays
|
| | | for ( size_t i = 0 ; i < m_columns ; i++ ) {
|
| | | delete [] m_matrix[i];
|
| | | }
|
| | |
|
| | | delete [] m_matrix;
|
| | |
|
| | | m_matrix = nullptr;
|
| | | m_rows = 0;
|
| | | m_columns = 0;
|
| | | }
|
| | |
|
| | | return *this;
|
| | | }
|
| | | ~Matrix(){
|
| | | if ( m_matrix != nullptr ) {
|
| | | // free arrays
|
| | | for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
| | | delete [] m_matrix[i];
|
| | | }
|
| | |
|
| | | delete [] m_matrix;
|
| | | }
|
| | | m_matrix = nullptr;
|
| | | }
|
| | | // all operations modify the matrix in-place.
|
| | | void resize(const size_t rows, const size_t columns, const T default_value = 0) {
|
| | | assert ( rows > 0 && columns > 0 && "Columns and rows must exist." );
|
| | |
|
| | | if ( m_matrix == nullptr ) {
|
| | | // alloc arrays
|
| | | m_matrix = new T*[rows]; // rows
|
| | | for ( size_t i = 0 ; i < rows ; i++ ) {
|
| | | m_matrix[i] = new T[columns]; // columns
|
| | | }
|
| | |
|
| | | m_rows = rows;
|
| | | m_columns = columns;
|
| | | clear();
|
| | | } else {
|
| | | // save array pointer
|
| | | T **new_matrix;
|
| | | // alloc new arrays
|
| | | new_matrix = new T*[rows]; // rows
|
| | | for ( size_t i = 0 ; i < rows ; i++ ) {
|
| | | new_matrix[i] = new T[columns]; // columns
|
| | | for ( size_t j = 0 ; j < columns ; j++ ) {
|
| | | new_matrix[i][j] = default_value;
|
| | | }
|
| | | }
|
| | |
|
| | | // copy data from saved pointer to new arrays
|
| | | size_t minrows = XYZMIN(rows, m_rows);
|
| | | size_t mincols = XYZMIN(columns, m_columns);
|
| | | for ( size_t x = 0 ; x < minrows ; x++ ) {
|
| | | for ( size_t y = 0 ; y < mincols ; y++ ) {
|
| | | new_matrix[x][y] = m_matrix[x][y];
|
| | | }
|
| | | }
|
| | |
|
| | | // delete old arrays
|
| | | if ( m_matrix != nullptr ) {
|
| | | for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
| | | delete [] m_matrix[i];
|
| | | }
|
| | |
|
| | | delete [] m_matrix;
|
| | | }
|
| | |
|
| | | m_matrix = new_matrix;
|
| | | }
|
| | |
|
| | | m_rows = rows;
|
| | | m_columns = columns;
|
| | | }
|
| | | void clear() {
|
| | | assert( m_matrix != nullptr );
|
| | |
|
| | | for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
| | | for ( size_t j = 0 ; j < m_columns ; j++ ) {
|
| | | m_matrix[i][j] = 0;
|
| | | }
|
| | | }
|
| | | }
|
| | | T& operator () (const size_t x, const size_t y) {
|
| | | assert ( x < m_rows );
|
| | | assert ( y < m_columns );
|
| | | assert ( m_matrix != nullptr );
|
| | | return m_matrix[x][y];
|
| | | }
|
| | |
|
| | | const T& operator () (const size_t x, const size_t y) const {
|
| | | assert ( x < m_rows );
|
| | | assert ( y < m_columns );
|
| | | assert ( m_matrix != nullptr );
|
| | | return m_matrix[x][y];
|
| | | }
|
| | | const T mmin() const {
|
| | | assert( m_matrix != nullptr );
|
| | | assert ( m_rows > 0 );
|
| | | assert ( m_columns > 0 );
|
| | | T min = m_matrix[0][0];
|
| | |
|
| | | for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
| | | for ( size_t j = 0 ; j < m_columns ; j++ ) {
|
| | | min = std::min<T>(min, m_matrix[i][j]);
|
| | | }
|
| | | }
|
| | |
|
| | | return min;
|
| | | }
|
| | |
|
| | | const T mmax() const {
|
| | | assert( m_matrix != nullptr );
|
| | | assert ( m_rows > 0 );
|
| | | assert ( m_columns > 0 );
|
| | | T max = m_matrix[0][0];
|
| | |
|
| | | for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
| | | for ( size_t j = 0 ; j < m_columns ; j++ ) {
|
| | | max = std::max<T>(max, m_matrix[i][j]);
|
| | | }
|
| | | }
|
| | |
|
| | | return max;
|
| | | }
|
| | | inline size_t minsize() { return ((m_rows < m_columns) ? m_rows : m_columns); }
|
| | | inline size_t columns() const { return m_columns;}
|
| | | inline size_t rows() const { return m_rows;}
|
| | |
|
| | | friend std::ostream& operator<<(std::ostream& os, const Matrix &matrix)
|
| | | {
|
| | | os << "Matrix:" << std::endl;
|
| | | for (size_t row = 0 ; row < matrix.rows() ; row++ )
|
| | | {
|
| | | for (size_t col = 0 ; col < matrix.columns() ; col++ )
|
| | | {
|
| | | os.width(8);
|
| | | os << matrix(row, col) << ",";
|
| | | }
|
| | | os << std::endl;
|
| | | }
|
| | | return os;
|
| | | }
|
| | |
|
| | | private:
|
| | | T **m_matrix;
|
| | | size_t m_rows;
|
| | | size_t m_columns;
|
| | | };
|
| | |
|
| | | //#ifndef USE_EXPORT_KEYWORD
|
| | | //#include "matrix.cpp"
|
| | | ////#define export /*export*/
|
| | | //#endif
|
| | |
|
| | | #endif /* !defined(_MATRIX_H_) */
|
| | |
|
| New file |
| | |
| | | /*
|
| | | * Copyright (c) 2007 John Weaver
|
| | | * Copyright (c) 2015 Miroslav Krajicek
|
| | | *
|
| | | * This program is free software; you can redistribute it and/or modify
|
| | | * it under the terms of the GNU General Public License as published by
|
| | | * the Free Software Foundation; either version 2 of the License, or
|
| | | * (at your option) any later version.
|
| | | *
|
| | | * This program is distributed in the hope that it will be useful,
|
| | | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| | | * GNU General Public License for more details.
|
| | | *
|
| | | * You should have received a copy of the GNU General Public License
|
| | | * along with this program; if not, write to the Free Software
|
| | | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
| | | */
|
| | |
|
| | | #include "munkres.h"
|
| | |
|
| | | template class Munkres<double>;
|
| | | template class Munkres<float>;
|
| | | template class Munkres<int>;
|
| | |
|
| New file |
| | |
| | | /*
|
| | | * Copyright (c) 2007 John Weaver
|
| | | * *
|
| | | * This program is free software; you can redistribute it and/or modify
|
| | | * it under the terms of the GNU General Public License as published by
|
| | | * the Free Software Foundation; either version 2 of the License, or
|
| | | * (at your option) any later version.
|
| | | *
|
| | | * This program is distributed in the hope that it will be useful,
|
| | | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| | | * GNU General Public License for more details.
|
| | | *
|
| | | * You should have received a copy of the GNU General Public License
|
| | | * along with this program; if not, write to the Free Software
|
| | | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
| | | */
|
| | |
|
| | | #if !defined(_MUNKRES_H_)
|
| | | #define _MUNKRES_H_
|
| | |
|
| | | #include "matrix.h"
|
| | |
|
| | | #include <list>
|
| | | #include <utility>
|
| | | #include <iostream>
|
| | | #include <cmath>
|
| | | #include <limits>
|
| | |
|
| | |
|
| | | template<typename Data> class Munkres
|
| | | {
|
| | | static constexpr int NORMAL = 0;
|
| | | static constexpr int STAR = 1;
|
| | | static constexpr int PRIME = 2;
|
| | | public:
|
| | |
|
| | | /*
|
| | | *
|
| | | * Linear assignment problem solution
|
| | | * [modifies matrix in-place.]
|
| | | * matrix(row,col): row major format assumed.
|
| | | *
|
| | | * Assignments are remaining 0 values
|
| | | * (extra 0 values are replaced with -1)
|
| | | *
|
| | | */
|
| | | void solve(Matrix<Data> &m) {
|
| | | const size_t rows = m.rows(),
|
| | | columns = m.columns(),
|
| | | size = XYZMAX(rows, columns);
|
| | |
|
| | | #ifdef DEBUG
|
| | | std::cout << "Munkres input: " << m << std::endl;
|
| | | #endif
|
| | |
|
| | | // Copy input matrix
|
| | | this->matrix = m;
|
| | |
|
| | | if ( rows != columns ) {
|
| | | // If the input matrix isn't square, make it square
|
| | | // and fill the empty values with the largest value present
|
| | | // in the matrix.
|
| | | matrix.resize(size, size, matrix.mmax());
|
| | | }
|
| | |
|
| | |
|
| | | // STAR == 1 == starred, PRIME == 2 == primed
|
| | | mask_matrix.resize(size, size);
|
| | |
|
| | | row_mask = new bool[size];
|
| | | col_mask = new bool[size];
|
| | | for ( size_t i = 0 ; i < size ; i++ ) {
|
| | | row_mask[i] = false;
|
| | | }
|
| | |
|
| | | for ( size_t i = 0 ; i < size ; i++ ) {
|
| | | col_mask[i] = false;
|
| | | }
|
| | |
|
| | | // Prepare the matrix values...
|
| | |
|
| | | // If there were any infinities, replace them with a value greater
|
| | | // than the maximum value in the matrix.
|
| | | replace_infinites(matrix);
|
| | |
|
| | | minimize_along_direction(matrix, rows >= columns);
|
| | | minimize_along_direction(matrix, rows < columns);
|
| | |
|
| | | // Follow the steps
|
| | | int step = 1;
|
| | | while ( step ) {
|
| | | switch ( step ) {
|
| | | case 1:
|
| | | step = step1();
|
| | | // step is always 2
|
| | | break;
|
| | | case 2:
|
| | | step = step2();
|
| | | // step is always either 0 or 3
|
| | | break;
|
| | | case 3:
|
| | | step = step3();
|
| | | // step in [3, 4, 5]
|
| | | break;
|
| | | case 4:
|
| | | step = step4();
|
| | | // step is always 2
|
| | | break;
|
| | | case 5:
|
| | | step = step5();
|
| | | // step is always 3
|
| | | break;
|
| | | }
|
| | | }
|
| | |
|
| | | // Store results
|
| | | for ( size_t row = 0 ; row < size ; row++ ) {
|
| | | for ( size_t col = 0 ; col < size ; col++ ) {
|
| | | if ( mask_matrix(row, col) == STAR ) {
|
| | | matrix(row, col) = 0;
|
| | | } else {
|
| | | matrix(row, col) = -1;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | #ifdef DEBUG
|
| | | std::cout << "Munkres output: " << matrix << std::endl;
|
| | | #endif
|
| | | // Remove the excess rows or columns that we added to fit the
|
| | | // input to a square matrix.
|
| | | matrix.resize(rows, columns);
|
| | |
|
| | | m = matrix;
|
| | |
|
| | | delete [] row_mask;
|
| | | delete [] col_mask;
|
| | | }
|
| | |
|
| | | static void replace_infinites(Matrix<Data> &matrix) {
|
| | | const size_t rows = matrix.rows(),
|
| | | columns = matrix.columns();
|
| | | //assert( rows > 0 && columns > 0 );
|
| | | double max = matrix(0, 0);
|
| | | constexpr auto infinity = std::numeric_limits<double>::infinity();
|
| | |
|
| | | // Find the greatest value in the matrix that isn't infinity.
|
| | | for ( size_t row = 0 ; row < rows ; row++ ) {
|
| | | for ( size_t col = 0 ; col < columns ; col++ ) {
|
| | | if ( matrix(row, col) != infinity ) {
|
| | | if ( max == infinity ) {
|
| | | max = matrix(row, col);
|
| | | } else {
|
| | | max = XYZMAX(max, matrix(row, col));
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | // a value higher than the maximum value present in the matrix.
|
| | | if ( max == infinity ) {
|
| | | // This case only occurs when all values are infinite.
|
| | | max = 0;
|
| | | } else {
|
| | | max++;
|
| | | }
|
| | |
|
| | | for ( size_t row = 0 ; row < rows ; row++ ) {
|
| | | for ( size_t col = 0 ; col < columns ; col++ ) {
|
| | | if ( matrix(row, col) == infinity ) {
|
| | | matrix(row, col) = max;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | }
|
| | | static void minimize_along_direction(Matrix<Data> &matrix, const bool over_columns) {
|
| | | const size_t outer_size = over_columns ? matrix.columns() : matrix.rows(),
|
| | | inner_size = over_columns ? matrix.rows() : matrix.columns();
|
| | |
|
| | | // Look for a minimum value to subtract from all values along
|
| | | // the "outer" direction.
|
| | | for ( size_t i = 0 ; i < outer_size ; i++ ) {
|
| | | double min = over_columns ? matrix(0, i) : matrix(i, 0);
|
| | |
|
| | | // As long as the current minimum is greater than zero,
|
| | | // keep looking for the minimum.
|
| | | // Start at one because we already have the 0th value in min.
|
| | | for ( size_t j = 1 ; j < inner_size && min > 0 ; j++ ) {
|
| | | min = XYZMIN(
|
| | | min,
|
| | | over_columns ? matrix(j, i) : matrix(i, j));
|
| | | }
|
| | |
|
| | | if ( min > 0 ) {
|
| | | for ( size_t j = 0 ; j < inner_size ; j++ ) {
|
| | | if ( over_columns ) {
|
| | | matrix(j, i) -= min;
|
| | | } else {
|
| | | matrix(i, j) -= min;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | private:
|
| | |
|
| | | inline bool find_uncovered_in_matrix(const double item, size_t &row, size_t &col) const {
|
| | | const size_t rows = matrix.rows(),
|
| | | columns = matrix.columns();
|
| | |
|
| | | for ( row = 0 ; row < rows ; row++ ) {
|
| | | if ( !row_mask[row] ) {
|
| | | for ( col = 0 ; col < columns ; col++ ) {
|
| | | if ( !col_mask[col] ) {
|
| | | if ( matrix(row,col) == item ) {
|
| | | return true;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | return false;
|
| | | }
|
| | |
|
| | | bool pair_in_list(const std::pair<size_t,size_t> &needle, const std::list<std::pair<size_t,size_t> > &haystack) {
|
| | | for ( std::list<std::pair<size_t,size_t> >::const_iterator i = haystack.begin() ; i != haystack.end() ; i++ ) {
|
| | | if ( needle == *i ) {
|
| | | return true;
|
| | | }
|
| | | }
|
| | |
|
| | | return false;
|
| | | }
|
| | |
|
| | | int step1() {
|
| | | const size_t rows = matrix.rows(),
|
| | | columns = matrix.columns();
|
| | |
|
| | | for ( size_t row = 0 ; row < rows ; row++ ) {
|
| | | for ( size_t col = 0 ; col < columns ; col++ ) {
|
| | | if ( 0 == matrix(row, col) ) {
|
| | | for ( size_t nrow = 0 ; nrow < row ; nrow++ )
|
| | | if ( STAR == mask_matrix(nrow,col) )
|
| | | goto next_column;
|
| | |
|
| | | mask_matrix(row,col) = STAR;
|
| | | goto next_row;
|
| | | }
|
| | | next_column:;
|
| | | }
|
| | | next_row:;
|
| | | }
|
| | |
|
| | | return 2;
|
| | | }
|
| | |
|
| | | int step2() {
|
| | | const size_t rows = matrix.rows(),
|
| | | columns = matrix.columns();
|
| | | size_t covercount = 0;
|
| | |
|
| | | for ( size_t row = 0 ; row < rows ; row++ )
|
| | | for ( size_t col = 0 ; col < columns ; col++ )
|
| | | if ( STAR == mask_matrix(row, col) ) {
|
| | | col_mask[col] = true;
|
| | | covercount++;
|
| | | }
|
| | |
|
| | | if ( covercount >= matrix.minsize() ) {
|
| | | #ifdef DEBUG
|
| | | std::cout << "Final cover count: " << covercount << std::endl;
|
| | | #endif
|
| | | return 0;
|
| | | }
|
| | |
|
| | | #ifdef DEBUG
|
| | | std::cout << "Munkres matrix has " << covercount << " of " << matrix.minsize() << " Columns covered:" << std::endl;
|
| | | std::cout << matrix << std::endl;
|
| | | #endif
|
| | |
|
| | |
|
| | | return 3;
|
| | | }
|
| | |
|
| | | int step3() {
|
| | | /*
|
| | | Main Zero Search
|
| | |
|
| | | 1. Find an uncovered Z in the distance matrix and prime it. If no such zero exists, go to Step 5
|
| | | 2. If No Z* exists in the row of the Z', go to Step 4.
|
| | | 3. If a Z* exists, cover this row and uncover the column of the Z*. Return to Step 3.1 to find a new Z
|
| | | */
|
| | | if ( find_uncovered_in_matrix(0, saverow, savecol) ) {
|
| | | mask_matrix(saverow,savecol) = PRIME; // prime it.
|
| | | } else {
|
| | | return 5;
|
| | | }
|
| | |
|
| | | for ( size_t ncol = 0 ; ncol < matrix.columns() ; ncol++ ) {
|
| | | if ( mask_matrix(saverow,ncol) == STAR ) {
|
| | | row_mask[saverow] = true; //cover this row and
|
| | | col_mask[ncol] = false; // uncover the column containing the starred zero
|
| | | return 3; // repeat
|
| | | }
|
| | | }
|
| | |
|
| | | return 4; // no starred zero in the row containing this primed zero
|
| | | }
|
| | |
|
| | | int step4() {
|
| | | const size_t rows = matrix.rows(),
|
| | | columns = matrix.columns();
|
| | |
|
| | | // seq contains pairs of row/column values where we have found
|
| | | // either a star or a prime that is part of the ``alternating sequence``.
|
| | | std::list<std::pair<size_t,size_t> > seq;
|
| | | // use saverow, savecol from step 3.
|
| | | std::pair<size_t,size_t> z0(saverow, savecol);
|
| | | seq.insert(seq.end(), z0);
|
| | |
|
| | | // We have to find these two pairs:
|
| | | std::pair<size_t,size_t> z1(-1, -1);
|
| | | std::pair<size_t,size_t> z2n(-1, -1);
|
| | |
|
| | | size_t row, col = savecol;
|
| | | /*
|
| | | Increment Set of Starred Zeros
|
| | |
|
| | | 1. Construct the ``alternating sequence'' of primed and starred zeros:
|
| | |
|
| | | Z0 : Unpaired Z' from Step 4.2
|
| | | Z1 : The Z* in the column of Z0
|
| | | Z[2N] : The Z' in the row of Z[2N-1], if such a zero exists
|
| | | Z[2N+1] : The Z* in the column of Z[2N]
|
| | |
|
| | | The sequence eventually terminates with an unpaired Z' = Z[2N] for some N.
|
| | | */
|
| | | bool madepair;
|
| | | do {
|
| | | madepair = false;
|
| | | for ( row = 0 ; row < rows ; row++ ) {
|
| | | if ( mask_matrix(row,col) == STAR ) {
|
| | | z1.first = row;
|
| | | z1.second = col;
|
| | | if ( pair_in_list(z1, seq) ) {
|
| | | continue;
|
| | | }
|
| | |
|
| | | madepair = true;
|
| | | seq.insert(seq.end(), z1);
|
| | | break;
|
| | | }
|
| | | }
|
| | |
|
| | | if ( !madepair )
|
| | | break;
|
| | |
|
| | | madepair = false;
|
| | |
|
| | | for ( col = 0 ; col < columns ; col++ ) {
|
| | | if ( mask_matrix(row, col) == PRIME ) {
|
| | | z2n.first = row;
|
| | | z2n.second = col;
|
| | | if ( pair_in_list(z2n, seq) ) {
|
| | | continue;
|
| | | }
|
| | | madepair = true;
|
| | | seq.insert(seq.end(), z2n);
|
| | | break;
|
| | | }
|
| | | }
|
| | | } while ( madepair );
|
| | |
|
| | | for ( std::list<std::pair<size_t,size_t> >::iterator i = seq.begin() ;
|
| | | i != seq.end() ;
|
| | | i++ ) {
|
| | | // 2. Unstar each starred zero of the sequence.
|
| | | if ( mask_matrix(i->first,i->second) == STAR )
|
| | | mask_matrix(i->first,i->second) = NORMAL;
|
| | |
|
| | | // 3. Star each primed zero of the sequence,
|
| | | // thus increasing the number of starred zeros by one.
|
| | | if ( mask_matrix(i->first,i->second) == PRIME )
|
| | | mask_matrix(i->first,i->second) = STAR;
|
| | | }
|
| | |
|
| | | // 4. Erase all primes, uncover all columns and rows,
|
| | | for ( size_t row = 0 ; row < mask_matrix.rows() ; row++ ) {
|
| | | for ( size_t col = 0 ; col < mask_matrix.columns() ; col++ ) {
|
| | | if ( mask_matrix(row,col) == PRIME ) {
|
| | | mask_matrix(row,col) = NORMAL;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | for ( size_t i = 0 ; i < rows ; i++ ) {
|
| | | row_mask[i] = false;
|
| | | }
|
| | |
|
| | | for ( size_t i = 0 ; i < columns ; i++ ) {
|
| | | col_mask[i] = false;
|
| | | }
|
| | |
|
| | | // and return to Step 2.
|
| | | return 2;
|
| | | }
|
| | |
|
| | | int step5() {
|
| | | const size_t rows = matrix.rows(),
|
| | | columns = matrix.columns();
|
| | | /*
|
| | | New Zero Manufactures
|
| | |
|
| | | 1. Let h be the smallest uncovered entry in the (modified) distance matrix.
|
| | | 2. Add h to all covered rows.
|
| | | 3. Subtract h from all uncovered columns
|
| | | 4. Return to Step 3, without altering stars, primes, or covers.
|
| | | */
|
| | | double h = 100000;//xyzoylz std::numeric_limits<double>::max();
|
| | | for ( size_t row = 0 ; row < rows ; row++ ) {
|
| | | if ( !row_mask[row] ) {
|
| | | for ( size_t col = 0 ; col < columns ; col++ ) {
|
| | | if ( !col_mask[col] ) {
|
| | | if ( h > matrix(row, col) && matrix(row, col) != 0 ) {
|
| | | h = matrix(row, col);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | for ( size_t row = 0 ; row < rows ; row++ ) {
|
| | | if ( row_mask[row] ) {
|
| | | for ( size_t col = 0 ; col < columns ; col++ ) {
|
| | | matrix(row, col) += h;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | for ( size_t col = 0 ; col < columns ; col++ ) {
|
| | | if ( !col_mask[col] ) {
|
| | | for ( size_t row = 0 ; row < rows ; row++ ) {
|
| | | matrix(row, col) -= h;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | return 3;
|
| | | }
|
| | |
|
| | | Matrix<int> mask_matrix;
|
| | | Matrix<Data> matrix;
|
| | | bool *row_mask;
|
| | | bool *col_mask;
|
| | | size_t saverow = 0, savecol = 0;
|
| | | };
|
| | |
|
| | |
|
| | | #endif /* !defined(_MUNKRES_H_) */
|
| New file |
| | |
| | | #include <unistd.h>
|
| | | #include <cstdlib>
|
| | | #include <algorithm>
|
| | | #include "fall_run_wander.h"
|
| | |
|
| | | /** 判断跌倒:
|
| | | 两个特征:1、宽高的比率;2、比率的变化速度(取变化后的和最初设计的小值)3、跌倒后的重心下降 4、跌倒过程小于1.5s
|
| | | return 跌倒的概率,以及持续的时间
|
| | | */
|
| | |
|
| | | //void detect_fall(DETECTBOX tmpbox, std::shared_ptr<Track>& track)
|
| | | //{
|
| | | // float rate = tmpbox(2)/tmpbox(3);
|
| | | // if(rate < track->rate)
|
| | | // {
|
| | | // track->rate = rate;
|
| | | // track->isFall = false;
|
| | | // }
|
| | | //
|
| | | //
|
| | | // // 更新track->rate_queue以及记录minRate的相关信息
|
| | | // if(track->rate_queue.size()>=5)
|
| | | // {
|
| | | // track->rate_queue.pop();
|
| | | //
|
| | | // }else if(track->rate_queue.isEmpty())
|
| | | // {
|
| | | // track->minRate = rate;
|
| | | // gettimeofday(&track->min_rate_time,0);
|
| | | //
|
| | | // track->center_point.x = float(tmpbox(0)+tmpbox(2)/2);
|
| | | // track->center_point.y = float(tmpbox(1)+tmpbox(3)/2);
|
| | | // track->human_h = tmpbox(3);
|
| | | // }
|
| | | //
|
| | | // if(track->rate_queue.size()>0)
|
| | | // {
|
| | | // if(track->rate_queue.min()>=rate)
|
| | | // {
|
| | | // track->minRate = rate;
|
| | | // gettimeofday(&track->min_rate_time,0);
|
| | | // track->center_point.x = float(tmpbox(0)+tmpbox(2)/2);
|
| | | // track->center_point.y = float(tmpbox(1)+tmpbox(3)/2);
|
| | | // if(rate>0.25)
|
| | | // {
|
| | | // track->human_h = tmpbox(3);
|
| | | // track->human_w = tmpbox(2);
|
| | | // }
|
| | | // }
|
| | | // }
|
| | | //
|
| | | // if(track->hisMinRate>=rate)
|
| | | // {
|
| | | // track->hisMinRate=rate;
|
| | | // track->min_center_point.x = float(tmpbox(0)+tmpbox(2)/2);
|
| | | // track->min_center_point.y = float(tmpbox(1)+tmpbox(3)/2);
|
| | | // }
|
| | | //
|
| | | // track->rate_queue.push(rate);
|
| | | //
|
| | | // // 判断是否跌倒
|
| | | //// float fall_threshold = 1.3; //默认调参1.3(能和蹲下区分的参数)
|
| | | // gettimeofday(&track->fall_e_time,0); // 当前比例时间
|
| | | // track->time_substract(&track->fall_diff_time,&track->min_rate_time,&track->fall_e_time); //距离最小比例的时间
|
| | | // int fall_rate_time = (int)(track->fall_diff_time.tv_sec*1000 + track->fall_diff_time.tv_usec/1000);
|
| | | // float fall_threshold = m_staticStruct::fall_rate;
|
| | | //
|
| | | // if((rate > std::min(fall_threshold, 5*track->rate)||track->human_h>=tmpbox(3)*2*track->human_w/tmpbox(2)) && fall_rate_time<2000 && std::min(track->min_center_point.y, track->center_point.y)<float(tmpbox(1)+tmpbox(3)/2))
|
| | | // {
|
| | | // track->isFall = true;
|
| | | //// std::cout << fall_threshold <<"-- fall_threshold--:" << rate << ":" << 5*track->rate <<std::endl;
|
| | | // }
|
| | | // else if(rate < 0.9)
|
| | | // {
|
| | | // track->isFall = false;
|
| | | // track->fall_total_time = 0 ;
|
| | | // track->first_Fall = true;
|
| | | // }
|
| | | //
|
| | | // // 计算跌倒置信度
|
| | | // if(track->isFall)
|
| | | // {
|
| | | // /**-- start计算累积跌倒时间*/
|
| | | // if(track->first_Fall) //是否开始计算跌倒时间
|
| | | // {
|
| | | // track->first_Fall = false;
|
| | | // gettimeofday(&track->fall_s_time,0);
|
| | | // }
|
| | | // gettimeofday(&track->fall_e_time,0);
|
| | | // track->time_substract(&track->fall_diff_time,&track->fall_s_time,&track->fall_e_time); //距离最小比例的时间
|
| | | // track->fall_total_time = (int)(track->fall_diff_time.tv_sec + track->fall_diff_time.tv_usec/1000000);
|
| | | //
|
| | | // /** -- end计算累积跌倒时间*/
|
| | | //
|
| | | // track->rateScale = int(std::min(float((rate - 0.6)*72), 100.0f));
|
| | | //
|
| | | // if(track->rateScale<0)
|
| | | // {
|
| | | // track->rateScale = 0-track->rateScale;
|
| | | // }
|
| | | // }else
|
| | | // {
|
| | | // track->rateScale = int(std::max(float(10 - (fall_threshold - rate)*10), 0.0f));
|
| | | // }
|
| | | //
|
| | | // // std::cout << track->fall_total_time << "::" << fall_rate_time << ":" <<track->min_center_point.y <<"-"<< track->center_point.y << ":"<<float(tmpbox(1)+tmpbox(3)/2) <<"-- fall--:" << rate << ":" << track->isFall <<std::endl;
|
| | | // // std::cout << track->human_h << ":::f:::" << tmpbox(3)*4*track->human_w/tmpbox(2) <<std::endl;
|
| | | //}
|
| | |
|
| | | /**
|
| | | 算法思想: 判断点的人体脚点的移动移动速度,移动的速度为单帧的移动距离比上单帧画面所花费的时间
|
| | | 做了一个10帧的队列,对队列中的速度进行平滑处理
|
| | |
|
| | | 改进点:根据不同的画面位置 进行移动距离的放缩
|
| | | 横纵画面距离的权重平衡(横纵的变化速度不一样)
|
| | | */
|
| | | float detect_runing(DETECTBOX tmpbox, std::shared_ptr<Track>& track, cv::Mat img)
|
| | | {
|
| | | float human_pointX = tmpbox(0) + tmpbox(2)/2;
|
| | | float human_pointY = tmpbox(1);
|
| | | double rate = tmpbox(2)/tmpbox(3);
|
| | | double curr_area = tmpbox(2)*tmpbox(3);
|
| | |
|
| | | float move_velocity = 0;
|
| | | float ave_velocity = 0;
|
| | | if(track->is_runing_p)
|
| | | {
|
| | | track->last_point.x = human_pointX;
|
| | | track->last_point.y = human_pointY;
|
| | | track->is_runing_p = false;
|
| | | }else
|
| | | {
|
| | | SPoint curr_point(human_pointX, human_pointY);
|
| | | float move_distance = calDistance(curr_point, track->last_point);
|
| | | if(tmpbox(1)<0 ||tmpbox(1)+tmpbox(3)>=img.rows)
|
| | | {
|
| | | ave_velocity=0;
|
| | | queue<float> empty;
|
| | | swap(empty,track->velocity_queue);
|
| | | track->sum_velocity=0;
|
| | | track->run_rate = rate;
|
| | | }
|
| | | move_velocity = move_distance/track->single_time;
|
| | |
|
| | | // std::cout << curr_point.x << ":" << curr_point.y <<"-------------------" <<track->last_point.x<< "::" << track->last_point.y <<std::endl;
|
| | | // std::cout << move_distance <<"-------- move_velocity:" << track->single_time << "::" << move_velocity <<std::endl;
|
| | |
|
| | | track->last_point.x = human_pointX;
|
| | | track->last_point.y = human_pointY;
|
| | |
|
| | | if(track->velocity_queue.size()==10)
|
| | | {
|
| | | float last_velocity = track->velocity_queue.front();
|
| | | track->sum_velocity -= last_velocity;
|
| | | track->velocity_queue.pop();
|
| | | // std::cout << "-------- last_velocity:" << last_velocity <<std::endl;
|
| | | }
|
| | | track->velocity_queue.push(move_velocity);
|
| | | track->sum_velocity += move_velocity;
|
| | | }
|
| | |
|
| | | if (track->velocity_queue.size()>0)
|
| | | {
|
| | | ave_velocity = track->sum_velocity/track->velocity_queue.size();
|
| | | }else
|
| | | {
|
| | | ave_velocity = 0;
|
| | | }
|
| | |
|
| | | double diff_rate = fabs(rate - track->run_rate);
|
| | | double min_area = curr_area>track->rate_area?track->rate_area:curr_area;
|
| | | double max_area = curr_area>track->rate_area?curr_area:track->rate_area;
|
| | | double rate_area = fabs(min_area/max_area); //面积比例变化
|
| | | double last_diff_rate = fabs(rate - track->last_rate);
|
| | | // std::cout <<rate_area<<"::::"<< rate << " ---------------------------------rate:"<<track->run_rate <<"===== diff_rate:" << diff_rate <<":::" << last_diff_rate <<std::endl;
|
| | | if(diff_rate>0.2 || last_diff_rate>0.2 || tmpbox(1)<0 || rate_area<0.8 ||tmpbox(1)+tmpbox(3)>=img.rows)
|
| | | {
|
| | | ave_velocity=0;
|
| | | queue<float> empty;
|
| | | swap(empty,track->velocity_queue);
|
| | | track->sum_velocity=0;
|
| | | track->run_rate = rate;
|
| | | }
|
| | | track->last_rate = rate;
|
| | | track->rate_area = curr_area;
|
| | |
|
| | | // std::cout << move_velocity << " :"<<track->sum_velocity <<"===== sum_velocity:" << track->velocity_queue.size() << "::" << ave_velocity <<std::endl;
|
| | |
|
| | | // std::cout << ave_velocity << "===== m_staticStruct::mv_velocity:" << std::endl;
|
| | |
|
| | |
|
| | | return ave_velocity;
|
| | | } |
| New file |
| | |
| | | //
|
| | | // Created by Scheaven on 2020/6/1.
|
| | | //
|
| | |
|
| | | #ifndef INC_01_DARKNET_SORT_FALL_RUN_WANDER_H
|
| | | #define INC_01_DARKNET_SORT_FALL_RUN_WANDER_H
|
| | |
|
| | | #include "../tracker_tools/track.h"
|
| | | #include "../config.h"
|
| | |
|
| | |
|
| | | void detect_fall(DETECTBOX tmpbox, std::shared_ptr<Track>& track);
|
| | |
|
| | | float detect_runing(DETECTBOX tmpbox, std::shared_ptr<Track>& track, cv::Mat img);
|
| | |
|
| | | #endif //INC_01_DARKNET_SORT_FALL_RUN_WANDER_H
|
| | |
| | |
|
| | | #ifndef INC_01_CPP_SORT_CONFIG_H
|
| | | #define INC_01_CPP_SORT_CONFIG_H
|
| | | #include "utils/timer_utils.hpp"
|
| | | #include "utils/time_util.h"
|
| | |
|
| | | #include <opencv2/opencv.hpp>
|
| | | #include <algorithm>
|
| | |
| | | #include "cuda_runtime_api.h"
|
| | | #include "NvInfer.h"
|
| | |
|
| | | const int nn_budget=100;
|
| | | const float max_cosine_distance=0.7;
|
| | |
|
| | | #define NN_BUDGET 100
|
| | | #define MAX_COSINE_DISTANCE 0.7
|
| | | #define MAX_IOU_DISTANCE 0.9
|
| | | #define MAX_AGE 450
|
| | | #define MAX_OUT_TIME 30.0
|
| | | #define N_INIT 5
|
| | |
|
| | | struct bbox_t {
|
| | | unsigned int x, y, w, h; // (x,y) - top-left corner, (w, h) - width & height of bounded box
|
| | | float prob; // confidence - probability that the object was found correctly
|
| | |
| | | {
|
| | | static std::string model_path;
|
| | | static int type;
|
| | | static bool isTrack;
|
| | | static int max_cam_num;
|
| | | static int wander_time;
|
| | | static float mv_velocity;
|
| | | static float fall_rate;
|
| | | }M_STATICSTRUCT, *P_STATICSTRUCT;
|
| | | #endif //INC_01_CPP_SORT_CONFIG_H
|
| | |
|
| | |
| | | //
|
| | |
|
| | | #include "ari_manager.h"
|
| | |
|
| | | #include "../additional/fall_run_wander.h"
|
| | |
|
| | | AriManager::AriManager()
|
| | | {
|
| | |
| | |
|
| | | }
|
| | |
|
| | | void AriManager::single_SDK(const int cam_id, const void *img, TResult& t_result)
|
| | | void AriManager::release()
|
| | | {
|
| | | DetecterManager::getInstance()->release();
|
| | | }
|
| | |
|
| | | void AriManager::init_load_model()
|
| | | {
|
| | | DEBUG("::loading detecter model!");
|
| | | DetecterManager::getInstance();
|
| | | }
|
| | |
|
| | | bool AriManager::add_cam(const int cam_id)
|
| | | {
|
| | | if (cam_id==(this->CAMERAS_VCT.size()+1))
|
| | | {
|
| | | auto cam_tracker = std::make_shared<tracker>(max_cosine_distance, nn_budget);
|
| | | this->CAMERAS_VCT.push_back(cam_tracker);
|
| | | return true;
|
| | | }else if(cam_id<this->CAMERAS_VCT.size())
|
| | | {
|
| | | WARN("The camera ID " + to_string(cam_id) + "is occupied!");
|
| | | return false;
|
| | | }else
|
| | | {
|
| | | WARN("Camera ID" + to_string(cam_id) + "discontinuous!");
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | void AriManager::single_SDK(const int cam_id, const void *img, TResult *t_result, char* img_time, const char* mode)
|
| | | {
|
| | | TImage *frame_img = (TImage*)img;
|
| | | // DEBUG((boost::format("%f, %f")%frame_img->width %frame_img->height).str());
|
| | | cv::Mat frame(Size(frame_img->width, frame_img->height), CV_8UC3); // size 是w,h Mat是h,w
|
| | | frame.data = (uchar*)frame_img->data; //注意不能写为:(uchar*)pFrameBGR->data
|
| | | cv::Mat draw_frame = frame.clone();
|
| | | Timer s_timer;
|
| | | s_timer.reset();
|
| | | DETECTIONS detections;
|
| | | DetecterManager::getInstance()->detecter_main(draw_frame, detections);
|
| | | s_timer.out("eve detecter_main");
|
| | |
|
| | | std::string mode_type = mode;
|
| | | DEBUG("detections human size::" + to_string(detections.size()));
|
| | | if(detections.size()>0)
|
| | | {
|
| | | if (mode_type == "video")
|
| | | {
|
| | | // if(HUMAN_STRUCT::reid_Extractor->featsEncoder(frame, detections) == false)
|
| | | // {
|
| | | // WARN("Encoder human feature failed!");
|
| | | // }
|
| | | // auto t_strat2 = std::chrono::steady_clock::now();
|
| | | // s_timer.out(to_string(detections.size())+" :eve reid_Extractor");
|
| | | single_tracker(cam_id, detections, img_time);
|
| | | s_timer.out("eve single_tracker");
|
| | | // auto t_strat3 = std::chrono::steady_clock::now();
|
| | | // std::cout<< "detections.size()" << detections.size()<< std::endl;
|
| | | switch_SDK_TResult(cam_id, frame, detections, t_result);
|
| | | // auto t_strat4 = std::chrono::steady_clock::now();
|
| | | s_timer.out("eve switch_SDK_TResult");
|
| | | // double t_9 = std::chrono::duration<double, std::milli>(t_strat8 - t_strat9).count();
|
| | | // double t_8 = std::chrono::duration<double, std::milli>(t_strat7 - t_strat8).count();
|
| | | // double t_7 = std::chrono::duration<double, std::milli>(t_strat6 - t_strat7).count();
|
| | | // double t_6 = std::chrono::duration<double, std::milli>(t_strat1 - t_strat6).count();
|
| | | // double t_1 = std::chrono::duration<double, std::milli>(t_strat2 - t_strat1).count();
|
| | | // double t_2 = std::chrono::duration<double, std::milli>(t_strat3 - t_strat2).count();
|
| | | // double t_3 = std::chrono::duration<double, std::milli>(t_strat4 - t_strat3).count();
|
| | | // double t_0 = std::chrono::duration<double, std::milli>(t_strat4 - t_strat9).count();
|
| | | // std::cout << "fps time:" << to_string(t_9) << " : " << to_string(t_8) << " : " << to_string(t_7) << " : " << to_string(t_6) <<std::endl;
|
| | | // std::cout << "fps runing_time:" << to_string(t_1) << " : " << to_string(t_2) << " : " << to_string(t_3) << std::endl;
|
| | | // std::cout << "fps all time " << t_0<< std::endl;
|
| | | // }
|
| | | DEBUG(":::::::::single_SDK end:::::");
|
| | | }
|
| | | else
|
| | | {
|
| | | switch_SDK_TResult(detections, t_result);
|
| | | }
|
| | | }
|
| | |
|
| | | }
|
| | |
|
| | | void AriManager::single_SDK(const int cam_id, const void *img, TResult* t_result)
|
| | | {
|
| | | TImage *frame_img = (TImage*)img;
|
| | | cv::Mat frame(Size(frame_img->width, frame_img->height), CV_8UC3);
|
| | |
| | | // cv::waitKey(0);
|
| | | this->detector->detect(batch_img, batch_res);
|
| | |
|
| | | t_result.targets = (Target*)malloc(sizeof(Target)*batch_res[0].size());
|
| | | // 将算法结果转化为标准的格式(以目标检测为例)""
|
| | | t_result->targets = (Target*)malloc(sizeof(Target)*batch_res[0].size());
|
| | | int w_count = 0;
|
| | | for (const auto &result_box:batch_res[0])
|
| | | {
|
| | |
| | | target.rect.right = result_box.rect.x + result_box.rect.width;
|
| | | target.rect.bottom = result_box.rect.y + result_box.rect.height;
|
| | |
|
| | | target.confidence = result_box.prob*100; // 置信度转化成百分制
|
| | | target.confidence = result_box.prob*100;
|
| | | // target.id = 1; //
|
| | |
|
| | | // target.attribute 可根据实际情况来添加,输出格式要求是json格式
|
| | |
|
| | | //string attribute_json = "{";
|
| | | //attribute_json += "\"smokingScore\":" + to_string(track->smokeScore)+",";
|
| | | //if(attribute_json.length()>2)
|
| | | //{
|
| | | // attribute_json = attribute_json.substr(0, attribute_json.length()-1) +"}";
|
| | | // target.attribute = new char[strlen(attribute_json.c_str())+1];
|
| | | // target.attribute_size = strlen(attribute_json.c_str());
|
| | | // strcpy(target.attribute, attribute_json.c_str());
|
| | | //}
|
| | | float mv_velocity = 0;
|
| | | int runScore = 0;
|
| | | string attribute_json = "{";
|
| | |
|
| | | t_result.targets[w_count] = target;
|
| | | if (m_staticStruct::fall_rate!=0)
|
| | | {
|
| | | // detect_fall(tmpbox, track);
|
| | | attribute_json += "\"fallScore\":" + to_string(0)+",";
|
| | | }
|
| | |
|
| | | if (m_staticStruct::mv_velocity!=0)
|
| | | {
|
| | | attribute_json += "\"runScore\":" + to_string(0)+",";
|
| | | }
|
| | |
|
| | | attribute_json += "\"hatScore\":" + to_string(0)+",";
|
| | |
|
| | | attribute_json += "\"helmetScore\":" + to_string(0)+",";
|
| | |
|
| | | attribute_json += "\"headScore\":" + to_string(0)+",";
|
| | |
|
| | | attribute_json += "\"maskScore\":" + to_string(0)+",";
|
| | |
|
| | | attribute_json += "\"smokingScore\":" + to_string(0)+",";
|
| | |
|
| | | DEBUG("image attribute_json:: "+ attribute_json);
|
| | |
|
| | | if(attribute_json.length()>2)
|
| | | {
|
| | | //转换输出的json格式 {"fallScore":100,"runScore":15.8,"wanderScore":10}
|
| | | attribute_json = attribute_json.substr(0, attribute_json.length()-1) +"}";
|
| | | target.attribute = new char[strlen(attribute_json.c_str())+1];
|
| | | target.attribute_size = strlen(attribute_json.c_str());
|
| | | strcpy(target.attribute, attribute_json.c_str());
|
| | | }
|
| | |
|
| | | t_result->targets[w_count] = target;
|
| | | w_count ++;
|
| | | }
|
| | | }
|
| | | std::cout << "eve batch_res size:: "<< batch_res[0].size() << " w_count: " << w_count <<std::endl;
|
| | | t_result.count = w_count;
|
| | | draw_SDK_result(cam_id, frame, t_result); //多线程无法调用绘图
|
| | | t_result->count = w_count;
|
| | | // draw_SDK_result(cam_id, frame, t_result);
|
| | | }
|
| | |
|
| | | void AriManager::init_target(Target *t){
|
| | |
|
| | | void AriManager::switch_SDK_TResult(DETECTIONS detections, TResult *t_result)
|
| | | {
|
| | | t_result->targets = (Target*)malloc(sizeof(Target) * detections.size());
|
| | | int w_count = 0;
|
| | | for(auto& detection :detections)
|
| | | {
|
| | | Target target;
|
| | | init_target(&target);
|
| | | // RESULT_STRUCT result;
|
| | |
|
| | | DETECTBOX tmpbox = detection.tlwh;
|
| | |
|
| | | istringstream iss(random_int(6));
|
| | | iss >> target.id;
|
| | |
|
| | | target.rect.left = tmpbox(0);
|
| | | target.rect.top = tmpbox(1);
|
| | | target.rect.right = tmpbox(0) + tmpbox(2);
|
| | | target.rect.bottom = tmpbox(1) + tmpbox(3);
|
| | |
|
| | | target.confidence = detection.confidence*100;
|
| | |
|
| | | float mv_velocity = 0;
|
| | | int runScore = 0;
|
| | | string attribute_json = "{";
|
| | |
|
| | | if (m_staticStruct::fall_rate!=0)
|
| | | {
|
| | | // detect_fall(tmpbox, track);
|
| | | attribute_json += "\"fallScore\":" + to_string(detection.fallScore)+",";
|
| | | }
|
| | |
|
| | | if (m_staticStruct::mv_velocity!=0)
|
| | | {
|
| | | attribute_json += "\"runScore\":" + to_string(detection.runScore)+",";
|
| | | }
|
| | |
|
| | | attribute_json += "\"hatScore\":" + to_string(detection.hatScore)+",";
|
| | |
|
| | | attribute_json += "\"helmetScore\":" + to_string(detection.helmetScore)+",";
|
| | |
|
| | | attribute_json += "\"headScore\":" + to_string(detection.headScore)+",";
|
| | |
|
| | | attribute_json += "\"maskScore\":" + to_string(detection.maskScore)+",";
|
| | |
|
| | | attribute_json += "\"smokingScore\":" + to_string(detection.smokeScore)+",";
|
| | |
|
| | | DEBUG("image attribute_json:: "+ attribute_json);
|
| | |
|
| | | if(attribute_json.length()>2)
|
| | | {
|
| | | //转换输出的json格式 {"fallScore":100,"runScore":15.8,"wanderScore":10}
|
| | | attribute_json = attribute_json.substr(0, attribute_json.length()-1) +"}";
|
| | | target.attribute = new char[strlen(attribute_json.c_str())+1];
|
| | | target.attribute_size = strlen(attribute_json.c_str());
|
| | | strcpy(target.attribute, attribute_json.c_str());
|
| | | }
|
| | |
|
| | | t_result->targets[w_count] = target;
|
| | | w_count ++;
|
| | | }
|
| | |
|
| | | t_result->count = w_count;
|
| | | }
|
| | |
|
| | | // 转换成SDK 想要的结果
|
| | | void AriManager::switch_SDK_TResult(int cam_id, cv::Mat img, DETECTIONS detections, TResult *t_result)
|
| | | {
|
| | | t_result->targets = (Target*)malloc(sizeof(Target) * this->CAMERAS_VCT[cam_id]->tracks.size());
|
| | | int w_count = 0;
|
| | | for(auto& track :this->CAMERAS_VCT[cam_id]->tracks)
|
| | | {
|
| | | // if(not track->isCurrent) //当前画面没有则返回
|
| | | // continue;
|
| | | Target target;
|
| | | init_target(&target);
|
| | | // RESULT_STRUCT result;
|
| | | if(!track->is_confirmed() || track->time_since_update >= 1) continue;
|
| | | // if(track->is_confirmed() && track->time_since_update >= 1) continue;
|
| | |
|
| | | /*
|
| | | * 算法思想:跟踪器跟踪的时候,是否能够强制将预测错位置的box框强制更新成新的box框,而id不发生变化
|
| | | * */
|
| | |
|
| | | // DETECTBOX tmpbox = track->to_tlwh();
|
| | | DETECTBOX tmpbox = track->to_xywh();
|
| | |
|
| | | target.rect.left = tmpbox(0);
|
| | | target.rect.top = tmpbox(1);
|
| | | target.rect.right = tmpbox(0) + tmpbox(2);
|
| | | target.rect.bottom = tmpbox(1) + tmpbox(3);
|
| | | // DEBUG((boost::format("%s:%d, %s:%d, %s:%d, %s:%d") %"id:" %track->track_id %"conf:" %track->confidence %", to tmpbox y:" %tmpbox(1) %", tmpbox(3) h:" %tmpbox(3)).str());
|
| | |
|
| | | target.id = track->track_id;
|
| | | target.confidence = track->confidence;
|
| | |
|
| | | float mv_velocity = 0;
|
| | | int runScore = 0;
|
| | | string attribute_json = "{";
|
| | |
|
| | | if (m_staticStruct::fall_rate!=0)
|
| | | {
|
| | | // detect_fall(tmpbox, track);
|
| | | attribute_json += "\"fallScore\":" + to_string(track->rateScale)+"," + "\"fallTime\":" + to_string(track->fall_total_time) + ",";
|
| | | }
|
| | |
|
| | | if (m_staticStruct::mv_velocity!=0)
|
| | | {
|
| | | if(track->isRuning)
|
| | | {
|
| | | mv_velocity = detect_runing(tmpbox, track, img);
|
| | | float run_velocity = mv_velocity;
|
| | | if(tmpbox(2)/tmpbox(3)<0)
|
| | | {
|
| | | run_velocity*=(img.cols*img.rows)/(tmpbox(2)*tmpbox(3));
|
| | | }else
|
| | | {
|
| | | run_velocity*=10;
|
| | | }
|
| | | // std::cout << mv_velocity << "mv_velocity::::::::::" << run_velocity << "::::::::::::"<<img.cols*img.rows<<":::"<<tmpbox(2)*tmpbox(3)<<std::endl;
|
| | | runScore = (track->confidence+2)*int(std::min(4*run_velocity, 100.0f));
|
| | | attribute_json += "\"runScore\":" + to_string(runScore)+",";
|
| | | }else if(track->is_hat)
|
| | | {
|
| | | mv_velocity = detect_runing(tmpbox, track, img);
|
| | | float run_velocity = mv_velocity;
|
| | | if(tmpbox(2)/tmpbox(3)<0)
|
| | | {
|
| | | run_velocity*=(img.cols*img.rows)/(tmpbox(2)*tmpbox(3));
|
| | | }else
|
| | | {
|
| | | run_velocity*=15;
|
| | | }
|
| | | // std::cout << mv_velocity << "mv_velocity::::::::::" << run_velocity << "::::::::::::"<<img.cols*img.rows<<":::"<<tmpbox(2)*tmpbox(3)<<std::endl;
|
| | | runScore = int(std::min(4*run_velocity, 100.0f));
|
| | | attribute_json += "\"runScore\":" + to_string(runScore)+",";
|
| | | }else
|
| | | attribute_json += "\"runScore\":" + to_string(runScore)+",";
|
| | |
|
| | |
|
| | | }
|
| | |
|
| | | //std::cout << track->track_id <<"-- human wander last time:" << track->last_time << ":" << m_staticStruct::wander_time <<std::endl;
|
| | |
|
| | | if(m_staticStruct::wander_time!=0)
|
| | | {
|
| | | if (track->last_time>m_staticStruct::wander_time)
|
| | | track->isWander = true;
|
| | | else
|
| | | track->isWander = false;
|
| | | attribute_json += "\"wanderTime\":" + to_string(track->last_time)+",";
|
| | | }
|
| | |
|
| | | if(track->is_hat)
|
| | | {
|
| | | attribute_json += "\"hatScore\":" + to_string(track->hatScore)+",";
|
| | | }else
|
| | | {
|
| | | attribute_json += "\"hatScore\":" + to_string(10)+",";
|
| | | }
|
| | |
|
| | | if(track->is_mask)
|
| | | {
|
| | | attribute_json += "\"maskScore\":" + to_string(track->maskScore)+",";
|
| | | }else
|
| | | {
|
| | | attribute_json += "\"maskScore\":" + to_string(10)+",";
|
| | | }
|
| | |
|
| | |
|
| | | if(track->is_smoke)
|
| | | {
|
| | | attribute_json += "\"smokingScore\":" + to_string(track->smokeScore)+",";
|
| | | }else
|
| | | {
|
| | | attribute_json += "\"smokingScore\":" + to_string(10)+",";
|
| | | }
|
| | |
|
| | | // cout << ":::::::::::::"<<attribute_json << endl;
|
| | |
|
| | | if(attribute_json.length()>2)
|
| | | {
|
| | | //转换输出的json格式 {"fallScore":100,"runScore":15.8,"wanderScore":10}
|
| | | attribute_json = attribute_json.substr(0, attribute_json.length()-1) +"}";
|
| | | target.attribute = new char[strlen(attribute_json.c_str())+1];
|
| | | target.attribute_size = strlen(attribute_json.c_str());
|
| | | strcpy(target.attribute, attribute_json.c_str());
|
| | | }
|
| | |
|
| | | t_result->targets[w_count] = target;
|
| | | w_count ++;
|
| | | }
|
| | |
|
| | | t_result->count = w_count;
|
| | | // printf("================================%d\n\n\n\n", t_result->count);
|
| | | #ifdef S_DEBUG
|
| | | draw_SDK_result(cam_id, img, t_result);
|
| | | #endif
|
| | | }
|
| | |
|
| | | void AriManager::single_tracker(int cam_id, DETECTIONS& detections, char* img_time)
|
| | | {
|
| | | // DETECTIONS detections = deal_features(boxes, feats_vec); // 使用传递特征追踪时需要打开该方法
|
| | | // printf("cam_id::::%d",cam_id);
|
| | | std::string str2 = img_time;
|
| | | img_time[str2.find_last_of(":")] = '.';
|
| | |
|
| | | // DEBUG( img_time);
|
| | | auto cam_tracker = this->CAMERAS_VCT[cam_id];
|
| | |
|
| | | DEBUG("single_tracker start:: ");
|
| | | cam_tracker->predict();
|
| | | cam_tracker->update(CAMERAS_VCT, detections, cam_id, img_time);
|
| | | DEBUG("single_tracker::");
|
| | | this->CAMERAS_VCT[cam_id] = cam_tracker;
|
| | | }
|
| | |
|
| | |
|
| | | void AriManager::init_target(Target *t)
|
| | | {
|
| | | t->attribute = NULL;
|
| | | t->feature = NULL;
|
| | | t->id = 0;
|
| | |
| | | t->attribute_size = 0;
|
| | | t->feature_size = 0;
|
| | | }
|
| | |
|
| | |
| | | #include "config.h"
|
| | | #include "detector.h"
|
| | | #include "../utils/draw_util.h"
|
| | | #include "../tracker_tools/tracker.h"
|
| | | #include "detecter_manager.h"
|
| | | // #include "../utils/result_util.h"
|
| | |
|
| | |
|
| | | using namespace std;
|
| | | using namespace cv;
|
| | |
| | | int cam_id; //指定待追踪摄像机编号
|
| | | Mat frame;
|
| | |
|
| | | std::vector<std::shared_ptr<tracker>> CAMERAS_VCT;
|
| | | std::vector<DETECTIONS> DETECTION_VCT;
|
| | |
|
| | | private:
|
| | | std::shared_ptr<Detector> detector;
|
| | | static void init_target(Target *t);
|
| | | void switch_SDK_TResult(int cam_id, cv::Mat img, DETECTIONS detections, TResult *t_result);
|
| | | void switch_SDK_TResult(DETECTIONS detections, TResult *t_result);
|
| | | void single_tracker(int cam_id, DETECTIONS& detections, char* img_time);
|
| | |
|
| | | public:
|
| | | AriManager();
|
| | | ~AriManager();
|
| | | void single_SDK(const int cam_id, const void *img, TResult& t_result); // 检测+追踪 接口(SDK封装)
|
| | | void release();
|
| | | void init_load_model();
|
| | | bool add_cam(int cam_id);
|
| | | // void single_detect_tracking(int cam_id, cv::Mat frame, FRAME_RESULT result_vec); // 检测+追踪 接口
|
| | | void single_SDK(const int cam_id, const void *img, TResult *t_result, char* img_time, const char* mode);
|
| | | void single_SDK(const int cam_id, const void *img, TResult* t_result);
|
| | | // void mul_detect_tracking(std::vector<int> cam_ids, std::vector<cv::Mat> frame_vec, std::vector<FRAME_RESULT>& results_vec); // 多摄像头追踪
|
| | | };
|
| | |
|
| | | #endif //INC_01_CPP_SORT_TRACKER_MANAGER_H
|
| New file |
| | |
| | | //
|
| | | // Created by Scheaven on 2019/11/19.
|
| | | //
|
| | |
|
| | | #include "detecter_manager.h"
|
| | | #include <thread>
|
| | | #include <unistd.h>
|
| | | #include <cstdlib>
|
| | |
|
| | | DetecterManager* DetecterManager::instance = NULL;
|
| | |
|
| | | DetecterManager* DetecterManager::getInstance()
|
| | | {
|
| | | if(instance==NULL)
|
| | | {
|
| | | instance = new DetecterManager();
|
| | | }
|
| | | return instance;
|
| | | }
|
| | |
|
| | | DetecterManager::DetecterManager()
|
| | | {
|
| | | Config config;
|
| | | // config.net_type = COMMON;
|
| | | if(m_staticStruct::type==2)
|
| | | config.net_type = SMALL;
|
| | | else
|
| | | config.net_type = COMMON;
|
| | |
|
| | |
|
| | | this->detector = std::shared_ptr<Detector>(new Detector());
|
| | | this->detector->init(config);
|
| | | std::cout << "loading detector model......" << std::endl;
|
| | | }
|
| | |
|
| | |
|
| | | DetecterManager::~DetecterManager()
|
| | | {
|
| | | }
|
| | |
|
| | | void DetecterManager::release()
|
| | | {
|
| | | // Detector::getInstance()->release();
|
| | |
|
| | | delete DetecterManager::instance;
|
| | | DetecterManager::instance = NULL;
|
| | | }
|
| | |
|
| | | void DetecterManager::detecter_main(cv::Mat &mat_image, DETECTIONS& detection)
|
| | | {
|
| | | std::vector<BatchResult> batch_res;
|
| | | std::vector<cv::Mat> batch_img;
|
| | |
|
| | | batch_img.push_back(mat_image.clone());
|
| | | this->detector->detect(batch_img, batch_res);
|
| | | encoder_features(batch_res, detection);
|
| | |
|
| | | // show_result(result_vec);
|
| | | // draw_boxes(mat_image, result_vec);
|
| | | }
|
| | |
|
| | | void DetecterManager::encoder_features(std::vector<BatchResult> boxes, DETECTIONS &detection)
|
| | | {
|
| | | std::vector<float> confidences;
|
| | | std::vector<int> human_index;
|
| | |
|
| | | int result_index=0;
|
| | |
|
| | | for (const auto &result_box:boxes[0])
|
| | | {
|
| | | // #ifdef S_DEBUG
|
| | | // printf("--%d-%d-%d-%d-%d---result_box-----\n", result_box.obj_id, result_box.x, result_box.y, result_box.w, result_box.h);
|
| | | // #endif
|
| | | if(result_box.id == 1)
|
| | | {
|
| | | // cv::Rect box = cv::Rect(result_box.x,result_box.y,result_box.w,result_box.h);
|
| | | // get_detections(DETECTBOX(box.x, box.y,box.width, box.height), confidences[idx],d);
|
| | | DETECTION_ROW tmpRow;
|
| | | tmpRow.tlwh = DETECTBOX(result_box.rect.x,result_box.rect.y,result_box.rect.width,result_box.rect.height); //DETECTBOX(x, y, w, h);
|
| | | tmpRow.confidence = result_box.prob*100;
|
| | | tmpRow.obj_id = 0;
|
| | | tmpRow.is_hat = true;
|
| | | tmpRow.is_mask = true;
|
| | | tmpRow.is_smoke = true;
|
| | | tmpRow.hatScore = 0;
|
| | | tmpRow.maskScore = 0;
|
| | | tmpRow.smokeScore = 0;
|
| | | // tmpRow.img_time = this->img_time;
|
| | |
|
| | | tmpRow.isFall = false;
|
| | | tmpRow.fallScore = 0;
|
| | | tmpRow.runScore = 0;
|
| | | tmpRow.isRun = false;
|
| | |
|
| | | // tmpRow.human_face = nullptr;
|
| | |
|
| | | int sub_box_index=0;
|
| | | human_index.push_back(result_index);
|
| | |
|
| | | detection.push_back(tmpRow);
|
| | | }
|
| | | result_index++;
|
| | | }
|
| | | }
|
| | |
|
| | | // bool DetecterManager::sort_score(bbox_t box1, bbox_t box2)
|
| | | // {
|
| | | // return (box1.prob>box2.prob);
|
| | | // }
|
| | |
|
| | | // float DetecterManager::box_iou(bbox_t box1, bbox_t box2)
|
| | | // {
|
| | | // int x1 = std::max(box1.x, box2.x);
|
| | | // int y1 = std::max(box1.y, box2.y);
|
| | | // int x2 = std::min((box1.x+box1.w),(box2.x+box2.w));
|
| | | // int y2 = std::min((box1.y+box1.h),(box2.y+box2.h));
|
| | | // float over_area = (x2-x1)*(y2-y1);
|
| | | // // printf("over_ares---%f ----%d----%d\n", over_area, box1.w*box1.h, box2.w*box2.h);
|
| | | // float iou = over_area/((box1.w*box1.h<box2.w*box2.h)?box1.w*box1.h:box2.w*box2.h);
|
| | | // return iou;
|
| | | // }
|
| | |
|
| | | void DetecterManager::set_imgTime(long img_time)
|
| | | {
|
| | | this->img_time = img_time;
|
| | | }
|
| New file |
| | |
| | | //
|
| | | // Created by Scheaven on 2019/11/19.
|
| | | //
|
| | | #ifndef DETECTER_MANAGER_H
|
| | | #define DETECTER_MANAGER_H
|
| | | #include "../config.h"
|
| | | #include "../tracker_tools/model.h"
|
| | | #include "../utils/draw_util.h"
|
| | | // #include "../utils/config_util.h"
|
| | | #include "../utils/time_util.h"
|
| | | #include "../std_target.h"
|
| | | #include "detector.h"
|
| | |
|
| | | using namespace std;
|
| | |
|
| | | class DetecterManager {
|
| | | private:
|
| | | std::vector<cv::Rect> boxes;
|
| | | std::shared_ptr<Detector> detector;
|
| | |
|
| | | struct timeval sys_t1, sys_t2, diff1;
|
| | | // Detector detector("../cfg/yolov3.cfg", "../model_dump/yolov3.weights");
|
| | | // bool sort_score(bbox_t box1, bbox_t box2);
|
| | | // float box_iou(bbox_t box1, bbox_t box2);
|
| | |
|
| | |
|
| | | public:
|
| | | static DetecterManager* instance;
|
| | | static DetecterManager* getInstance();
|
| | | long img_time;
|
| | |
|
| | | public:
|
| | | DetecterManager();
|
| | | ~DetecterManager();
|
| | | void release();
|
| | | void detecter_main(cv::Mat &mat_image, DETECTIONS& detection);
|
| | | void ex_features(string in_path);
|
| | |
|
| | | public:
|
| | | void encoder_features(std::vector<BatchResult> boxes, DETECTIONS& detection);
|
| | | void set_imgTime(long img_time);
|
| | |
|
| | | };
|
| | |
|
| | |
|
| | | #endif //INC_04_S_MUTICAM_TRACKING_DETECTER_MANAGER_H
|
| | |
| | | |
| | | void Detector::build_net() |
| | | { |
| | | if(_config.net_type == COMMON) |
| | | _p_net = std::unique_ptr<Detecter>{new Detecter(_info,_infer_param,1)}; |
| | | else{ |
| | | if(_config.net_type == SMALL) |
| | | _p_net = std::unique_ptr<Detecter>{new Detecter(_info,_infer_param,2)}; |
| | | else{ |
| | | _p_net = std::unique_ptr<Detecter>{new Detecter(_info,_infer_param,1)}; |
| | | } |
| | | } |
| | |
| | | void Detecter::setOutput(int type) |
| | | { |
| | | m_OutputTensors.clear(); |
| | | printf("0-0-0-0-0-0------------------%d",type); |
| | | if(type==2) |
| | | for (int i = 0; i < 2; ++i) |
| | | { |
| | | |
| | | TensorInfo outputTensor; |
| | | outputTensor.numClasses = CLASS_BUM; |
| | | outputTensor.blobName = "yolo_" + std::to_string(i); |
| | |
| | | { |
| | | TensorInfo outputTensor; |
| | | outputTensor.numClasses = CLASS_BUM; |
| | | outputTensor.blobName = "yolo_" + to_string(i); |
| | | // if (i==0) |
| | | // { |
| | | // outputTensor.blobName = "139_convolutional_reshape_2"; |
| | | // }else if (i==1) |
| | | // { |
| | | // outputTensor.blobName = "150_convolutional_reshape_2"; |
| | | // }else if (i==2) |
| | | // { |
| | | // outputTensor.blobName = "161_convolutional_reshape_2"; |
| | | // } |
| | | outputTensor.blobName = "yolo_" + std::to_string(i); |
| | | outputTensor.gridSize = (m_InputH / 32) * pow(2, 2-i); |
| | | outputTensor.grid_h = (m_InputH / 32) * pow(2, 2-i); |
| | | outputTensor.grid_w = (m_InputW / 32) * pow(2, 2-i); |
| | |
| | | #include <stdint.h> |
| | | #include <string> |
| | | #include <vector> |
| | | #include "../utils/timer_utils.hpp" |
| | | #include "../utils/time_util.h" |
| | | #include "../config.h" |
| | | #include "opencv2/opencv.hpp" |
| | | |
| | |
| | |
|
| | | string m_staticStruct::model_path = "path";
|
| | | int m_staticStruct::type = 1;
|
| | | bool m_staticStruct::isTrack= true;
|
| | | int m_staticStruct::max_cam_num = 0;
|
| | | int m_staticStruct::wander_time = 0;
|
| | | float m_staticStruct::mv_velocity = 0;
|
| | | float m_staticStruct::fall_rate = 0;
|
| | |
|
| | | // 创建
|
| | |
|
| | | API void* create(const char *conf, int *max_chan)
|
| | | {
|
| | | // CLog::Initialize("/opt/vasystem/bin/models/baseDetector/log.properties");
|
| | | CLog::Initialize("../config/log4cplus.properties");
|
| | | ReadJsonFromFile(conf);
|
| | | AriManager *handle = new AriManager();
|
| | | *max_chan = m_staticStruct::max_cam_num;
|
| | | for (int i = 1; i <= m_staticStruct::max_cam_num; ++i)
|
| | | {
|
| | | handle->add_cam(i);
|
| | | }
|
| | | Timer::getInstance()->reset();
|
| | | return handle;
|
| | | }
|
| | |
|
| | | // 原查找结果接口
|
| | | API void* get_result(void *handle, const void *img, const int chan)
|
| | | {
|
| | | AriManager *h = (AriManager*)handle;
|
| | | TResult *t_result = (TResult*)malloc(sizeof(TResult));
|
| | | init_TResult(t_result);
|
| | | h->single_SDK(chan, img, *t_result);
|
| | |
|
| | | Timer::getInstance()->out("eveTime before yolo");
|
| | | // h->single_SDK(chan, img, *t_result);
|
| | | Timer::getInstance()->out("eveTime runing yolo");
|
| | | return t_result;
|
| | | }
|
| | |
|
| | |
|
| | | API void* get_result2(void *handle, const void *img, const int chan, const char* timestamp, const char* mode)
|
| | | {
|
| | | DEBUG("-----------------------begin------------ ");
|
| | | AriManager *h = (AriManager*)handle;
|
| | | TResult *t_result = (TResult*)malloc(sizeof(TResult));
|
| | | init_TResult(t_result);
|
| | |
|
| | | if(!m_staticStruct::isTrack)
|
| | | {
|
| | | Timer::getInstance()->out("get_result2 before yolo");
|
| | | h->single_SDK(chan, img, t_result);
|
| | | Timer::getInstance()->out("get_result2 runing yolo");
|
| | | return t_result;
|
| | | }
|
| | |
|
| | | h->single_SDK(chan, img, t_result, const_cast<char*>(timestamp), mode);
|
| | | DEBUG("--cam id:" + to_string(chan) + " image human_count:" + to_string(t_result->count));
|
| | | for (int i = 0; i < t_result->count; ++i)
|
| | | {
|
| | | if(mode == "video"){
|
| | | DEBUG("--human_id:" + to_string(t_result->targets[i].id)+" human_confidence:" + to_string(t_result->targets[i].confidence) + " human_attribute:" + std::string(t_result->targets[i].attribute) + " human_top:" + to_string(t_result->targets[i].rect.top)+" human_left:" + to_string(t_result->targets[i].rect.left) + " human_right:" + to_string(t_result->targets[i].rect.right)+ " human_bottom:" + to_string(t_result->targets[i].rect.bottom));
|
| | | }
|
| | | else{
|
| | | DEBUG("human_confidence:" + to_string(t_result->targets[i].confidence) + " human_top:" + to_string(t_result->targets[i].rect.top)+" human_left:" + to_string(t_result->targets[i].rect.left) + " human_right:" + to_string(t_result->targets[i].rect.right)+ " human_bottom:" + to_string(t_result->targets[i].rect.bottom));
|
| | | }
|
| | | }
|
| | | DEBUG("---------------------end over------------------------\n\n");
|
| | | return t_result;
|
| | | }
|
| | |
|
| | |
| | | h = NULL;
|
| | | }
|
| | |
|
| | | // 读取Json文件
|
| | | void ReadJsonFromFile(const char* filename)
|
| | | {
|
| | | Json::Reader reader;
|
| | |
| | | {
|
| | | std::string model_path = root["param"]["model_path"].asString();
|
| | | int type = root["param"]["type"].asInt();
|
| | | bool isTrack = root["param"]["isTrack"].asBool();
|
| | | int max_cam_num = root["param"]["max_cam_num"].asInt();
|
| | | int wander_time = root["param"]["wander_time"].asInt();
|
| | | int mv_velocity = root["param"]["mv_velocity"].asFloat();
|
| | | int fall_rate = root["param"]["fall_rate"].asFloat();
|
| | | m_staticStruct::model_path = model_path;
|
| | | m_staticStruct::type = type;
|
| | | m_staticStruct::isTrack = isTrack;
|
| | | m_staticStruct::max_cam_num = max_cam_num;
|
| | | m_staticStruct::wander_time = wander_time;
|
| | | m_staticStruct::mv_velocity = mv_velocity;
|
| | | m_staticStruct::fall_rate = fall_rate;
|
| | |
|
| | | }
|
| | | in.close();
|
| | | }
|
| | |
| | | t->count = 0;
|
| | | t->targets = nullptr;
|
| | | }
|
| | |
|
| | |
| | | #endif
|
| | |
|
| | | #define API extern "C" __attribute__((visibility ("default")))
|
| | |
|
| | | API void* create(const char *conf, int *max_chan);
|
| | | API void release(void* handle);
|
| | | API void* get_result(void *handle, const void *img, const int chan);
|
| | | API void* get_result2(void *handle, const void *img, const int chan,const char* timestamp, const char* mode);
|
| | | API void release_result(void *res);
|
| | |
|
| | | void ReadJsonFromFile(const char* filename); // 读取json文件
|
| | | void ReadJsonFromFile(const char* filename);
|
| | | int setCamConfig(const char* data);
|
| | | int ReadJsonStr(void* handle, const char* data);
|
| | |
|
| New file |
| | |
| | | #pragma once
|
| | | #ifndef DATATYPE_H
|
| | | #define DATATYPEH
|
| | |
|
| | | #include <cstddef>
|
| | | #include <vector>
|
| | |
|
| | | #include <Eigen/Core>
|
| | | #include <Eigen/Dense>
|
| | |
|
| | | #define FEATURE_DIM 128 // 特征抽取的維度
|
| | | typedef unsigned char uint8;
|
| | |
|
| | | typedef Eigen::Matrix<float, 1, 4, Eigen::RowMajor> DETECTBOX;
|
| | | typedef Eigen::Matrix<float, -1, 4, Eigen::RowMajor> DETECTBOXSS;
|
| | | typedef Eigen::Matrix<float, 1, 128, Eigen::RowMajor> FEATURE;
|
| | | typedef Eigen::Matrix<float, Eigen::Dynamic, 128, Eigen::RowMajor> FEATURESS;
|
| | | //typedef std::vector<FEATURE> FEATURESS;
|
| | |
|
| | | //Kalmanfilter
|
| | | //typedef Eigen::Matrix<float, 8, 8, Eigen::RowMajor> KAL_FILTER;
|
| | | typedef Eigen::Matrix<float, 1, 8, Eigen::RowMajor> KAL_MEAN;
|
| | | typedef Eigen::Matrix<float, 8, 8, Eigen::RowMajor> KAL_COVA;
|
| | | typedef Eigen::Matrix<float, 1, 4, Eigen::RowMajor> KAL_HMEAN;
|
| | | typedef Eigen::Matrix<float, 4, 4, Eigen::RowMajor> KAL_HCOVA;
|
| | | using KAL_DATA = std::pair<KAL_MEAN, KAL_COVA>;
|
| | | using KAL_HDATA = std::pair<KAL_HMEAN, KAL_HCOVA>;
|
| | |
|
| | | //main
|
| | | using RESULT_DATA = std::pair<int, DETECTBOX>;
|
| | |
|
| | | //tracker:
|
| | | using TRACKER_DATA = std::pair<uint64_t, FEATURESS>;
|
| | | using MATCH_DATA = std::pair<int, int>;
|
| | | typedef struct t{
|
| | | std::vector<MATCH_DATA> matches;
|
| | | std::vector<int> unmatched_tracks;
|
| | | std::vector<int> unmatched_detections;
|
| | | }TRACHER_MATCHD;
|
| | |
|
| | | //linear_assignment:
|
| | | typedef Eigen::Matrix<float, -1, -1, Eigen::RowMajor> DYNAMICM;
|
| | |
|
| | |
|
| | | #endif // DATATYPE_H
|
| New file |
| | |
| | | //
|
| | | // Created by Scheaven on 2020/9/3.
|
| | | //
|
| | | #include "feature_util.h"
|
| | |
|
| | | double feature_distance(FEATURE feat1, FEATURE feat2)
|
| | | {
|
| | | double FeatA=0.0, FeatB=0.0, score=0.0;
|
| | | for (int i = 0; i < 128; i++)
|
| | | {
|
| | | FeatA += double(feat1[i])*double(feat1[i]);
|
| | | FeatB += double(feat2[i])*double(feat2[i]);
|
| | | score += double(feat1[i])*double(feat2[i]);
|
| | | }
|
| | |
|
| | |
|
| | |
|
| | | FeatA = sqrt(FeatA);
|
| | | FeatB = sqrt(FeatB);
|
| | |
|
| | | score = score / (FeatA * FeatB);
|
| | |
|
| | | if (score < 0) {
|
| | | score = 0;
|
| | | }
|
| | | printf("--评分---%f--",score);
|
| | | return score;
|
| | | }
|
| New file |
| | |
| | | //
|
| | | // Created by Scheaven on 2020/9/3.
|
| | | //
|
| | |
|
| | | #ifndef FEATURE_UTIL_H
|
| | | #define FEATURE_UTIL_H
|
| | |
|
| | | #include "dataType.h"
|
| | | #include "../config.h"
|
| | |
|
| | | double feature_distance(FEATURE feat1, FEATURE feat2);
|
| | |
|
| | |
|
| | | #endif //FEATURE_UTIL_H
|
| New file |
| | |
| | | #include "kalmfilter.h"
|
| | | #include <Eigen/Cholesky>
|
| | |
|
| | | const double KalmFilter::chi2inv95[10] = {
|
| | | 0,
|
| | | 3.8415,
|
| | | 5.9915,
|
| | | 7.8147,
|
| | | 9.4877,
|
| | | 11.070,
|
| | | 12.592,
|
| | | 14.067,
|
| | | 15.507,
|
| | | 16.919
|
| | | };
|
| | | KalmFilter::KalmFilter()
|
| | | {
|
| | | int ndim = 4;
|
| | | double dt = 1.;
|
| | |
|
| | | _motion_mat = Eigen::MatrixXf::Identity(8, 8);
|
| | | for(int i = 0; i < ndim; i++) {
|
| | | _motion_mat(i, ndim+i) = dt;
|
| | | }
|
| | | _update_mat = Eigen::MatrixXf::Identity(4, 8);
|
| | |
|
| | | this->_std_weight_position = 1. / 20;
|
| | | this->_std_weight_velocity = 1. / 160;
|
| | | }
|
| | |
|
| | | KalmFilter::~KalmFilter()
|
| | | {
|
| | |
|
| | | }
|
| | |
|
| | | KAL_DATA KalmFilter::initiate(const DETECTBOX &measurement)
|
| | | {
|
| | | DETECTBOX mean_pos = measurement;
|
| | | DETECTBOX mean_vel;
|
| | | for(int i = 0; i < 4; i++) mean_vel(i) = 0;
|
| | |
|
| | | KAL_MEAN mean;
|
| | | for(int i = 0; i < 8; i++){
|
| | | if(i < 4) mean(i) = mean_pos(i);
|
| | | else mean(i) = mean_vel(i - 4);
|
| | | }
|
| | |
|
| | | KAL_MEAN std;
|
| | | std(0) = 2 * _std_weight_position * measurement[3];
|
| | | std(1) = 2 * _std_weight_position * measurement[3];
|
| | | std(2) = 1e-2;
|
| | | std(3) = 2 * _std_weight_position * measurement[3];
|
| | | std(4) = 10 * _std_weight_velocity * measurement[3];
|
| | | std(5) = 10 * _std_weight_velocity * measurement[3];
|
| | | std(6) = 1e-5;
|
| | | std(7) = 10 * _std_weight_velocity * measurement[3];
|
| | |
|
| | | KAL_MEAN tmp = std.array().square();
|
| | | KAL_COVA var = tmp.asDiagonal();
|
| | | return std::make_pair(mean, var);
|
| | | }
|
| | |
|
| | | void KalmFilter::predict(KAL_MEAN &mean, KAL_COVA &covariance)
|
| | | {
|
| | | //revise the data;
|
| | | DETECTBOX std_pos;
|
| | | std_pos << _std_weight_position * mean(3),
|
| | | _std_weight_position * mean(3),
|
| | | 1e-2,
|
| | | _std_weight_position * mean(3);
|
| | | DETECTBOX std_vel;
|
| | | std_vel << _std_weight_velocity * mean(3),
|
| | | _std_weight_velocity * mean(3),
|
| | | 1e-5,
|
| | | _std_weight_velocity * mean(3);
|
| | | KAL_MEAN tmp;
|
| | | tmp.block<1,4>(0,0) = std_pos;
|
| | | tmp.block<1,4>(0,4) = std_vel;
|
| | | tmp = tmp.array().square();
|
| | | KAL_COVA motion_cov = tmp.asDiagonal();
|
| | | KAL_MEAN mean1 = this->_motion_mat * mean.transpose();
|
| | | KAL_COVA covariance1 = this->_motion_mat * covariance *(_motion_mat.transpose());
|
| | | covariance1 += motion_cov;
|
| | |
|
| | | mean = mean1;
|
| | | covariance = covariance1;
|
| | | }
|
| | |
|
| | | KAL_HDATA KalmFilter::project(const KAL_MEAN &mean, const KAL_COVA &covariance)
|
| | | {
|
| | | DETECTBOX std;
|
| | | std << _std_weight_position * mean(3), _std_weight_position * mean(3),
|
| | | 1e-1, _std_weight_position * mean(3);
|
| | | KAL_HMEAN mean1 = _update_mat * mean.transpose();
|
| | | KAL_HCOVA covariance1 = _update_mat * covariance * (_update_mat.transpose());
|
| | | Eigen::Matrix<float, 4, 4> diag = std.asDiagonal();
|
| | | diag = diag.array().square().matrix();
|
| | | covariance1 += diag;
|
| | | // covariance1.diagonal() << diag;
|
| | | return std::make_pair(mean1, covariance1);
|
| | | }
|
| | |
|
| | | KAL_DATA
|
| | | KalmFilter::update(
|
| | | const KAL_MEAN &mean,
|
| | | const KAL_COVA &covariance,
|
| | | const DETECTBOX &measurement)
|
| | | {
|
| | | KAL_HDATA pa = project(mean, covariance);
|
| | | KAL_HMEAN projected_mean = pa.first;
|
| | | KAL_HCOVA projected_cov = pa.second;
|
| | |
|
| | | //chol_factor, lower =
|
| | | //scipy.linalg.cho_factor(projected_cov, lower=True, check_finite=False)
|
| | | //kalmain_gain =
|
| | | //scipy.linalg.cho_solve((cho_factor, lower),
|
| | | //np.dot(covariance, self._upadte_mat.T).T,
|
| | | //check_finite=False).T
|
| | | Eigen::Matrix<float, 4, 8> B = (covariance * (_update_mat.transpose())).transpose();
|
| | | Eigen::Matrix<float, 8, 4> kalman_gain = (projected_cov.llt().solve(B)).transpose(); // eg.8x4
|
| | | Eigen::Matrix<float, 1, 4> innovation = measurement - projected_mean; //eg.1x4
|
| | | auto tmp = innovation*(kalman_gain.transpose());
|
| | | KAL_MEAN new_mean = (mean.array() + tmp.array()).matrix();
|
| | | KAL_COVA new_covariance = covariance - kalman_gain*projected_cov*(kalman_gain.transpose());
|
| | | return std::make_pair(new_mean, new_covariance);
|
| | | }
|
| | |
|
| | | Eigen::Matrix<float, 1, -1>
|
| | | KalmFilter::gating_distance(
|
| | | const KAL_MEAN &mean,
|
| | | const KAL_COVA &covariance,
|
| | | const std::vector<DETECTBOX> &measurements,
|
| | | bool only_position)
|
| | | {
|
| | | KAL_HDATA pa = this->project(mean, covariance);
|
| | | // if(only_position) {
|
| | | // printf("not implement!");
|
| | | // exit(0);
|
| | | // }
|
| | | KAL_HMEAN mean1 = pa.first;
|
| | | KAL_HCOVA covariance1 = pa.second;
|
| | |
|
| | | // Eigen::Matrix<float, -1, 4, Eigen::RowMajor> d(size, 4);
|
| | | DETECTBOXSS d(measurements.size(), 4);
|
| | | int pos = 0;
|
| | | for(DETECTBOX box:measurements) {
|
| | | d.row(pos++) = box - mean1;
|
| | | }
|
| | | Eigen::Matrix<float, -1, -1, Eigen::RowMajor> factor = covariance1.llt().matrixL();
|
| | | Eigen::Matrix<float, -1, -1> z = factor.triangularView<Eigen::Lower>().solve<Eigen::OnTheRight>(d).transpose();
|
| | | auto zz = ((z.array())*(z.array())).matrix();
|
| | | auto square_maha = zz.colwise().sum();
|
| | | return square_maha;
|
| | | }
|
| | |
|
| New file |
| | |
| | | #ifndef KALMFILTER_H
|
| | | #define KALMFILTER_H
|
| | |
|
| | | #include "dataType.h"
|
| | |
|
| | | class KalmFilter
|
| | | {
|
| | | public:
|
| | | static const double chi2inv95[10];
|
| | | KalmFilter();
|
| | | ~KalmFilter();
|
| | | KAL_DATA initiate(const DETECTBOX& measurement);
|
| | | void predict(KAL_MEAN& mean, KAL_COVA& covariance);
|
| | | KAL_HDATA project(const KAL_MEAN& mean, const KAL_COVA& covariance);
|
| | | KAL_DATA update(const KAL_MEAN& mean,
|
| | | const KAL_COVA& covariance,
|
| | | const DETECTBOX& measurement);
|
| | |
|
| | | Eigen::Matrix<float, 1, -1> gating_distance(
|
| | | const KAL_MEAN& mean,
|
| | | const KAL_COVA& covariance,
|
| | | const std::vector<DETECTBOX>& measurements,
|
| | | bool only_position = false);
|
| | |
|
| | | private:
|
| | | Eigen::Matrix<float, 8, 8, Eigen::RowMajor> _motion_mat;
|
| | | Eigen::Matrix<float, 4, 8, Eigen::RowMajor> _update_mat;
|
| | | float _std_weight_position;
|
| | | float _std_weight_velocity;
|
| | | };
|
| | |
|
| | | #endif // KALMFILTER_H
|
| New file |
| | |
| | | #include "linear_assignment.h"
|
| | | #include "../Munkres_assign/hungarianoper.h"
|
| | | #include <map>
|
| | |
|
| | | linear_assignment *linear_assignment::instance = NULL;
|
| | | linear_assignment::linear_assignment()
|
| | | {
|
| | | }
|
| | |
|
| | | linear_assignment *linear_assignment::getInstance()
|
| | | {
|
| | | if(instance == NULL) instance = new linear_assignment();
|
| | | return instance;
|
| | | }
|
| | |
|
| | | linear_assignment::~linear_assignment()
|
| | | {
|
| | | delete instance;
|
| | | }
|
| | |
|
| | | TRACHER_MATCHD
|
| | | linear_assignment::matching_cascade(
|
| | | tracker *distance_metric,
|
| | | tracker::GATED_METRIC_FUNC distance_metric_func,
|
| | | float max_distance,
|
| | | int cascade_depth,
|
| | | std::vector<std::shared_ptr<Track>> &tracks,
|
| | | const DETECTIONS &detections,
|
| | | std::vector<int>& track_indices,
|
| | | std::vector<int> detection_indices)
|
| | | {
|
| | | TRACHER_MATCHD res;
|
| | | for(size_t i = 0; i < detections.size(); i++) {
|
| | | detection_indices.push_back(int(i));
|
| | | }
|
| | |
|
| | | std::vector<int> unmatched_detections;
|
| | | unmatched_detections.assign(detection_indices.begin(), detection_indices.end());
|
| | | res.matches.clear();
|
| | | std::vector<int> track_indices_l;
|
| | |
|
| | | std::map<int, int> matches_trackid;
|
| | | for(int level = 0; level < cascade_depth; level++) {
|
| | | if(unmatched_detections.size() == 0) break; //No detections left;
|
| | |
|
| | | track_indices_l.clear();
|
| | | for(int k:track_indices) {
|
| | | if(tracks[k]->time_since_update == 1+level)
|
| | | track_indices_l.push_back(k);
|
| | | }
|
| | | if(track_indices_l.size() == 0) continue; //Nothing to match at this level.
|
| | |
|
| | | TRACHER_MATCHD tmp = min_cost_matching(
|
| | | distance_metric, distance_metric_func,
|
| | | max_distance, tracks, detections, track_indices_l,
|
| | | unmatched_detections);
|
| | | unmatched_detections.assign(tmp.unmatched_detections.begin(), tmp.unmatched_detections.end());
|
| | | for(size_t i = 0; i < tmp.matches.size(); i++) {
|
| | | MATCH_DATA pa = tmp.matches[i];
|
| | | res.matches.push_back(pa);
|
| | | matches_trackid.insert(pa);
|
| | | }
|
| | | }
|
| | | res.unmatched_detections.assign(unmatched_detections.begin(), unmatched_detections.end());
|
| | |
|
| | | for(size_t i = 0; i < track_indices.size(); i++) {
|
| | | int tid = track_indices[i];
|
| | | if(matches_trackid.find(tid) == matches_trackid.end())
|
| | | res.unmatched_tracks.push_back(tid); // 未匹配的追加
|
| | | }
|
| | |
|
| | | return res;
|
| | | }
|
| | |
|
| | | TRACHER_MATCHD
|
| | | linear_assignment::min_cost_matching(tracker *distance_metric,
|
| | | tracker::GATED_METRIC_FUNC distance_metric_func,
|
| | | float max_distance,
|
| | | std::vector<std::shared_ptr<Track>> &tracks,
|
| | | const DETECTIONS &detections,
|
| | | std::vector<int> &track_indices,
|
| | | std::vector<int> &detection_indices)
|
| | | {
|
| | | TRACHER_MATCHD res;
|
| | | if((detection_indices.size() == 0) || (track_indices.size() == 0)) {
|
| | | res.matches.clear();
|
| | | res.unmatched_tracks.assign(track_indices.begin(), track_indices.end());
|
| | | res.unmatched_detections.assign(detection_indices.begin(), detection_indices.end());
|
| | | return res;
|
| | | }
|
| | | DYNAMICM cost_matrix = (distance_metric->*(distance_metric_func))( // distance_metric_func其实是调用tracker.cpp中的iou_cost 函数
|
| | | tracks, detections, track_indices, detection_indices);
|
| | | for(int i = 0; i < cost_matrix.rows(); i++) {
|
| | | for(int j = 0; j < cost_matrix.cols(); j++) {
|
| | | float tmp = cost_matrix(i,j);
|
| | | if(tmp > max_distance) cost_matrix(i,j) = max_distance + 1e-5;
|
| | | }
|
| | | }
|
| | | Eigen::Matrix<float, -1, 2, Eigen::RowMajor> indices = HungarianOper::Solve(cost_matrix);
|
| | | res.matches.clear();
|
| | | res.unmatched_tracks.clear();
|
| | | res.unmatched_detections.clear();
|
| | | for(size_t col = 0; col < detection_indices.size(); col++) {
|
| | | bool flag = false;
|
| | | for(int i = 0; i < indices.rows(); i++)
|
| | | if(indices(i, 1) == col) { flag = true; break;}
|
| | | if(flag == false)res.unmatched_detections.push_back(detection_indices[col]);
|
| | | }
|
| | | for(size_t row = 0; row < track_indices.size(); row++) {
|
| | | bool flag = false;
|
| | | for(int i = 0; i < indices.rows(); i++)
|
| | | if(indices(i, 0) == row) { flag = true; break; }
|
| | | if(flag == false) res.unmatched_tracks.push_back(track_indices[row]);
|
| | | }
|
| | | for(int i = 0; i < indices.rows(); i++) {
|
| | | int row = indices(i, 0);
|
| | | int col = indices(i, 1);
|
| | |
|
| | | int track_idx = track_indices[row];
|
| | | int detection_idx = detection_indices[col];
|
| | | if(cost_matrix(row, col) > max_distance) {
|
| | | res.unmatched_tracks.push_back(track_idx);
|
| | | res.unmatched_detections.push_back(detection_idx);
|
| | | } else res.matches.push_back(std::make_pair(track_idx, detection_idx));
|
| | | }
|
| | | return res;
|
| | | }
|
| | |
|
| | | DYNAMICM
|
| | | linear_assignment::gate_cost_matrix(
|
| | | KalmFilter *kf,
|
| | | DYNAMICM &cost_matrix,
|
| | | std::vector<std::shared_ptr<Track>> &tracks,
|
| | | const DETECTIONS &detections,
|
| | | const std::vector<int> &track_indices,
|
| | | const std::vector<int> &detection_indices,
|
| | | float gated_cost, bool only_position)
|
| | | {
|
| | | int gating_dim = (only_position == true?2:4);
|
| | | double gating_threshold = KalmFilter::chi2inv95[gating_dim];
|
| | | std::vector<DETECTBOX> measurements;
|
| | | for(int i:detection_indices)
|
| | | {
|
| | | DETECTION_ROW t = detections[i];
|
| | | measurements.push_back(t.to_xyah());
|
| | | }
|
| | |
|
| | | for(size_t i = 0; i < track_indices.size(); i++)
|
| | | {
|
| | | auto& track = tracks[track_indices[i]];
|
| | | Eigen::Matrix<float, 1, -1> gating_distance = kf->gating_distance(
|
| | | track->mean, track->covariance, measurements, only_position);
|
| | |
|
| | | for (int j = 0; j < gating_distance.cols(); j++)
|
| | | {
|
| | | if (gating_distance(0, j) > gating_threshold) cost_matrix(i, j) = gated_cost;
|
| | | }
|
| | | }
|
| | | return cost_matrix;
|
| | | }
|
| | |
|
| New file |
| | |
| | | #ifndef LINEAR_ASSIGNMENT_H
|
| | | #define LINEAR_ASSIGNMENT_H
|
| | | #include "dataType.h"
|
| | | #include "tracker.h"
|
| | |
|
| | | #define INFTY_COST 1e5
|
| | | class tracker;
|
| | | //for matching;
|
| | | class linear_assignment
|
| | | {
|
| | | linear_assignment();
|
| | | linear_assignment(const linear_assignment& );
|
| | | linear_assignment& operator=(const linear_assignment&);
|
| | | static linear_assignment* instance;
|
| | |
|
| | | public:
|
| | | static linear_assignment* getInstance();
|
| | | ~linear_assignment();
|
| | |
|
| | | TRACHER_MATCHD matching_cascade(tracker* distance_metric,
|
| | | tracker::GATED_METRIC_FUNC distance_metric_func,
|
| | | float max_distance,
|
| | | int cascade_depth,
|
| | | std::vector<std::shared_ptr<Track>>& tracks,
|
| | | const DETECTIONS& detections,
|
| | | std::vector<int> &track_indices,
|
| | | std::vector<int> detection_indices = std::vector<int>());
|
| | | TRACHER_MATCHD min_cost_matching(
|
| | | tracker* distance_metric,
|
| | | tracker::GATED_METRIC_FUNC distance_metric_func,
|
| | | float max_distance,
|
| | | std::vector<std::shared_ptr<Track>>& tracks,
|
| | | const DETECTIONS& detections,
|
| | | std::vector<int>& track_indices,
|
| | | std::vector<int>& detection_indices);
|
| | | DYNAMICM gate_cost_matrix(
|
| | | KalmFilter* kf,
|
| | | DYNAMICM& cost_matrix,
|
| | | std::vector<std::shared_ptr<Track>>& tracks,
|
| | | const DETECTIONS& detections,
|
| | | const std::vector<int>& track_indices,
|
| | | const std::vector<int>& detection_indices,
|
| | | float gated_cost = INFTY_COST,
|
| | | bool only_position = true);
|
| | | };
|
| | |
|
| | | #endif // LINEAR_ASSIGNMENT_H
|
| New file |
| | |
| | | #include "model.h"
|
| | |
|
| | |
|
| | | const float kRatio=0.5;
|
| | | enum DETECTBOX_IDX {IDX_X = 0, IDX_Y, IDX_W, IDX_H };
|
| | |
|
| | | DETECTBOX DETECTION_ROW::to_xyah() const
|
| | | {//(centerx, centery, ration, h)
|
| | | DETECTBOX ret = tlwh;
|
| | | ret(0,IDX_X) += (ret(0, IDX_W)*kRatio);
|
| | | ret(0, IDX_Y) += (ret(0, IDX_H)*kRatio);
|
| | | ret(0, IDX_W) /= ret(0, IDX_H);
|
| | | return ret;
|
| | | }
|
| | |
|
| | | DETECTBOX DETECTION_ROW::to_tlbr() const
|
| | | {//(x,y,xx,yy)
|
| | | DETECTBOX ret = tlwh;
|
| | | ret(0, IDX_X) += ret(0, IDX_W);
|
| | | ret(0, IDX_Y) += ret(0, IDX_H);
|
| | | return ret;
|
| | | }
|
| | |
|
| New file |
| | |
| | | #ifndef MODEL_H
|
| | | #define MODEL_H
|
| | | #include "dataType.h"
|
| | | #include <algorithm>
|
| | | #include "../config.h"
|
| | |
|
| | | // * Each rect's data structure.
|
| | | // * tlwh: topleft point & (w,h).
|
| | | // * confidence: detection confidence.
|
| | | // * feature: the rect's 128d feature.
|
| | | // */
|
| | | class DETECTION_ROW
|
| | | {
|
| | | public:
|
| | | int obj_id;
|
| | | DETECTBOX tlwh;
|
| | | float confidence;
|
| | | FEATURE feature;
|
| | | DETECTBOX to_xyah() const;
|
| | | DETECTBOX to_tlbr() const;
|
| | |
|
| | | bool isFall;
|
| | | int fallScore;
|
| | |
|
| | | bool isRun;
|
| | | int runScore;
|
| | |
|
| | | bool is_hat;
|
| | | int hatScore;
|
| | |
|
| | | int helmetScore;
|
| | |
|
| | | int headScore;
|
| | |
|
| | | bool is_mask;
|
| | | int maskScore;
|
| | |
|
| | | bool is_smoke;
|
| | | int smokeScore;
|
| | |
|
| | | };
|
| | |
|
| | | typedef std::vector<DETECTION_ROW> DETECTIONS;
|
| | |
|
| | |
|
| | | #endif // MODEL_H
|
| New file |
| | |
| | | #include "nn_matching.h"
|
| | |
|
| | |
|
| | | using namespace Eigen;
|
| | |
|
| | | NearNeighborDisMetric::NearNeighborDisMetric(
|
| | | NearNeighborDisMetric::METRIC_TYPE metric,
|
| | | float matching_threshold, int budget)
|
| | | {
|
| | | if(metric == euclidean)
|
| | | {
|
| | | _metric = &NearNeighborDisMetric::_nneuclidean_distance;
|
| | | } else if (metric == cosine)
|
| | | {
|
| | | _metric = &NearNeighborDisMetric::_nncosine_distance;
|
| | | }
|
| | |
|
| | | this->mating_threshold = matching_threshold;
|
| | | this->budget = budget;
|
| | | this->samples.clear();
|
| | | }
|
| | |
|
| | | NearNeighborDisMetric::~NearNeighborDisMetric()
|
| | | {
|
| | |
|
| | | }
|
| | |
|
| | | DYNAMICM
|
| | | NearNeighborDisMetric::distance(
|
| | | const FEATURESS &features,
|
| | | const std::vector<uint64_t>& targets)
|
| | | {
|
| | | DYNAMICM cost_matrix = Eigen::MatrixXf::Zero(targets.size(), features.rows());
|
| | | int idx = 0;
|
| | | for(uint64_t target:targets) {
|
| | | cost_matrix.row(idx) = (this->*_metric)(this->samples[target], features);
|
| | | idx++;
|
| | | }
|
| | | return cost_matrix;
|
| | | }
|
| | |
|
| | | DYNAMICM
|
| | | NearNeighborDisMetric::cos_distance(const FEATURESS &features, std::map<uint64_t, FEATURESS> cos_samples)
|
| | | {
|
| | | DYNAMICM cost_matrix = Eigen::MatrixXf::Zero(cos_samples.size(), features.rows());
|
| | | int idx = 0;
|
| | | std::map<uint64_t, FEATURESS>::iterator iter;
|
| | | for (iter=cos_samples.begin(); iter!= cos_samples.end(); iter++)
|
| | | {
|
| | | cost_matrix.row(idx) = (this->*_metric)(iter->second, features);
|
| | | idx++;
|
| | | }
|
| | |
|
| | | return cost_matrix;
|
| | | }
|
| | |
|
| | | void
|
| | | NearNeighborDisMetric::partial_fit(
|
| | | std::vector<TRACKER_DATA> &tid_feats,
|
| | | std::vector<uint64_t> &active_targets)
|
| | | {
|
| | | /*python code:
|
| | | * let feature(target_id) append to samples;
|
| | | * && delete not comfirmed target_id from samples.
|
| | | * update samples;
|
| | | */
|
| | | for(TRACKER_DATA& data:tid_feats) {
|
| | | uint64_t track_id = data.first;
|
| | | FEATURESS newFeatOne = data.second;
|
| | |
|
| | | if(samples.find(track_id) != samples.end()) {//append
|
| | | int oldSize = samples[track_id].rows();
|
| | | int addSize = newFeatOne.rows();
|
| | | int newSize = oldSize + addSize;
|
| | |
|
| | | if(newSize <= this->budget) {
|
| | | FEATURESS newSampleFeatures(newSize, 128);
|
| | | newSampleFeatures.block(0,0, oldSize, 128) = samples[track_id];
|
| | | newSampleFeatures.block(oldSize, 0, addSize, 128) = newFeatOne;
|
| | | samples[track_id] = newSampleFeatures;
|
| | | } else {
|
| | | if(oldSize < this->budget) { //original space is not enough;
|
| | | FEATURESS newSampleFeatures(this->budget, 128);
|
| | | if(addSize >= this->budget) {
|
| | | newSampleFeatures = newFeatOne.block(0, 0, this->budget, 128);
|
| | | } else {
|
| | | newSampleFeatures.block(0, 0, this->budget-addSize, 128) =
|
| | | samples[track_id].block(addSize-1, 0, this->budget-addSize, 128).eval();
|
| | | newSampleFeatures.block(this->budget-addSize, 0, addSize, 128) = newFeatOne;
|
| | | }
|
| | | samples[track_id] = newSampleFeatures;
|
| | | } else {//original space is ok;
|
| | | if(addSize >= this->budget) {
|
| | | samples[track_id] = newFeatOne.block(0,0, this->budget, 128);
|
| | | } else {
|
| | | samples[track_id].block(0, 0, this->budget-addSize, 128) =
|
| | | samples[track_id].block(addSize-1, 0, this->budget-addSize, 128).eval();
|
| | | samples[track_id].block(this->budget-addSize, 0, addSize, 128) = newFeatOne;
|
| | | }
|
| | | }
|
| | | }
|
| | | } else {//not exit, create new one;
|
| | | samples[track_id] = newFeatOne;
|
| | | }
|
| | | }//add features;
|
| | |
|
| | | //erase the samples which not in active_targets;
|
| | | for(std::map<uint64_t, FEATURESS>::iterator i = samples.begin(); i != samples.end();) {
|
| | | bool flag = false;
|
| | | for(uint64_t j:active_targets) if(j == i->first) { flag=true; break; }
|
| | | if(flag == false) samples.erase(i++);
|
| | | else i++;
|
| | | }
|
| | | }
|
| | |
|
| | | Eigen::VectorXf
|
| | | NearNeighborDisMetric::_nncosine_distance(
|
| | | const FEATURESS &x, const FEATURESS &y)
|
| | | {
|
| | | MatrixXf distances = _cosine_distance(x,y);
|
| | | VectorXf res = distances.colwise().minCoeff().transpose();
|
| | | return res;
|
| | | }
|
| | |
|
| | | Eigen::VectorXf
|
| | | NearNeighborDisMetric::_nneuclidean_distance(
|
| | | const FEATURESS &x, const FEATURESS &y)
|
| | | {
|
| | | MatrixXf distances = _pdist(x,y);
|
| | | VectorXf res = distances.colwise().maxCoeff().transpose();
|
| | | res = res.array().max(VectorXf::Zero(res.rows()).array());
|
| | | return res;
|
| | | }
|
| | |
|
| | | Eigen::MatrixXf
|
| | | NearNeighborDisMetric::_pdist(const FEATURESS &x, const FEATURESS &y)
|
| | | {
|
| | | int len1 = x.rows(), len2 = y.rows();
|
| | | if(len1 == 0 || len2 == 0) {
|
| | | return Eigen::MatrixXf::Zero(len1, len2);
|
| | | }
|
| | | MatrixXf res = x * y.transpose()* -2;
|
| | | res = res.colwise() + x.rowwise().squaredNorm();
|
| | | res = res.rowwise() + y.rowwise().squaredNorm().transpose();
|
| | | res = res.array().max(MatrixXf::Zero(res.rows(), res.cols()).array());
|
| | | return res;
|
| | | }
|
| | |
|
| | | Eigen::MatrixXf
|
| | | NearNeighborDisMetric::_cosine_distance(
|
| | | const FEATURESS & a,
|
| | | const FEATURESS& b, bool data_is_normalized) {
|
| | | if(data_is_normalized == true) {
|
| | | //undo:
|
| | | assert(false);
|
| | | }
|
| | | MatrixXf res = 1. - (a*b.transpose()).array();
|
| | | return res;
|
| | | }
|
| New file |
| | |
| | | #ifndef NN_MATCHING_H
|
| | | #define NN_MATCHING_H
|
| | |
|
| | | #include "dataType.h"
|
| | |
|
| | | #include <map>
|
| | |
|
| | | //A tool to calculate distance;
|
| | | class NearNeighborDisMetric{
|
| | | public:
|
| | | enum METRIC_TYPE{euclidean=1, cosine};
|
| | | NearNeighborDisMetric(METRIC_TYPE metric,
|
| | | float matching_threshold,
|
| | | int budget);
|
| | | ~NearNeighborDisMetric();
|
| | | DYNAMICM distance(const FEATURESS& features, const std::vector<uint64_t> &targets);
|
| | | DYNAMICM cos_distance(const FEATURESS& features, std::map<uint64_t, FEATURESS> cos_samples);
|
| | | // void partial_fit(FEATURESS& features, std::vector<int> targets, std::vector<int> active_targets);
|
| | | void partial_fit(std::vector<TRACKER_DATA>& tid_feats, std::vector<uint64_t>& active_targets);
|
| | | float mating_threshold;
|
| | |
|
| | | private:
|
| | | typedef Eigen::VectorXf (NearNeighborDisMetric::*PTRFUN)(const FEATURESS&, const FEATURESS&);
|
| | | Eigen::VectorXf _nncosine_distance(const FEATURESS& x, const FEATURESS& y);
|
| | | Eigen::VectorXf _nneuclidean_distance(const FEATURESS& x, const FEATURESS& y);
|
| | |
|
| | | Eigen::MatrixXf _pdist(const FEATURESS& x, const FEATURESS& y);
|
| | | Eigen::MatrixXf _cosine_distance(const FEATURESS & a, const FEATURESS& b, bool data_is_normalized = false);
|
| | | private:
|
| | | PTRFUN _metric;
|
| | | int budget;
|
| | | std::map<uint64_t, FEATURESS > samples;
|
| | | };
|
| | |
|
| | | #endif // NN_MATCHING_H
|
| New file |
| | |
| | | #include "track.h"
|
| | | Track::Track()
|
| | | {
|
| | |
|
| | | }
|
| | | Track::~Track()
|
| | | {
|
| | |
|
| | | }
|
| | | Track::Track(KAL_MEAN& mean, KAL_COVA& covariance, uint64_t track_id, int n_init, int max_age, const FEATURE& feature,char* img_time)
|
| | | {
|
| | | this->mean = mean;
|
| | | this->covariance = covariance;
|
| | | this->track_id = track_id;
|
| | | this->hits = 1;
|
| | | this->age = 1;
|
| | | this->time_since_update = 0;
|
| | | this->state = TrackState::Tentative;
|
| | | features = FEATURESS(1, 128);
|
| | | features.row(0) = feature;//features.rows() must = 0;
|
| | |
|
| | | this->_n_init = n_init;
|
| | | this->_max_age = max_age;
|
| | | this->init_t = true;
|
| | | this->isCurrent = true;
|
| | |
|
| | | //初始化徘徊参数
|
| | | this->last_time = 0;
|
| | | // gettimeofday(&this->last_s_time,0); // 徘徊计时开启
|
| | | this->last_s_time = char_2_unix(img_time);
|
| | | std::cout<< "==track img time=%s:" << img_time << std::endl;
|
| | |
|
| | | this->isWander = false;
|
| | |
|
| | | //初始化跌倒的参数
|
| | | this->rate = 100;
|
| | | this->isFall = false;
|
| | | this->first_Fall = true;
|
| | | this->rateScale = 0;
|
| | | this->minRate = 0;
|
| | | this->center_point.x = 0;
|
| | | this->center_point.y = 0;
|
| | | this->fall_total_time = 0;
|
| | | this->hisMinRate = 100;
|
| | | this->human_h = 0;
|
| | | this->human_w = 0;
|
| | |
|
| | |
|
| | | //初始化奔跑的参数
|
| | | this->last_point.x = -1;
|
| | | this->last_point.y = -1;
|
| | | this->is_runing_p = true;
|
| | | this->is_runing_t = true;
|
| | | this->isRuning = false;
|
| | | this->sum_velocity = 0;
|
| | | this->confidence = 0;
|
| | | this->run_rate = 0;
|
| | | this->last_rate = 0;
|
| | | this->rate_area = 0.0;
|
| | |
|
| | | this->is_hat = false;
|
| | | this->hatScore = 0;
|
| | | this->headScore = 0;
|
| | | this->helmetScore = 0;
|
| | |
|
| | | this->is_mask=false;
|
| | | this->maskScore = 0;
|
| | |
|
| | | this->is_smoke=false;
|
| | | this->smokeScore = 0;
|
| | |
|
| | | // 添加当前的xy坐标
|
| | | // memset(&this->start,0,sizeof(struct this->timeval));
|
| | | // memset(&this->stop,0,sizeof(struct this->timeval));
|
| | | // memset(&this->diff,0,sizeof(struct this->timeval));
|
| | | }
|
| | |
|
| | | void Track::predit(KalmFilter *kf)
|
| | | {
|
| | | /*Propagate the state distribution to the current time step using a
|
| | | Kalman filter prediction step.
|
| | |
|
| | | Parameters
|
| | | ----------
|
| | | kf : kalman_filter.KalmFilter
|
| | | The Kalman filter.
|
| | | */
|
| | |
|
| | | kf->predict(this->mean, this->covariance);
|
| | | this->age += 1;
|
| | | this->time_since_update += 1;
|
| | | }
|
| | |
|
| | | void Track::update(KalmFilter * const kf, const DETECTION_ROW& detection, char* img_time)
|
| | | {
|
| | | // 判断消失三秒后删除该轨迹
|
| | | if(this->init_t){
|
| | | // gettimeofday(&this->start,0);
|
| | | this->start = char_2_unix(img_time);
|
| | | std::cout << "tracks start:: " << this->start << std::endl;
|
| | | this->init_t = false;
|
| | | }
|
| | |
|
| | | // gettimeofday(&this->stop,0);
|
| | | this->stop = char_2_unix(img_time);
|
| | | // this->time_substract(&this->diff, &this->start, &this->stop);
|
| | | this->diff = this->stop - this->start;
|
| | | std::cout << "tracks curr time:: " << this->stop << " tracks curr diff:: "<<(double)this->diff <<std::endl;
|
| | |
|
| | | // this->sum_timer = (double)((diff.tv_sec*1000000 + diff.tv_usec)/1000000);
|
| | | this->sum_timer = (double)(this->diff)/1000;
|
| | | printf("----Track update time------%f\n\n\n\n\n\n", this->sum_timer);
|
| | | // std::cout<< this->sum_timer << "::" << MAX_OUT_TIME<<std::endl;
|
| | |
|
| | | if(this->sum_timer > MAX_OUT_TIME)
|
| | | {
|
| | | this->state = TrackState::Deleted;
|
| | | this->_max_age = 0;
|
| | | this->last_time = 0;
|
| | |
|
| | | // gettimeofday(&this->last_s_time,0); // 重新徘徊计时(这是离开不到三秒都算是徘徊)
|
| | | this->last_s_time = char_2_unix(img_time);
|
| | | std::cout<< "wander start "<< this->last_s_time << " : " << img_time <<std::endl;
|
| | | // std::cout<< "--------------------------delete -----------------------";
|
| | | }
|
| | | // gettimeofday(&this->start,0);
|
| | | this->start = char_2_unix(img_time);
|
| | |
|
| | | // 计算徘徊的时长
|
| | | // gettimeofday(&this->last_e_time,0);
|
| | | this->last_e_time = char_2_unix(img_time);
|
| | | std::cout<< "wander end "<< this->last_e_time << " : " << img_time <<std::endl;
|
| | | // this->time_substract(&this->last_diff_time,&this->last_s_time,&this->last_e_time);
|
| | | this->last_diff_time = this->last_e_time - this->last_s_time;
|
| | | // this->last_time = (int)(this->last_diff_time.tv_sec+this->last_diff_time.tv_usec/1000000);
|
| | | this->last_time = (int)(this->last_diff_time/1000);
|
| | | std::cout<< "wander time "<< this->last_time << "::" << this->last_diff_time << "last_s_time" << this->last_s_time << " e: "<< this->last_e_time <<std::endl;
|
| | |
|
| | | // 奔跑记录单帧时间
|
| | | if(this->is_runing_t)
|
| | | {
|
| | | // gettimeofday(&this->single_s_time, 0);
|
| | | this->single_s_time = char_2_unix(img_time);
|
| | |
|
| | | this->is_runing_t = false;
|
| | | }else{
|
| | | // this->time_substract(&this->single_diff_time,&this->single_s_time,&this->last_e_time);
|
| | | this->single_diff_time = this->last_e_time - this->single_s_time;
|
| | | // this->single_time = (int)(this->single_diff_time.tv_sec*1000 + this->single_diff_time.tv_usec/1000);
|
| | | this->single_time = (int)(this->single_diff_time);
|
| | | // gettimeofday(&this->single_s_time, 0);
|
| | | this->single_s_time = char_2_unix(img_time);
|
| | | }
|
| | |
|
| | |
|
| | | KAL_DATA pa = kf->update(this->mean, this->covariance, detection.to_xyah());
|
| | | this->mean = pa.first;
|
| | | this->covariance = pa.second;
|
| | |
|
| | | // 添加当前的xy坐标
|
| | | this->xywh = detection.tlwh;
|
| | | this->confidence = (this->confidence*4+detection.confidence)/5;
|
| | |
|
| | | if(this->is_hat)
|
| | | {
|
| | | this->is_hat = detection.is_hat;
|
| | | this->hatScore =(int)((this->hatScore*9 + detection.hatScore)/10);
|
| | | this->helmetScore =(int)((this->helmetScore*9 + detection.helmetScore)/10);
|
| | | this->headScore =(int)((this->headScore*9 + detection.headScore)/10);
|
| | | }else
|
| | | {
|
| | | this->is_hat = detection.is_hat;
|
| | | this->hatScore = detection.hatScore;
|
| | | this->helmetScore = detection.helmetScore;
|
| | | this->headScore = detection.headScore;
|
| | | }
|
| | |
|
| | |
|
| | | this->is_mask = detection.is_mask;
|
| | | this->maskScore = detection.maskScore;
|
| | | this->is_smoke = detection.is_smoke;
|
| | | this->smokeScore = detection.smokeScore;
|
| | | /***yolo 直接测跌倒代码更新 s*/
|
| | | if(detection.obj_id==0)
|
| | | {
|
| | | this->fall_total_time = 0 ;
|
| | | this->first_Fall = true;
|
| | | this->rateScale = 0;
|
| | | this->isRuning = false;
|
| | | }else if(detection.obj_id==1)
|
| | | {
|
| | | /**-- start计算累积跌倒时间*/
|
| | | if(this->first_Fall) //是否开始计算跌倒时间
|
| | | {
|
| | | this->first_Fall = false;
|
| | | // gettimeofday(&this->fall_s_time,0);
|
| | | this->fall_s_time = char_2_unix(img_time);
|
| | | }
|
| | | // gettimeofday(&this->fall_e_time,0);
|
| | | this->fall_e_time = char_2_unix(img_time);
|
| | | // this->time_substract(&this->fall_diff_time,&this->fall_s_time,&this->fall_e_time); //距离最小比例的时间
|
| | | this->fall_diff_time = this->fall_e_time - this->fall_s_time;
|
| | | // this->fall_total_time = (int)(this->fall_diff_time.tv_sec + this->fall_diff_time.tv_usec/1000000);
|
| | | this->fall_total_time = (int)(this->fall_diff_time/1000);
|
| | |
|
| | | /** -- end计算累积跌倒时间*/
|
| | |
|
| | | this->rateScale = detection.confidence;
|
| | | this->isRuning = false;
|
| | |
|
| | | }else if(detection.obj_id==2)
|
| | | {
|
| | | this->isRuning = true;
|
| | | }
|
| | | /***yolo 直接测跌倒代码更新 end*/
|
| | |
|
| | | featuresAppendOne(detection.feature);
|
| | | // this->features.row(features.rows()) = detection.feature;
|
| | | this->hits += 1;
|
| | | this->time_since_update = 0;
|
| | | if(this->state == TrackState::Tentative && this->hits >= this->_n_init) {
|
| | | this->state = TrackState::Confirmed;
|
| | | }
|
| | | this->isCurrent = true;
|
| | | }
|
| | |
|
| | | bool Track::mark_missed(char* img_time)
|
| | | {
|
| | | if(this->init_t)
|
| | | {
|
| | | // gettimeofday(&this->start,0);
|
| | | this->start = char_2_unix(img_time);
|
| | | this->init_t = false;
|
| | | }
|
| | | // gettimeofday(&this->stop,0);
|
| | | this->stop = char_2_unix(img_time);
|
| | |
|
| | | // this->time_substract(&this->diff,&this->start,&this->stop);
|
| | | this->diff = this->stop - this->start;
|
| | |
|
| | | // this->sum_timer = (double)((diff.tv_sec*1000000 + diff.tv_usec)/1000000);
|
| | | this->sum_timer = (double)(this->diff)/1000;
|
| | |
|
| | | if(this->state == TrackState::Tentative) {
|
| | | this->state = TrackState::Deleted;
|
| | | return true;
|
| | | } else if(this->time_since_update > this->_max_age) {
|
| | | this->state = TrackState::Deleted;
|
| | | return true;
|
| | | } else if(this->sum_timer > MAX_OUT_TIME)
|
| | | {
|
| | | this->state = TrackState::Deleted;
|
| | | this->_max_age = 0;
|
| | | return true;
|
| | | }
|
| | | this->isCurrent = false;
|
| | | return false;
|
| | | }
|
| | |
|
| | | bool Track::is_confirmed()
|
| | | {
|
| | | return this->state == TrackState::Confirmed;
|
| | | }
|
| | |
|
| | | bool Track::is_deleted()
|
| | | {
|
| | | return this->state == TrackState::Deleted;
|
| | | }
|
| | |
|
| | | bool Track::is_tentative()
|
| | | {
|
| | | return this->state == TrackState::Tentative;
|
| | | }
|
| | |
|
| | | DETECTBOX Track::to_tlwh()
|
| | | {
|
| | | DETECTBOX ret = mean.leftCols(4);
|
| | | ret(2) *= ret(3);
|
| | | ret.leftCols(2) -= (ret.rightCols(2)/2);
|
| | | return ret;
|
| | | }
|
| | |
|
| | | DETECTBOX Track::to_xywh()
|
| | | {
|
| | | return this->xywh;
|
| | | }
|
| | |
|
| | | void Track::featuresAppendOne(const FEATURE &f)
|
| | | {
|
| | | int size = this->features.rows();
|
| | | FEATURESS newfeatures = FEATURESS(size+1, 128);
|
| | | newfeatures.block(0, 0, size, 128) = this->features;
|
| | | newfeatures.row(size) = f;
|
| | | features = newfeatures;
|
| | | // printf("--features size::---%d---%d--\n",size,features.rows());
|
| | | }
|
| | |
|
| | | int Track::time_substract(struct timeval *result, struct timeval *begin, struct timeval *end)
|
| | | {
|
| | | if(begin->tv_sec > end->tv_sec) return -1;
|
| | | if((begin->tv_sec == end->tv_sec) && (begin->tv_usec > end->tv_usec)) return -2;
|
| | | result->tv_sec = (end->tv_sec - begin->tv_sec);
|
| | | result->tv_usec = (end->tv_usec - begin->tv_usec);
|
| | |
|
| | | if(result->tv_usec < 0)
|
| | | {
|
| | | result->tv_sec--;
|
| | | result->tv_usec += 1000000;
|
| | | }
|
| | | return 0;
|
| | |
|
| | | }
|
| New file |
| | |
| | | #ifndef TRACK_H
|
| | | #define TRACK_H
|
| | |
|
| | | #include "dataType.h"
|
| | |
|
| | | #include "kalmfilter.h"
|
| | | #include "model.h"
|
| | | #include "time.h"
|
| | | #include "stdio.h"
|
| | | #include "stdlib.h"
|
| | | #include <iostream>
|
| | | #include<sys/time.h>
|
| | | #include "../utils/geometry_util.h"
|
| | | #include <queue>
|
| | | #include "../utils/queue_util.hpp"
|
| | | #include "../utils/log_util.h"
|
| | | #include "../utils/time_util.h"
|
| | |
|
| | | using namespace std;
|
| | |
|
| | | class Track
|
| | | {
|
| | |
|
| | | enum TrackState {Tentative = 1, Confirmed, Deleted}; // 轨迹的状态,Tentative 是刚开始的时候,Confirmed是确认了是人的轨迹,Deleted是删除的轨迹
|
| | |
|
| | | public:
|
| | | bool isCurrent;
|
| | | DETECTBOX xywh;
|
| | | Track();
|
| | | ~Track();
|
| | | Track(KAL_MEAN& mean, KAL_COVA& covariance, uint64_t track_id,
|
| | | int n_init, int max_age, const FEATURE& feature, char* img_time);
|
| | | void predit(KalmFilter *kf);
|
| | | void update(KalmFilter * const kf, const DETECTION_ROW &detection, char* img_time);
|
| | | bool mark_missed(char* img_time);
|
| | | bool is_confirmed();
|
| | | bool is_deleted();
|
| | | bool is_tentative();
|
| | | DETECTBOX to_tlwh();
|
| | | DETECTBOX to_xywh();
|
| | | int time_since_update; //累积检测不到的次数
|
| | | uint64_t track_id;
|
| | | FEATURESS features;
|
| | | float confidence;
|
| | | KAL_MEAN mean;
|
| | | KAL_COVA covariance;
|
| | |
|
| | | int hits;
|
| | | int age;
|
| | | int _n_init;
|
| | | int _max_age;
|
| | | TrackState state;
|
| | | int time_substract(struct timeval *result, struct timeval *begin,struct timeval *end);
|
| | |
|
| | | public:
|
| | | // 附加的其他算法
|
| | | // 逗留
|
| | | // struct timeval last_s_time, last_e_time, last_diff_time; // 逗留的开始时间、结束时间,和持续时间
|
| | | int last_s_time, last_e_time, last_diff_time; // 逗留的开始时间、结束时间,和持续时间
|
| | | int last_time; //持续逗留时间
|
| | | bool isWander;
|
| | |
|
| | | //跌倒
|
| | | float rate; //人体身高变化率
|
| | | bool isFall;
|
| | | bool first_Fall;
|
| | | int rateScale; //判断是否逐步跌倒(短时间内)
|
| | | MinQueue<float> rate_queue;
|
| | | // struct timeval fall_s_time, fall_e_time, fall_diff_time; // 跌倒的持续时间 ,字段fall_diff_time代表了两个含义。距离最小比例的时间+累积跌倒时间
|
| | | // struct timeval min_rate_time; //最大比例的定位时间
|
| | |
|
| | | int fall_s_time, fall_e_time, fall_diff_time; // 跌倒的持续时间 ,字段fall_diff_time代表了两个含义。距离最小比例的时间+累积跌倒时间
|
| | | int min_rate_time; //最大比例的定位时间
|
| | |
|
| | |
|
| | | int fall_total_time;
|
| | | float minRate; // 队列中的最大比例
|
| | | float hisMinRate;
|
| | | SPoint center_point, min_center_point; //重心的高度
|
| | | float human_h;
|
| | | float human_w;
|
| | |
|
| | |
|
| | |
|
| | | //奔跑
|
| | | bool is_runing_t;
|
| | | bool is_runing_p;
|
| | | bool isRuning;
|
| | | SPoint last_point;
|
| | | // struct timeval single_s_time, single_diff_time; // 单帧的结束时间可以用逗留里的时间代替
|
| | | int single_s_time, single_diff_time; // 单帧的结束时间可以用逗留里的时间代替
|
| | | int single_time; // 单帧所花销的时长(ms)
|
| | | queue<float> velocity_queue;
|
| | | float sum_velocity;
|
| | | double run_rate;
|
| | | double last_rate;
|
| | | double rate_area;
|
| | |
|
| | | // 帽子、口罩、抽烟
|
| | | bool is_hat;
|
| | | int hatScore;
|
| | | int helmetScore;
|
| | | int headScore;
|
| | |
|
| | | bool is_mask;
|
| | | int maskScore;
|
| | |
|
| | | bool is_smoke;
|
| | | int smokeScore;
|
| | |
|
| | | private:
|
| | | // struct timeval start,stop,diff;
|
| | | int start,stop,diff;
|
| | | double sum_timer;
|
| | | bool init_t;
|
| | | void init_track_time();
|
| | | void featuresAppendOne(const FEATURE& f);
|
| | |
|
| | | };
|
| | |
|
| | | #endif // TRACK_H
|
| New file |
| | |
| | | #include "tracker.h"
|
| | | #include "nn_matching.h"
|
| | | #include "model.h"
|
| | | #include "linear_assignment.h"
|
| | | #include <iostream>
|
| | |
|
| | | using namespace std;
|
| | |
|
| | | //#define MY_inner_DEBUG
|
| | | #ifdef MY_inner_DEBUG
|
| | | #include <string>
|
| | | #include <iostream>
|
| | | #endif
|
| | |
|
| | | tracker::tracker(
|
| | | float max_cosine_distance, int nn_budget,
|
| | | float max_iou_distance, int max_age, int n_init)
|
| | | {
|
| | | this->metric = new NearNeighborDisMetric(
|
| | | NearNeighborDisMetric::METRIC_TYPE::cosine,
|
| | | max_cosine_distance, nn_budget);
|
| | | this->max_iou_distance = max_iou_distance;
|
| | | this->max_age = max_age;
|
| | | this->n_init = n_init;
|
| | |
|
| | | this->kf = new KalmFilter();
|
| | | this->tracks.clear();
|
| | | this->_next_idx = 1;
|
| | | }
|
| | |
|
| | | tracker::~tracker()
|
| | | {
|
| | | // delete this->metric;
|
| | | // delete this->kf;
|
| | | }
|
| | |
|
| | | void tracker::predict()
|
| | | {
|
| | | for(auto& track:tracks)
|
| | | {
|
| | | track->predit(this->kf);
|
| | | }
|
| | | }
|
| | |
|
| | | void tracker::update(std::vector<std::shared_ptr<tracker>> &CAMERAS_VCT, const DETECTIONS &detections, int cam_id, char* img_time)
|
| | | {
|
| | | TRACHER_MATCHD res;
|
| | | // for (map<uint64_t, std::shared_ptr<Track>>::iterator iter=candidate_track_map.begin();iter!=candidate_track_map.end();iter++)
|
| | | // {
|
| | | // this->tracks.push_back(iter->second);
|
| | | // printf("-------------------this->tracks.size:%d\n",this->tracks.size());
|
| | | // }
|
| | |
|
| | | // std::cout<< "size1:"<< detections.size() << std::endl;
|
| | | // if (detections.size()==2){
|
| | | // for (DETECTION_ROW det : detections)
|
| | | // {
|
| | | // std::cout<< det.feature <<std::endl;
|
| | | // }
|
| | | // exit(0);
|
| | | // }
|
| | |
|
| | | _match(detections, res);
|
| | |
|
| | | vector<MATCH_DATA>& matches = res.matches;
|
| | | //#ifdef MY_inner_DEBUG
|
| | | // printf("res.matches size = %d:\n", matches.size());
|
| | | //#endif
|
| | | for(MATCH_DATA& data:matches) {
|
| | | int track_idx = data.first;
|
| | | int detection_idx = data.second;
|
| | | //#ifdef MY_inner_DEBUG
|
| | | // printf("\t%d == %d;\n", track_idx, detection_idx);
|
| | | //#endif
|
| | | tracks[track_idx]->update(this->kf, detections[detection_idx], img_time);
|
| | | // LOG(INFO) << "=======match-track_idx::" << tracks[track_idx]->track_id;
|
| | | // DEBUG( "=======match-track_idx::" + to_string(tracks[track_idx]->track_id));
|
| | | }
|
| | |
|
| | | vector<int>& unmatched_tracks = res.unmatched_tracks;
|
| | | //#ifdef MY_inner_DEBUG
|
| | | // printf("res.unmatched_tracks size = %d\n", unmatched_tracks.size());
|
| | | //#endif
|
| | | for(int& track_idx:unmatched_tracks)
|
| | | {
|
| | | this->tracks[track_idx]->mark_missed(img_time);
|
| | | }
|
| | | vector<int>& unmatched_detections = res.unmatched_detections;
|
| | | //#ifdef MY_inner_DEBUG
|
| | | // printf("res.unmatched_detections size = %d\n", unmatched_detections.size());
|
| | | //#endif
|
| | | for(int& detection_idx:unmatched_detections) {
|
| | | this->_initiate_track(detections[detection_idx], cam_id, img_time);
|
| | | }
|
| | | //#ifdef MY_inner_DEBUG
|
| | | // int size = tracks.size();
|
| | | // printf("now track size = %d\n", size);
|
| | | //#endif
|
| | | vector<std::shared_ptr<Track>>::iterator it;
|
| | | for(it = tracks.begin(); it != tracks.end();) {
|
| | | if((*it)->is_deleted()) it = tracks.erase(it);
|
| | | else ++it;
|
| | | }
|
| | | //#ifdef MY_inner_DEBUG
|
| | | // printf("update track size = %d\n", tracks.size());
|
| | | //#endif
|
| | |
|
| | | /* old version:
|
| | | //update distance metric:
|
| | | FEATURESS features;
|
| | | vector<int> targets;
|
| | | vector<int> active_targets;
|
| | | int pos = 0;
|
| | | for(Track track:tracks) {
|
| | | if(track.is_confirmed() == false) continue;
|
| | | active_targets.push_back(track.track_id);
|
| | | features.row(pos) = track.features;
|
| | | int rows = track.features.rows();
|
| | | pos += rows;
|
| | | for(int i = 0; i < rows; i++) targets.push_back(track.track_id);
|
| | | //attention!!!
|
| | | //track.features.clear();
|
| | | track.features = Eigen::Matrix<float, -1, 128, Eigen::RowMajor>(0,128);
|
| | | }
|
| | | this->metric->partial_fit(features, targets, active_targets);
|
| | | */
|
| | |
|
| | | vector<uint64_t> active_targets;
|
| | | vector<TRACKER_DATA> tid_features;
|
| | | for (auto& track:tracks)
|
| | | {
|
| | | if(track->is_confirmed() == false) continue;
|
| | | active_targets.push_back(track->track_id);
|
| | | tid_features.push_back(std::make_pair(track->track_id, track->features));
|
| | | FEATURESS t = FEATURESS(0, 128);
|
| | | track->features = t;
|
| | | }
|
| | |
|
| | | this->metric->partial_fit(tid_features, active_targets);
|
| | |
|
| | | }
|
| | |
|
| | | void tracker::_match(const DETECTIONS &detections, TRACHER_MATCHD &res)
|
| | | {
|
| | | DEBUG("tracker.cpp _match start 147:: ");
|
| | | vector<int> confirmed_tracks;
|
| | | vector<int> unconfirmed_tracks;
|
| | | int idx = 0;
|
| | | for(auto& t:tracks) {
|
| | | if(t->is_confirmed()) confirmed_tracks.push_back(idx);
|
| | | else unconfirmed_tracks.push_back(idx);
|
| | | idx++;
|
| | | }
|
| | |
|
| | | TRACHER_MATCHD matcha = linear_assignment::getInstance()->matching_cascade(
|
| | | this, &tracker::gated_matric,
|
| | | this->metric->mating_threshold,
|
| | | this->max_age,
|
| | | this->tracks,
|
| | | detections,
|
| | | confirmed_tracks);
|
| | | vector<int> iou_track_candidates;
|
| | | iou_track_candidates.assign(unconfirmed_tracks.begin(), unconfirmed_tracks.end());
|
| | | vector<int>::iterator it;
|
| | |
|
| | | for(it = matcha.unmatched_tracks.begin(); it != matcha.unmatched_tracks.end();) {
|
| | | int idx = *it;
|
| | | if(tracks[idx]->time_since_update == 1) { //push into unconfirmed
|
| | | iou_track_candidates.push_back(idx);
|
| | | it = matcha.unmatched_tracks.erase(it);
|
| | | continue;
|
| | | }
|
| | | ++it;
|
| | | }
|
| | |
|
| | | TRACHER_MATCHD matchb = linear_assignment::getInstance()->min_cost_matching(
|
| | | this, &tracker::iou_cost,
|
| | | this->max_iou_distance,
|
| | | this->tracks,
|
| | | detections,
|
| | | iou_track_candidates,
|
| | | matcha.unmatched_detections);
|
| | |
|
| | | //get result:
|
| | | res.matches.assign(matcha.matches.begin(), matcha.matches.end());
|
| | | res.matches.insert(res.matches.end(), matchb.matches.begin(), matchb.matches.end());
|
| | | //unmatched_tracks;
|
| | | res.unmatched_tracks.assign(
|
| | | matcha.unmatched_tracks.begin(),
|
| | | matcha.unmatched_tracks.end());
|
| | | res.unmatched_tracks.insert(
|
| | | res.unmatched_tracks.end(),
|
| | | matchb.unmatched_tracks.begin(),
|
| | | matchb.unmatched_tracks.end());
|
| | | res.unmatched_detections.assign(
|
| | | matchb.unmatched_detections.begin(),
|
| | | matchb.unmatched_detections.end());
|
| | | DEBUG("tracker.cpp _match end 207:: ");
|
| | |
|
| | | }
|
| | |
|
| | |
|
| | | void tracker::_initiate_track(const DETECTION_ROW &detection, int cam_id, char* img_time)
|
| | | {
|
| | | KAL_DATA data = kf->initiate(detection.to_xyah());
|
| | | KAL_MEAN mean = data.first;
|
| | | KAL_COVA covariance = data.second;
|
| | | uint64_t n_track_id;
|
| | | stringstream strValue;
|
| | | strValue << random_int(8);
|
| | | strValue >> n_track_id;
|
| | | // n_track_id = m_staticStruct::human_ids++;
|
| | | auto t = std::make_shared<Track>(mean, covariance, n_track_id, this->n_init, this->max_age, detection.feature, img_time);
|
| | | t->xywh = detection.tlwh;
|
| | | this->tracks.push_back(t);
|
| | |
|
| | | // auto t = std::make_shared<Track>(mean, covariance, this->_next_idx, this->n_init,this->max_age, detection.feature);
|
| | | // this->tracks.push_back(t);
|
| | | //
|
| | | // _next_idx += 1;
|
| | | }
|
| | |
|
| | |
|
| | | DYNAMICM tracker::gated_matric(
|
| | | std::vector<std::shared_ptr<Track>> &tracks,
|
| | | const DETECTIONS &dets,
|
| | | const std::vector<int>& track_indices,
|
| | | const std::vector<int>& detection_indices)
|
| | | {
|
| | | // FEATURESS features(detection_indices.size(), 128);
|
| | | // int pos = 0;
|
| | | // for(int i:detection_indices) {
|
| | | // features.row(pos++) = dets[i].feature;
|
| | | // }
|
| | | vector<uint64_t> targets;
|
| | | for(int i:track_indices) {
|
| | | targets.push_back(tracks[i]->track_id);
|
| | | }
|
| | | // DYNAMICM cost_matrix = this->metric->distance(features, targets);
|
| | | DYNAMICM cost_matrix = Eigen::MatrixXf::Zero(targets.size(), detection_indices.size());
|
| | | DYNAMICM res = linear_assignment::getInstance()->gate_cost_matrix(
|
| | | this->kf, cost_matrix, tracks, dets, track_indices,
|
| | | detection_indices);
|
| | | return res;
|
| | | }
|
| | |
|
| | | DYNAMICM
|
| | | tracker::cos_matric(
|
| | | std::vector<std::shared_ptr<Track> > &tracks,
|
| | | const DETECTIONS &dets, const std::vector<int>
|
| | | &track_indices, const std::vector<int>
|
| | | &detection_indices)
|
| | | {
|
| | | FEATURESS features(detection_indices.size(), 128);
|
| | | int pos = 0;
|
| | | for(int i : detection_indices) {
|
| | | features.row(pos++) = dets[i].feature;
|
| | | }
|
| | | std::map<uint64_t, FEATURESS> simples;
|
| | | for(auto i : track_indices)
|
| | | {
|
| | | simples[tracks[i]->track_id] = tracks[i]->features;
|
| | | }
|
| | |
|
| | | DYNAMICM res = this->metric->cos_distance(features, simples);
|
| | |
|
| | | return res;
|
| | | }
|
| | |
|
| | |
|
| | | DYNAMICM
|
| | | tracker::iou_cost(
|
| | | std::vector<std::shared_ptr<Track>> &tracks,
|
| | | const DETECTIONS &dets,
|
| | | const std::vector<int>& track_indices,
|
| | | const std::vector<int>& detection_indices)
|
| | | {
|
| | | //!!!python diff: track_indices && detection_indices will never be None.
|
| | | // if(track_indices.empty() == true) {
|
| | | // for(size_t i = 0; i < tracks.size(); i++) {
|
| | | // track_indices.push_back(i);
|
| | | // }
|
| | | // }
|
| | | // if(detection_indices.empty() == true) {
|
| | | // for(size_t i = 0; i < dets.size(); i++) {
|
| | | // detection_indices.push_back(i);
|
| | | // }
|
| | | // }
|
| | | int rows = track_indices.size();
|
| | | int cols = detection_indices.size();
|
| | | DYNAMICM cost_matrix = Eigen::MatrixXf::Zero(rows, cols);
|
| | | for(int i = 0; i < rows; i++) {
|
| | | int track_idx = track_indices[i];
|
| | | if(tracks[track_idx]->time_since_update > 1) {
|
| | | cost_matrix.row(i) = Eigen::RowVectorXf::Constant(cols, INFTY_COST);
|
| | | continue;
|
| | | }
|
| | | DETECTBOX bbox = tracks[track_idx]->to_tlwh();
|
| | | int csize = detection_indices.size();
|
| | | DETECTBOXSS candidates(csize, 4);
|
| | | for(int k = 0; k < csize; k++) candidates.row(k) = dets[detection_indices[k]].tlwh;
|
| | | Eigen::RowVectorXf rowV = (1. - iou(bbox, candidates).array()).matrix().transpose();
|
| | | cost_matrix.row(i) = rowV;
|
| | | }
|
| | | return cost_matrix;
|
| | | }
|
| | |
|
| | |
|
| | | Eigen::VectorXf
|
| | | tracker::iou(DETECTBOX& bbox, DETECTBOXSS& candidates)
|
| | | {
|
| | | float bbox_tl_1 = bbox[0];
|
| | | float bbox_tl_2 = bbox[1];
|
| | | float bbox_br_1 = bbox[0] + bbox[2];
|
| | | float bbox_br_2 = bbox[1] + bbox[3];
|
| | | float area_bbox = bbox[2] * bbox[3];
|
| | |
|
| | | Eigen::Matrix<float, -1, 2> candidates_tl;
|
| | | Eigen::Matrix<float, -1, 2> candidates_br;
|
| | | candidates_tl = candidates.leftCols(2) ;
|
| | | candidates_br = candidates.rightCols(2) + candidates_tl;
|
| | |
|
| | | int size = int(candidates.rows());
|
| | | // Eigen::VectorXf area_intersection(size);
|
| | | // Eigen::VectorXf area_candidates(size);
|
| | | Eigen::VectorXf res(size);
|
| | | for(int i = 0; i < size; i++) {
|
| | | float tl_1 = std::max(bbox_tl_1, candidates_tl(i, 0));
|
| | | float tl_2 = std::max(bbox_tl_2, candidates_tl(i, 1));
|
| | | float br_1 = std::min(bbox_br_1, candidates_br(i, 0));
|
| | | float br_2 = std::min(bbox_br_2, candidates_br(i, 1));
|
| | |
|
| | | float w = br_1 - tl_1; w = (w < 0? 0: w);
|
| | | float h = br_2 - tl_2; h = (h < 0? 0: h);
|
| | | float area_intersection = w * h;
|
| | | float area_candidates = candidates(i, 2) * candidates(i, 3);
|
| | | res[i] = area_intersection/(area_bbox + area_candidates - area_intersection);
|
| | | }
|
| | | //#ifdef MY_inner_DEBUG
|
| | | // std::cout << res << std::endl;
|
| | | //#endif
|
| | | return res;
|
| | | }
|
| New file |
| | |
| | | #ifndef TRACKER_H
|
| | | #define TRACKER_H
|
| | | #include <vector>
|
| | |
|
| | | #include "kalmfilter.h"
|
| | | #include "track.h"
|
| | | #include "model.h"
|
| | | // #include "../utils/config_util.h"
|
| | | #include "feature_util.h"
|
| | | #include "../utils/geometry_util.h"
|
| | | #include "../std_target.h"
|
| | |
|
| | | typedef int (*fn)(void* args, const int sender_chan, const char *recver, const char *data, const int len);
|
| | |
|
| | | class NearNeighborDisMetric;
|
| | |
|
| | | using CURRENT_ID_REG = std::pair<uint64_t, std::vector<bool>>;
|
| | |
|
| | | class tracker
|
| | | {
|
| | | public:
|
| | | NearNeighborDisMetric* metric;
|
| | | float max_iou_distance;
|
| | | int max_age;
|
| | | int n_init;
|
| | |
|
| | | KalmFilter* kf;
|
| | |
|
| | | uint64_t _next_idx;
|
| | |
|
| | | private:
|
| | | // bool P_in_Polygon(SPoint p, IntersectReg polygon);
|
| | | // std::vector<uint64_t> candidate_track_ids; // 候选列表,也就是新加入的人员信息:id、 track信息(特征信息、 坐标信息)
|
| | | // std::vector<uint64_t> current_track_ids; // 跟踪的id 信息
|
| | |
|
| | | public:
|
| | | std::vector<std::shared_ptr<Track>> tracks;
|
| | | tracker( /*NearNeighborDisMetric* metric,*/
|
| | | float max_cosine_distance, int nn_budget,
|
| | | float max_iou_distance = MAX_IOU_DISTANCE,
|
| | | int max_age = MAX_AGE, int n_init = N_INIT);
|
| | |
|
| | | ~tracker();
|
| | | void predict();
|
| | | void update(std::vector<std::shared_ptr<tracker>> &CAMERAS_VCT, const DETECTIONS& detections, int cam_id, char* img_time);
|
| | |
|
| | | typedef DYNAMICM (tracker::* GATED_METRIC_FUNC)(
|
| | | std::vector<std::shared_ptr<Track>>& tracks,
|
| | | const DETECTIONS& dets,
|
| | | const std::vector<int>& track_indices,
|
| | | const std::vector<int>& detection_indices);
|
| | | private:
|
| | | void _match(const DETECTIONS& detections, TRACHER_MATCHD& res);
|
| | | void _initiate_track(const DETECTION_ROW& detection, int cam_id, char* img_time);
|
| | | public:
|
| | | DYNAMICM gated_matric(
|
| | | std::vector<std::shared_ptr<Track>>& tracks,
|
| | | const DETECTIONS& dets,
|
| | | const std::vector<int>& track_indices,
|
| | | const std::vector<int>& detection_indices);
|
| | |
|
| | | DYNAMICM cos_matric(
|
| | | std::vector<std::shared_ptr<Track>>& tracks,
|
| | | const DETECTIONS& dets,
|
| | | const std::vector<int>& track_indices,
|
| | | const std::vector<int>& detection_indices);
|
| | |
|
| | | DYNAMICM iou_cost(
|
| | | std::vector<std::shared_ptr<Track>>& tracks,
|
| | | const DETECTIONS& dets,
|
| | | const std::vector<int>& track_indices,
|
| | | const std::vector<int>& detection_indices);
|
| | | Eigen::VectorXf iou(DETECTBOX& bbox,
|
| | | DETECTBOXSS &candidates);
|
| | | };
|
| | |
|
| | | #endif // TRACKER_H
|
| | |
| | | cv::imwrite(file_path + name + "_" + to_string(type) + ".jpg", aaaa);
|
| | | }
|
| | |
|
| | | void draw_SDK_result(cv::Mat mat_img, Target& target)
|
| | | void draw_SDK_result(cv::Mat mat_img, Target* target)
|
| | | {
|
| | | cv::Rect tmp_rect = cv::Rect(target.rect.left,target.rect.top,target.rect.right-target.rect.left,target.rect.bottom-target.rect.top);
|
| | | cv::Rect tmp_rect = cv::Rect(target->rect.left,target->rect.top,target->rect.right-target->rect.left,target->rect.bottom-target->rect.top);
|
| | | cv::rectangle(mat_img, tmp_rect , cv::Scalar(50, 200, 50), 2);
|
| | | // cv::resize(mat_img, mat_img, frameSize);
|
| | | // cv::imwrite("1111.jpg", mat_img);
|
| | | cv::imshow(to_string(1), mat_img);
|
| | | cv::waitKey(0);
|
| | | cv::waitKey(1);
|
| | | }
|
| | |
|
| | | cv::VideoWriter writer("./01_baseDetector.avi", cv::VideoWriter::fourcc('M','J','P','G'),24, cv::Size(800,500), true);
|
| | | // cv::VideoWriter writer("/opt/vasystem/valog/01_Scheanve/01_baseDetector.avi", cv::VideoWriter::fourcc('M','J','P','G'),24, cv::Size(800,500), true);
|
| | |
|
| | | void draw_SDK_result(const int cam_id, cv::Mat mat_img, TResult& t_result)
|
| | | void draw_SDK_result(const int cam_id, cv::Mat mat_img, TResult* t_result)
|
| | | {
|
| | | cv::Rect tmp_rect;
|
| | |
|
| | | for (int i = 0; i < t_result.count; ++i)
|
| | | for (int i = 0; i < t_result->count; ++i)
|
| | | {
|
| | | auto &result = t_result.targets[i];
|
| | | auto &result = t_result->targets[i];
|
| | | tmp_rect = cv::Rect(result.rect.left,result.rect.top,result.rect.right-result.rect.left,result.rect.bottom-result.rect.top);
|
| | | cv::rectangle(mat_img, tmp_rect , cv::Scalar(50, 200, 50), 2);
|
| | | // cv::putText(mat_img, std::to_string(result.id), Point((result.rect.left+result.rect.right)/2,result.rect.top+150), CV_FONT_HERSHEY_SIMPLEX, 0.8, Scalar(255,255,0), 2);
|
| | |
| | |
|
| | | void create_foldert(const char *path);
|
| | |
|
| | | void draw_SDK_result(cv::Mat mat_img, Target& target);
|
| | | void draw_SDK_result(const int cam_id, cv::Mat mat_img, TResult& t_result);
|
| | | void draw_SDK_result(cv::Mat mat_img, Target* target);
|
| | | void draw_SDK_result(const int cam_id, cv::Mat mat_img, TResult* t_result);
|
| | |
|
| | |
|
| | |
|
| New file |
| | |
| | | //
|
| | | // Created by Scheaven on 2020/5/31.
|
| | | //
|
| | |
|
| | | #include "geometry_util.h"
|
| | | using namespace std;
|
| | |
|
| | |
|
| | | SPoint::_Point() {}
|
| | | SPoint::_Point(float x, float y)
|
| | | {
|
| | | this->x = x;
|
| | | this->y = y;
|
| | | this->z = 0;
|
| | | }
|
| | |
|
| | | SPoint::_Point(double a, double b, double c)
|
| | | {
|
| | | x = a; y = b; z = c;
|
| | | }
|
| | |
|
| | | float calDistance(SPoint A, SPoint B)
|
| | | {
|
| | | float x_d, y_d;
|
| | | x_d = A.x - B.x;
|
| | | y_d = A.y - B.y;
|
| | | float len = sqrt(x_d * x_d + 4*y_d * y_d);
|
| | | return len;
|
| | | }
|
| | |
|
| | | //bool Pt_in_Polygon(SPoint point, RegInfo* polygon)
|
| | | //{
|
| | | // int nCross = 0;
|
| | | // for (int i = 0; i < polygon->count; ++i)
|
| | | // {
|
| | | // SPoint p1 = polygon[i];
|
| | | // SPoint p2 = polygon[(i+1)%polygon->count];
|
| | | //
|
| | | // if ( p1.y == p2.y )
|
| | | // continue;
|
| | | // if ( p.y < min(p1.y, p2.y) )
|
| | | // continue;
|
| | | // if ( p.y >= max(p1.y, p2.y) )
|
| | | // continue;
|
| | | //
|
| | | // float x = (float)(p.y - p1.y) * (float)(p2.x - p1.x) / (float)(p2.y - p1.y) + p1.x;
|
| | | //
|
| | | // if ( x > p.x )
|
| | | // {
|
| | | // nCross++;
|
| | | // }
|
| | | //
|
| | | // }
|
| | | //
|
| | | // if ((nCross % 2) == 1)
|
| | | // {
|
| | | // return true;
|
| | | // }
|
| | | // else
|
| | | // {
|
| | | // return false;
|
| | | // }
|
| | |
|
| | | //}
|
| | |
|
| | |
|
| | | float computeArea(const SPoint * pt,int n ) {
|
| | | float area0 = 0.f;
|
| | | for (int i = 0 ; i < n ; i++ )
|
| | | {
|
| | | int j = (i+1)%n;
|
| | | area0 += pt[i].x * pt[j].y;
|
| | | area0 -= pt[i].y * pt[j].x;
|
| | | }
|
| | | return 0.5f * fabs(area0);
|
| | | }
|
| | |
|
| | | struct PointAngle{
|
| | | SPoint p;
|
| | | float angle;
|
| | | };
|
| | |
|
| | | float Polygon::area() const {
|
| | | return computeArea(pt,n);
|
| | | }
|
| | |
|
| | | static inline int cross(const SPoint* a,const SPoint* b) {
|
| | | return a->x * b->y - a->y * b->x;
|
| | | }
|
| | |
|
| | | static inline SPoint* vsub(const SPoint* a,const SPoint* b, SPoint* res) {
|
| | | res->x = a->x - b->x;
|
| | | res->y = a->y - b->y;
|
| | | return res;
|
| | | }
|
| | |
|
| | |
|
| | | static int line_sect(const SPoint* x0,const SPoint* x1,const SPoint* y0,const SPoint* y1, SPoint* res) {
|
| | | SPoint dx, dy, d;
|
| | | vsub(x1, x0, &dx);
|
| | | vsub(y1, y0, &dy);
|
| | | vsub(x0, y0, &d);
|
| | | float dyx = (float)cross(&dy, &dx);
|
| | | if (!dyx) return 0;
|
| | | dyx = cross(&d, &dx) / dyx;
|
| | | if (dyx <= 0 || dyx >= 1) return 0;
|
| | | res->x = int(y0->x + dyx * dy.x);
|
| | | res->y = int(y0->y + dyx * dy.y);
|
| | | return 1;
|
| | | }
|
| | |
|
| | | static int left_of(const SPoint* a,const SPoint* b,const SPoint* c) {
|
| | | SPoint tmp1, tmp2;
|
| | | int x;
|
| | | vsub(b, a, &tmp1);
|
| | | vsub(c, b, &tmp2);
|
| | | x = cross(&tmp1, &tmp2);
|
| | | return x < 0 ? -1 : x > 0;
|
| | | }
|
| | |
|
| | | static void poly_edge_clip(const Polygon* sub,const SPoint* x0,const SPoint* x1, int left, Polygon* res) {
|
| | | int i, side0, side1;
|
| | | SPoint tmp;
|
| | | const SPoint* v0 = sub->pt+ sub->n - 1;
|
| | | const SPoint* v1;
|
| | | res->clear();
|
| | |
|
| | | side0 = left_of(x0, x1, v0);
|
| | | if (side0 != -left) res->add(*v0);
|
| | |
|
| | | for (i = 0; i < sub->n; i++) {
|
| | | v1 = sub->pt + i;
|
| | | side1 = left_of(x0, x1, v1);
|
| | | if (side0 + side1 == 0 && side0)
|
| | | /* last point and current straddle the edge */
|
| | | if (line_sect(x0, x1, v0, v1, &tmp))
|
| | | res->add(tmp);
|
| | | if (i == sub->n - 1) break;
|
| | | if (side1 != -left) res->add(*v1);
|
| | | v0 = v1;
|
| | | side0 = side1;
|
| | | }
|
| | | }
|
| | |
|
| | | static int poly_winding(const Polygon* p) {
|
| | | return left_of(p->pt, p->pt + 1, p->pt + 2);
|
| | | }
|
| | |
|
| | |
|
| | | void intersectPolygonSHPC(const Polygon * sub, const Polygon* clip, Polygon* res)
|
| | | {
|
| | | int i;
|
| | | Polygon P1,P2;
|
| | | Polygon *p1 = &P1;
|
| | | Polygon *p2 = &P2;
|
| | | Polygon *tmp;
|
| | |
|
| | | int dir = poly_winding(clip);
|
| | | poly_edge_clip(sub, clip->pt + clip->n - 1, clip->pt, dir, p2);
|
| | | for (i = 0; i < clip->n - 1; i++) {
|
| | | tmp = p2; p2 = p1; p1 = tmp;
|
| | | if(p1->n == 0) {
|
| | | p2->n = 0;
|
| | | break;
|
| | | }
|
| | | poly_edge_clip(p1, clip->pt + i, clip->pt + i + 1, dir, p2);
|
| | | }
|
| | | res->clear();
|
| | | for (i = 0 ; i < p2->n ; i++) res->add(p2->pt[i]);
|
| | | }
|
| | |
|
| | | void intersectPolygonSHPC(const Polygon & sub,const Polygon& clip,Polygon& res) {
|
| | | intersectPolygonSHPC(&sub, &clip, &res);
|
| | | }
|
| | |
|
| | | Line::Line(SPoint a, SPoint b, bool _is_seg)
|
| | | {
|
| | | s = a; e = b; is_seg = _is_seg;
|
| | | }
|
| | |
|
| | | Line::Line() {}
|
| | |
|
| | |
|
| | | bool PointCmp(const SPoint &a,const SPoint &b,const SPoint ¢er)
|
| | | {
|
| | | if (a.x >= 0 && b.x < 0)
|
| | | return true;
|
| | | if (a.x == 0 && b.x == 0)
|
| | | return a.y > b.y;
|
| | | int det = (a.x - center.x) * (b.y - center.y) - (b.x - center.x) * (a.y - center.y);
|
| | | if (det < 0)
|
| | | return true;
|
| | | if (det > 0)
|
| | | return false;
|
| | | int d1 = (a.x - center.x) * (a.x - center.x) + (a.y - center.y) * (a.y - center.y);
|
| | | int d2 = (b.x - center.x) * (b.x - center.y) + (b.y - center.y) * (b.y - center.y);
|
| | | return d1 > d2;
|
| | | }
|
| | |
|
| | | SPoint ClockwiseSortPoints(std::vector<SPoint> &vPoints)
|
| | | {
|
| | | SPoint center;
|
| | | double x = 0,y = 0;
|
| | | for (int i = 0;i < vPoints.size();i++)
|
| | | {
|
| | | x += vPoints[i].x;
|
| | | y += vPoints[i].y;
|
| | | }
|
| | | center.x = (int)x/vPoints.size();
|
| | | center.y = (int)y/vPoints.size();
|
| | |
|
| | | for(int i = 0;i < vPoints.size() - 1;i++)
|
| | | {
|
| | | for (int j = 0;j < vPoints.size() - i - 1;j++)
|
| | | {
|
| | | if (PointCmp(vPoints[j],vPoints[j+1],center))
|
| | | {
|
| | | SPoint tmp = vPoints[j];
|
| | | vPoints[j] = vPoints[j + 1];
|
| | | vPoints[j + 1] = tmp;
|
| | | }
|
| | | }
|
| | | }
|
| | | return center;
|
| | | }
|
| | |
|
| | | SPoint add(const SPoint& lhs, const SPoint& rhs)
|
| | | {
|
| | | SPoint res;
|
| | |
|
| | | res.x = lhs.x + rhs.x;
|
| | | res.y = lhs.y + rhs.y;
|
| | | res.z = lhs.z + rhs.z;
|
| | |
|
| | | return res;
|
| | | }
|
| | | SPoint sub(const SPoint& lhs, const SPoint& rhs)
|
| | | {
|
| | | SPoint res;
|
| | |
|
| | | res.x = lhs.x - rhs.x;
|
| | | res.y = lhs.y - rhs.y;
|
| | | res.z = lhs.z - rhs.z;
|
| | |
|
| | | return res;
|
| | | }
|
| | | SPoint mul(const SPoint& p, double ratio)
|
| | | {
|
| | | SPoint res;
|
| | |
|
| | | res.x = p.x * ratio;
|
| | | res.y = p.y * ratio;
|
| | | res.z = p.z * ratio;
|
| | |
|
| | | return res;
|
| | | }
|
| | | SPoint div(const SPoint& p, double ratio)
|
| | | {
|
| | | SPoint res;
|
| | |
|
| | | res.x = p.x / ratio;
|
| | | res.y = p.y / ratio;
|
| | | res.z = p.z / ratio;
|
| | |
|
| | | return res;
|
| | | }
|
| | | bool equal(const SPoint& lhs, const SPoint& rhs)
|
| | | {
|
| | | return(lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
|
| | | }
|
| | |
|
| | | double length(const SPoint& vec)
|
| | | {
|
| | | return (sqrt(pow(vec.x, 2) + pow(vec.y, 2) + pow(vec.z, 2)));
|
| | | }
|
| | |
|
| | | SPoint normalize(const SPoint& vec)
|
| | | {
|
| | | SPoint res;
|
| | |
|
| | | res = div(vec, length(vec));
|
| | |
|
| | | return res;
|
| | | }
|
| | |
|
| | | double dotMultiply(const SPoint& op, const SPoint& p1, const SPoint& p2)
|
| | | {
|
| | | return ((p1.x - op.x) * (p2.x - op.x) + (p1.y - op.y) * (p2.y - op.y) + (p1.z - op.z) * (p2.z - op.z));
|
| | | }
|
| | | double dotMultiply(const SPoint& vec1, const SPoint& vec2)
|
| | | {
|
| | | return(vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z);
|
| | | }
|
| | |
|
| | | SPoint multiply(const SPoint& op, const SPoint& p1, const SPoint& p2)
|
| | | {
|
| | | SPoint result;
|
| | |
|
| | | result.x = (p1.y - op.y) * (p2.z - op.z) - (p2.y - op.y) * (p1.z - op.z);
|
| | | result.y = (p1.z - op.z) * (p2.x - op.x) - (p2.z - op.z) * (p1.x - op.x);
|
| | | result.z = (p1.x - op.x) * (p2.y - op.y) - (p2.x - op.x) * (p1.y - op.y);
|
| | |
|
| | | return result;
|
| | | }
|
| | |
|
| | | SPoint multiply(const SPoint& vec1, const SPoint& vec2)
|
| | | {
|
| | | SPoint result;
|
| | |
|
| | | result.x = vec1.y * vec2.z - vec2.y * vec1.z;
|
| | | result.y = vec1.z * vec2.x - vec2.z * vec1.x;
|
| | | result.z = vec1.x * vec2.y - vec2.x * vec1.y;
|
| | |
|
| | | return result;
|
| | | }
|
| | |
|
| | | bool isponl(const SPoint& p, const Line& l)
|
| | | {
|
| | | SPoint line_vec = sub(l.e, l.s);
|
| | | SPoint point_vec1 = sub(p, l.s);
|
| | | SPoint point_vec2 = sub(p, l.e);
|
| | |
|
| | | SPoint mul_vec = multiply(line_vec, point_vec1);
|
| | | double dot = dotMultiply(point_vec1, point_vec2);
|
| | | if (l.is_seg)
|
| | | {
|
| | | if (equal(p,l.s) || equal(p,l.e))
|
| | | return true;
|
| | | return (0.0 == length(mul_vec) && dot < 0.0);
|
| | |
|
| | | }
|
| | | else
|
| | | {
|
| | | return (0.0 == length(mul_vec));
|
| | | }
|
| | | }
|
| | |
|
| | | double Cos(const SPoint& vec1, const SPoint& vec2)
|
| | | {
|
| | | SPoint unit_vec1 = normalize(vec1);
|
| | | SPoint unit_vec2 = normalize(vec2);
|
| | |
|
| | | return dotMultiply(unit_vec1, unit_vec2);
|
| | | }
|
| | |
|
| | | double Cos(const SPoint& op, const SPoint& p1, const SPoint& p2)
|
| | | {
|
| | | SPoint vec1 = sub(p1, op);
|
| | | SPoint vec2 = sub(p2, op);
|
| | |
|
| | | return Cos(vec1, vec2);
|
| | | }
|
| | |
|
| | |
|
| | | bool isSegIntersect(const Line& l1, const Line& l2, SPoint& inter_p)
|
| | | {
|
| | | SPoint line1 = sub(l1.e, l1.s);
|
| | | SPoint line2 = sub(l2.e, l2.s);
|
| | | SPoint norm1 = normalize(line1);
|
| | | SPoint norm2 = normalize(line2);
|
| | | if (l1.is_seg)
|
| | | {
|
| | | if (isponl(l1.s, l2))
|
| | | {
|
| | | inter_p = l1.s;
|
| | | return true;
|
| | | }
|
| | | if (isponl(l1.e, l2))
|
| | | {
|
| | | inter_p = l1.e;
|
| | | return true;
|
| | | }
|
| | | if (isponl(l2.s, l1))
|
| | | {
|
| | | inter_p = l2.s;
|
| | | return true;
|
| | | }
|
| | | if (isponl(l2.e, l1))
|
| | | {
|
| | | inter_p = l2.e;
|
| | | return true;
|
| | | }
|
| | | double dot1 = dotMultiply(multiply(sub(l2.s, l1.s), line1), multiply(sub(l2.e, l1.s), line1));
|
| | | double dot2 = dotMultiply(multiply(sub(l1.s, l2.s), line2), multiply(sub(l1.e, l2.s), line2));
|
| | | if (dot1 < 0.0 && dot2 < 0.0)
|
| | | {
|
| | | double t1 = length(multiply(sub(l1.s, l2.s), norm2)) / length(multiply(norm2, norm1));
|
| | | double t2 = length(multiply(sub(l2.s, l1.s), norm1)) / length(multiply(norm1, norm2));
|
| | |
|
| | | inter_p = add(l1.s, mul(norm1, t1));
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | return false;
|
| | | }
|
| | |
|
| | | }
|
| | | else
|
| | | {
|
| | | if (Cos(line1, line2) == 1.0)
|
| | | return false;
|
| | |
|
| | | double t1 = length(multiply(sub(l1.s, l2.s), norm2)) / length(multiply(norm2, norm1));
|
| | | double t2 = length(multiply(sub(l2.s, l1.s), norm1)) / length(multiply(norm1, norm2));
|
| | |
|
| | | inter_p = add(l1.s, mul(norm1, t1));
|
| | | return true;
|
| | | }
|
| | | }
|
| | |
|
| | | // bool p_inPolygon(Point p, vector<Point> point_vec)
|
| | | // {
|
| | | // int nCross = 0;
|
| | | // for (int i = 0; i < point_vec.size(); ++i)
|
| | | // {
|
| | | // Point p1(point_vec[i].x, point_vec[i].y);
|
| | | // Point p2(point_vec[(i+1)%point_vec.size()].x, point_vec[(i+1)%point_vec.size()].y);
|
| | |
|
| | | // if ( p1.y == p2.y )
|
| | | // continue;
|
| | | // if ( p.y < min(p1.y, p2.y) )
|
| | | // continue;
|
| | | // if ( p.y >= max(p1.y, p2.y) )
|
| | | // continue;
|
| | |
|
| | | // float x = (float)(p.y - p1.y) * (float)(p2.x - p1.x) / (float)(p2.y - p1.y) + p1.x;
|
| | |
|
| | | // if ( x > p.x )
|
| | | // {
|
| | | // nCross++;
|
| | | // }
|
| | |
|
| | | // }
|
| | |
|
| | | // if ((nCross % 2) == 1)
|
| | | // {
|
| | | // return true;
|
| | | // }
|
| | | // else
|
| | | // {
|
| | | // return false;
|
| | | // }
|
| | | // }
|
| | |
|
| New file |
| | |
| | | //
|
| | | // Created by Scheaven on 2020/5/31.
|
| | | //
|
| | | #ifndef GEOMETRY_UTIL_H
|
| | | #define GEOMETRY_UTIL_H
|
| | |
|
| | | #include <vector>
|
| | | #include <map>
|
| | | #include <string>
|
| | | #include <list>
|
| | | #include <fstream>
|
| | | #include <stdint.h>
|
| | | #include "stdio.h"
|
| | | #include <stdlib.h>
|
| | | #include <math.h>
|
| | |
|
| | | #include <iostream>
|
| | | #include <cmath>
|
| | | #include <cstring>
|
| | | #include "assert.h"
|
| | |
|
| | | const double PI = 3.14159265;
|
| | |
|
| | | typedef struct _Point
|
| | | {
|
| | | public:
|
| | | float x;
|
| | | float y;
|
| | | float z;
|
| | |
|
| | | public:
|
| | | _Point(float x, float y);
|
| | | _Point();
|
| | | _Point(double a , double b , double c );
|
| | | }SPoint;
|
| | |
|
| | | // 多边形区域结构
|
| | | typedef struct _PInfo
|
| | | {
|
| | | SPoint* point;
|
| | | int count;
|
| | | }RegInfo;
|
| | |
|
| | | float calDistance(SPoint A, SPoint B);
|
| | |
|
| | |
|
| | | bool Pt_in_Polygon(SPoint point, RegInfo* polygon);
|
| | |
|
| | | #define MAX_POINT_POLYGON 64
|
| | |
|
| | | struct Polygon {
|
| | | SPoint pt[MAX_POINT_POLYGON];
|
| | | int n;
|
| | |
|
| | | Polygon(int n_ = 0 ) { assert(n_>= 0 && n_ < MAX_POINT_POLYGON); n = n_;}
|
| | | virtual ~Polygon() {}
|
| | |
|
| | | void clear() { n = 0; }
|
| | | void add(const SPoint &p) {if(n < MAX_POINT_POLYGON) pt[n++] = p;}
|
| | | void push_back(const SPoint &p) {add(p);}
|
| | | int size() const { return n;}
|
| | | SPoint getCenter() const ;
|
| | | const SPoint & operator[] (int index) const { assert(index >= 0 && index < n); return pt[index];}
|
| | | SPoint& operator[] (int index) { assert(index >= 0 && index < n); return pt[index]; }
|
| | | void pointsOrdered() ;
|
| | | float area() const ;
|
| | | bool pointIsInPolygon(SPoint p) const ;
|
| | | };
|
| | |
|
| | |
|
| | | void intersectPolygonSHPC(const Polygon * sub,const Polygon* clip,Polygon* res) ;
|
| | | void intersectPolygonSHPC(const Polygon & sub,const Polygon& clip,Polygon& res) ;
|
| | |
|
| | |
|
| | | //struct Point
|
| | | //{
|
| | | // double x; // x坐标
|
| | | // double y; // y坐标
|
| | | // double z; // z坐标(默认为0,如果需要三维点则给z赋值)
|
| | | //
|
| | | // Point(double a , double b , double c = 0); // 构造函数
|
| | | // Point(); // 构造函数
|
| | | //};
|
| | |
|
| | | struct Line
|
| | | {
|
| | | SPoint s;
|
| | | SPoint e;
|
| | | bool is_seg;
|
| | |
|
| | | Line();
|
| | | Line(SPoint a, SPoint b, bool _is_seg = true);
|
| | | };
|
| | |
|
| | | bool PointCmp(const SPoint &a,const SPoint &b,const SPoint ¢er);
|
| | |
|
| | | SPoint ClockwiseSortPoints(std::vector<SPoint> &vPoints); // 多边形的点按照逆时针排序
|
| | |
|
| | | SPoint add(const SPoint& lhs, const SPoint& rhs);
|
| | |
|
| | | SPoint sub(const SPoint& lhs, const SPoint& rhs);
|
| | |
|
| | | SPoint mul(const SPoint& p, double ratio);
|
| | |
|
| | | SPoint div(const SPoint& p, double ratio);
|
| | |
|
| | | bool equal(const SPoint& lhs, const SPoint& rhs);
|
| | |
|
| | | double length(const SPoint& vec);
|
| | |
|
| | | SPoint normalize(const SPoint& vec);
|
| | |
|
| | | double dotMultiply(const SPoint& op, const SPoint& p1, const SPoint& p2);
|
| | |
|
| | | double dotMultiply(const SPoint& vec1, const SPoint& vec2);
|
| | |
|
| | | SPoint multiply(const SPoint& op, const SPoint& p1, const SPoint& p2);
|
| | |
|
| | | SPoint multiply(const SPoint& vec1, const SPoint& vec2);
|
| | |
|
| | | bool isponl(const SPoint& p, const Line& l);
|
| | |
|
| | | double Cos(const SPoint& vec1, const SPoint& vec2);
|
| | |
|
| | | double Cos(const SPoint& op, const SPoint& p1, const SPoint& p2);
|
| | |
|
| | | bool isSegIntersect(const Line& l1, const Line& l2, SPoint& inter_p);
|
| | |
|
| | | #endif //GEOMETRY_UTIL_H
|
| New file |
| | |
| | | //
|
| | | // Created by Scheaven on 2020/6/8.
|
| | | //
|
| | |
|
| | | #ifndef _QUEUE_UTIL_H
|
| | | #define _QUEUE_UTIL_H
|
| | |
|
| | | #include "stack_util.hpp"
|
| | |
|
| | | using namespace std;
|
| | |
|
| | | template <typename T>
|
| | | class MaxQueue
|
| | | {
|
| | | private:
|
| | | MaxStack<T> stackA;
|
| | | MaxStack<T> stackB;
|
| | |
|
| | | public:
|
| | | MaxQueue(){};
|
| | | ~MaxQueue(){};
|
| | |
|
| | | void push(T ele)
|
| | | {
|
| | | stackA.push(ele);
|
| | | };
|
| | |
|
| | | void pop()
|
| | | {
|
| | | if(stackB.isEmpty())
|
| | | {
|
| | | // if(stackA.isEmpty())
|
| | | // {
|
| | | // return ;
|
| | | // }
|
| | | while (!stackA.isEmpty())
|
| | | {
|
| | | stackB.push(stackA.top());
|
| | | stackA.pop();
|
| | | }
|
| | | }
|
| | |
|
| | | stackB.pop();
|
| | | };
|
| | |
|
| | |
|
| | | T front()
|
| | | {
|
| | | if(stackB.isEmpty())
|
| | | {
|
| | | // if(stackA.isEmpty())
|
| | | // {
|
| | | // return ;
|
| | | // }
|
| | | while (!stackA.isEmpty())
|
| | | {
|
| | | stackB.push(stackA.top());
|
| | | stackA.pop();
|
| | | }
|
| | | }
|
| | | return stackB.top();
|
| | | };
|
| | |
|
| | | T max()
|
| | | {
|
| | | if(!stackA.isEmpty()&&!stackB.isEmpty())
|
| | | {
|
| | | return stackA.maxItem()>stackB.maxItem()?stackA.maxItem():stackB.maxItem();
|
| | | } else if(!stackA.isEmpty()&&stackB.isEmpty())
|
| | | {
|
| | | return stackA.maxItem();
|
| | | } else
|
| | | {
|
| | | return stackB.maxItem();
|
| | | }
|
| | | };
|
| | |
|
| | | int size()
|
| | | {
|
| | | return stackA.size()+stackB.size();
|
| | | }
|
| | |
|
| | | bool isEmpty()
|
| | | {
|
| | | return stackA.isEmpty()&&stackB.isEmpty();
|
| | | };
|
| | |
|
| | | };
|
| | |
|
| | | template <typename T>
|
| | | class MinQueue
|
| | | {
|
| | | private:
|
| | | MinStack<T> stackA;
|
| | | MinStack<T> stackB;
|
| | |
|
| | | public:
|
| | | MinQueue(){};
|
| | | ~MinQueue(){};
|
| | |
|
| | | void push(T ele)
|
| | | {
|
| | | stackA.push(ele);
|
| | | };
|
| | |
|
| | | void pop()
|
| | | {
|
| | | if(stackB.isEmpty())
|
| | | {
|
| | | // if(stackA.isEmpty())
|
| | | // {
|
| | | // return ;
|
| | | // }
|
| | | while (!stackA.isEmpty())
|
| | | {
|
| | | stackB.push(stackA.top());
|
| | | stackA.pop();
|
| | | }
|
| | | }
|
| | |
|
| | | stackB.pop();
|
| | | };
|
| | |
|
| | |
|
| | | T front()
|
| | | {
|
| | | if(stackB.isEmpty())
|
| | | {
|
| | | // if(stackA.isEmpty())
|
| | | // {
|
| | | // return ;
|
| | | // }
|
| | | while (!stackA.isEmpty())
|
| | | {
|
| | | stackB.push(stackA.top());
|
| | | stackA.pop();
|
| | | }
|
| | | }
|
| | | return stackB.top();
|
| | | };
|
| | |
|
| | | T min()
|
| | | {
|
| | | if(!stackA.isEmpty()&&!stackB.isEmpty())
|
| | | {
|
| | | return stackA.minItem()<stackB.minItem()?stackA.minItem():stackB.minItem();
|
| | | } else if(!stackA.isEmpty()&&stackB.isEmpty())
|
| | | {
|
| | | return stackA.minItem();
|
| | | } else
|
| | | {
|
| | | return stackB.minItem();
|
| | | }
|
| | | };
|
| | |
|
| | | int size()
|
| | | {
|
| | | return stackA.size()+stackB.size();
|
| | | }
|
| | |
|
| | | bool isEmpty()
|
| | | {
|
| | | return stackA.isEmpty()&&stackB.isEmpty();
|
| | | };
|
| | |
|
| | | };
|
| | |
|
| | | #endif //INC_05_MAX_STACK_QUEUE_QUEUE_UTIL_H
|
| New file |
| | |
| | | //
|
| | | // Created by Scheaven on 2020/6/8.
|
| | | //
|
| | |
|
| | | #ifndef _STACK_UTIL_H
|
| | | #define _STACK_UTIL_H
|
| | |
|
| | | #include <algorithm>
|
| | | #include <memory.h>
|
| | | #include <iostream>
|
| | | #include <fstream>
|
| | | #include <string>
|
| | | #include <iomanip>
|
| | | #include <stdlib.h>
|
| | | #include <vector>
|
| | | #include <stack>
|
| | | #include <cstdio>
|
| | |
|
| | | using namespace std;
|
| | |
|
| | |
|
| | | template <typename T>
|
| | | class MaxStack
|
| | | {
|
| | | private:
|
| | | stack<T> max_stack;
|
| | | stack<T> _data;
|
| | |
|
| | | public:
|
| | | MaxStack(){};
|
| | | ~MaxStack(){};
|
| | |
|
| | |
|
| | | void push(T ele)
|
| | | {
|
| | | _data.push(ele);
|
| | | if(max_stack.empty() || ele>=max_stack.top())
|
| | | {
|
| | | max_stack.push(ele);
|
| | | }
|
| | | };
|
| | |
|
| | | void pop()
|
| | | {
|
| | | T tem = _data.top();
|
| | | _data.pop();
|
| | | if(tem==max_stack.top())
|
| | | {
|
| | | max_stack.pop();
|
| | | }
|
| | | };
|
| | |
|
| | | T top()
|
| | | {
|
| | | return _data.top();
|
| | |
|
| | | };
|
| | |
|
| | | bool isEmpty()
|
| | | {
|
| | | return _data.empty();
|
| | | };
|
| | |
|
| | | T maxItem()
|
| | | {
|
| | | return max_stack.top();
|
| | | };
|
| | |
|
| | | int size()
|
| | | {
|
| | | return _data.size();
|
| | | };
|
| | | };
|
| | |
|
| | |
|
| | | template <typename T>
|
| | | class MinStack
|
| | | {
|
| | | private:
|
| | | stack<T> min_stack;
|
| | | stack<T> _data;
|
| | |
|
| | | public:
|
| | | MinStack(){};
|
| | | ~MinStack(){};
|
| | |
|
| | | void push(T ele)
|
| | | {
|
| | | _data.push(ele);
|
| | | if(min_stack.empty() || ele<=min_stack.top())
|
| | | {
|
| | | min_stack.push(ele);
|
| | | }
|
| | | };
|
| | |
|
| | | void pop(){
|
| | | T tem = _data.top();
|
| | | _data.pop();
|
| | | if(tem==min_stack.top())
|
| | | {
|
| | | min_stack.pop();
|
| | | }
|
| | | };
|
| | |
|
| | | T top()
|
| | | {
|
| | | return _data.top();
|
| | |
|
| | | };
|
| | |
|
| | | bool isEmpty()
|
| | | {
|
| | | return _data.empty();
|
| | | };
|
| | |
|
| | | T minItem()
|
| | | {
|
| | | return min_stack.top();
|
| | | };
|
| | |
|
| | | int size()
|
| | | {
|
| | | return _data.size();
|
| | | };
|
| | | };
|
| | |
|
| | | #endif //INC_05_MAX_STACK_QUEUE_STACK_UTIL_H
|
| New file |
| | |
| | | //
|
| | | // Created by Scheaven on 2020/5/14.
|
| | | //
|
| | |
|
| | | #include "time_util.h"
|
| | |
|
| | | #include <stdio.h>
|
| | | #include <memory.h>
|
| | | #include <iostream>
|
| | | #include <ctime>
|
| | | #include <string>
|
| | | #include "stdlib.h"
|
| | | #include <sys/time.h>
|
| | | #include <time.h>
|
| | | #include <unistd.h>
|
| | |
|
| | | using namespace std;
|
| | |
|
| | | int get_run_time(struct timeval *result, struct timeval *begin, struct timeval * end)
|
| | | {
|
| | | if(begin->tv_sec > end->tv_sec) return -1;
|
| | | if((begin->tv_sec == end->tv_sec) && (begin->tv_usec > end->tv_usec)) return -2;
|
| | | result->tv_sec = end->tv_sec - begin->tv_sec;
|
| | | result->tv_usec = end->tv_usec - begin->tv_usec;
|
| | |
|
| | | if(result->tv_usec<0)
|
| | | {
|
| | | result->tv_sec--;
|
| | | result->tv_usec += 1000000;
|
| | | }
|
| | | return 0;
|
| | | }
|
| | |
|
| | | time_t strTime2unix(char* timeStamp)
|
| | | {
|
| | | struct tm tm;
|
| | | memset(&tm, 0, sizeof(tm));
|
| | |
|
| | | sscanf(timeStamp, "%d-%d-%d %d:%d:%d",
|
| | | &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
|
| | | &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
|
| | |
|
| | | tm.tm_year -= 1900;
|
| | | tm.tm_mon--;
|
| | |
|
| | | return mktime(&tm);
|
| | | }
|
| | |
|
| | | long char_2_unix(char* str1)
|
| | | {
|
| | | char str[100];
|
| | | // std::cout<< "==char_2_unix=%s:" << str1<< std::endl;
|
| | |
|
| | | strcpy(str, str1);
|
| | | const char *mySplit = ".";
|
| | | char *p;
|
| | | char *p1;
|
| | | char *p2;
|
| | |
|
| | | p1 = strtok(str, mySplit);
|
| | | p2 = strtok(NULL, mySplit);
|
| | | // std::cout<< "--p1=:" << p1 << " : " << p2 << std::endl;
|
| | | time_t t = strTime2unix(p1);
|
| | |
|
| | | // std::cout<< "char_2_unix=t=%s:" << t << std::endl;
|
| | | return t*1000+atoi(p2);
|
| | | }
|
| | |
|
| | |
|
| | | char* fa_getSysTime()
|
| | | {
|
| | | struct timeval tv;
|
| | | gettimeofday(&tv,NULL);
|
| | | struct tm* pTime;
|
| | | pTime = localtime(&tv.tv_sec);
|
| | |
|
| | | static char sTemp[30] = "0";
|
| | | snprintf(sTemp, sizeof(sTemp), "%04d-%02d-%02d %02d:%02d:%02d:%03d", pTime->tm_year+1900, \
|
| | | pTime->tm_mon+1, pTime->tm_mday, pTime->tm_hour, pTime->tm_min, pTime->tm_sec, \
|
| | | tv.tv_usec/1000);
|
| | | char* TP = sTemp;
|
| | | return TP;
|
| | | }
|
| | |
|
| | | string random_int(size_t length)
|
| | | {
|
| | | long seed = (unsigned)time(NULL) + (unsigned)clock();
|
| | | srand(seed);
|
| | | auto randchar= []() ->char
|
| | | {
|
| | | const char charset[] = "0123456789";
|
| | | const size_t max_index = (sizeof(charset) - 1);
|
| | | return charset[rand()%max_index];
|
| | | };
|
| | | std::string str(length,0);
|
| | | std::generate_n(str.begin(),length,randchar);
|
| | | //SLOG::getInstance()->addLog(0, str + "------seed and id--init-----id:" + to_string(seed));
|
| | | return str;
|
| | | }
|
| | |
|
| | |
|
| | | Timer* Timer::instance = NULL;
|
| | | Timer* Timer::getInstance()
|
| | | {
|
| | | if (instance==NULL)
|
| | | {
|
| | | instance = new Timer();
|
| | | }
|
| | | return instance;
|
| | | }
|
| | |
|
| | | Timer::Timer():beg_(clock_::now()){}
|
| | | void Timer::reset()
|
| | | {
|
| | | beg_ = clock_::now();
|
| | | }
|
| | |
|
| | | double Timer::elapsed() const
|
| | | {
|
| | | return std::chrono::duration_cast<second_>(clock_::now() - beg_).count();
|
| | | }
|
| | |
|
| | | void Timer::out(std::string message)
|
| | | {
|
| | | double t = elapsed();
|
| | | // std::cout << message << " elasped time:" << t << "ms" << std::endl;
|
| | | DEBUG((boost::format("%e: %f ms")%message %t).str());
|
| | | reset();
|
| | | }
|
| | |
|
| | | double Timer::get_duration() const
|
| | | {
|
| | | return elapsed();
|
| | | }
|
| New file |
| | |
| | | //
|
| | | // Created by Scheaven on 2020/5/14.
|
| | | //
|
| | |
|
| | | #ifndef DEMO_TIME_UTIL_H
|
| | | #define DEMO_TIME_UTIL_H
|
| | |
|
| | | #include <sys/time.h>
|
| | | #include <cstdio>
|
| | | #include <time.h>
|
| | | #include <stdlib.h>
|
| | | #include <string>
|
| | | #include <algorithm>
|
| | | #include <sstream>
|
| | |
|
| | | int get_run_time(struct timeval *result, struct timeval *begin, struct timeval *end);
|
| | |
|
| | | time_t strTime2unix(char* timeStamp);
|
| | |
|
| | | long char_2_unix(char* str1);
|
| | |
|
| | | char* fa_getSysTime();
|
| | |
|
| | | std::string random_int(size_t length);
|
| | |
|
| | | #include <chrono>
|
| | | #include "log_util.h"
|
| | | #include <boost/format.hpp>
|
| | |
|
| | | class Timer
|
| | | {
|
| | | public:
|
| | | static Timer* instance;
|
| | | static Timer* getInstance();
|
| | |
|
| | | Timer();
|
| | | public:
|
| | | void reset();
|
| | | double elapsed() const;
|
| | | void out(std::string message="");
|
| | | // DEBUG((boost::format("nhao%d")%1).str());
|
| | | double get_duration() const;
|
| | | private:
|
| | | using clock_ = std::chrono::high_resolution_clock;
|
| | | using second_=std::chrono::duration<double,std::milli>;
|
| | | std::chrono::time_point<clock_>beg_;
|
| | | };
|
| | |
|
| | | #endif //DEMO_TIME_UTIL_H
|
| | |
| | | void out(std::string message="") |
| | | { |
| | | double t = elapsed(); |
| | | std::cout << message << " elasped time:" << t << "ms" << std::endl; |
| | | // DEBUG((boost::format("%e lasped time:%f ms")%message %t).str()); |
| | | // std::cout << message << " elasped time:" << t << "ms" << std::endl; |
| | | DEBUG((boost::format("%e lasped time:%f ms")%message %t).str()); |
| | | reset(); |
| | | } |
| | | // DEBUG((boost::format("nhao%d")%1).str()); |