diff --git a/.gitignore b/.gitignore index b96c2d79a..46378c895 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ build +.vscode CMakeLists.txt.user +.idea* +cmake-build-debug* +yolov3-urbantracker_13300.weights + +*.caffemodel +*.weights +data/videos/ +doc/ diff --git a/Build guide.docx b/Build guide.docx new file mode 100644 index 000000000..44aabbb58 Binary files /dev/null and b/Build guide.docx differ diff --git a/CMakeLists.txt b/CMakeLists.txt index 6652c4a46..ba639ed3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,80 @@ cmake_minimum_required(VERSION 2.8) project(MultitargetTracker) +################################################################################################ +# Short command for cuDNN detection. Believe it soon will be a part of CUDA toolkit distribution. +# That's why not FindcuDNN.cmake file, but just the macro +# Usage: +# detect_cuDNN() +function(detect_cuDNN) + set(CUDNN_ROOT "" CACHE PATH "CUDNN root folder") + + find_path(CUDNN_INCLUDE cudnn.h + PATHS ${CUDNN_ROOT} $ENV{CUDNN_ROOT} ${CUDA_TOOLKIT_INCLUDE} + PATH_SUFFIXES include + DOC "Path to cuDNN include directory." ) + + unset(_path_suffixes) + if(MSVC AND ${CMAKE_SIZEOF_VOID_P} EQUAL 8) + set(_path_suffixes PATH_SUFFIXES lib/x64) + else() + set(_path_suffixes PATH_SUFFIXES lib/Win32) + endif() + + # dynamic libs have different suffix in mac and linux + if(APPLE) + set(CUDNN_LIB_NAME "libcudnn.dylib") + elseif(MSVC) + set(CUDNN_LIB_NAME "cudnn") + else() + set(CUDNN_LIB_NAME "libcudnn.so") + endif() + + get_filename_component(__libpath_hist ${CUDA_CUDART_LIBRARY} PATH) + find_library(CUDNN_LIBRARY NAMES ${CUDNN_LIB_NAME} + PATHS ${CUDNN_ROOT} $ENV{CUDNN_ROOT} ${CUDNN_INCLUDE} ${__libpath_hist} ${__libpath_hist}/../lib + ${_path_suffixes} + DOC "Path to cuDNN library.") + + if(CUDNN_INCLUDE AND CUDNN_LIBRARY) + set(HAVE_CUDNN TRUE PARENT_SCOPE) + set(CUDNN_FOUND TRUE PARENT_SCOPE) + + file(READ ${CUDNN_INCLUDE}/cudnn.h CUDNN_VERSION_FILE_CONTENTS) + + # cuDNN v3 and beyond + string(REGEX MATCH "define CUDNN_MAJOR * +([0-9]+)" + CUDNN_VERSION_MAJOR "${CUDNN_VERSION_FILE_CONTENTS}") + string(REGEX REPLACE "define CUDNN_MAJOR * +([0-9]+)" "\\1" + CUDNN_VERSION_MAJOR "${CUDNN_VERSION_MAJOR}") + string(REGEX MATCH "define CUDNN_MINOR * +([0-9]+)" + CUDNN_VERSION_MINOR "${CUDNN_VERSION_FILE_CONTENTS}") + string(REGEX REPLACE "define CUDNN_MINOR * +([0-9]+)" "\\1" + CUDNN_VERSION_MINOR "${CUDNN_VERSION_MINOR}") + string(REGEX MATCH "define CUDNN_PATCHLEVEL * +([0-9]+)" + CUDNN_VERSION_PATCH "${CUDNN_VERSION_FILE_CONTENTS}") + string(REGEX REPLACE "define CUDNN_PATCHLEVEL * +([0-9]+)" "\\1" + CUDNN_VERSION_PATCH "${CUDNN_VERSION_PATCH}") + + if(NOT CUDNN_VERSION_MAJOR) + set(CUDNN_VERSION "???") + else() + set(CUDNN_VERSION "${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}") + endif() + + message(STATUS "Found cuDNN: ver. ${CUDNN_VERSION} found (include: ${CUDNN_INCLUDE}, library: ${CUDNN_LIBRARY})") + + string(COMPARE LESS "${CUDNN_VERSION_MAJOR}" 3 cuDNNVersionIncompatible) + if(cuDNNVersionIncompatible) + message(FATAL_ERROR "cuDNN version >3 is required.") + endif() + + set(CUDNN_VERSION "${CUDNN_VERSION}" PARENT_SCOPE) + mark_as_advanced(CUDNN_INCLUDE CUDNN_LIBRARY CUDNN_ROOT) + + endif() +endfunction() + unset(CMAKE_CXX_FLAGS CACHE) find_package(OpenMP) @@ -49,7 +123,11 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) Detector/pedestrians/c4-pedestrian-detector.cpp Detector/SSDMobileNetDetector.cpp Detector/YoloDetector.cpp - +### Custom code ########################################################### + Detector/SSDCustomNetDetector.cpp + Detector/gpu_allocator.cpp + Detector/SSD.cpp +########################################################################### Tracker/Ctracker.cpp Tracker/track.cpp Tracker/HungarianAlg/HungarianAlg.cpp @@ -78,7 +156,12 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) Detector/pedestrians/c4-pedestrian-detector.h Detector/SSDMobileNetDetector.h Detector/YoloDetector.h - +### Custom code ########################################################### + Detector/SSDCustomNetDetector.h + Detector/gpu_allocator.h + Detector/SSD.h + Detector/common.h +########################################################################### Tracker/Ctracker.h Tracker/track.h Tracker/HungarianAlg/HungarianAlg.h @@ -212,6 +295,35 @@ if(USE_OCV_BGFG) add_definitions(-DUSE_OCV_BGFG) endif(USE_OCV_BGFG) +option(USE_CAFFE "Use Specify Caffe library for Custom trained .caffemodel" OFF) + +if(USE_CAFFE) + find_package(CUDA) + detect_cuDNN() + + add_definitions(-DCAFFE_VERSION=1.0.0-rc3) + add_definitions(-DBOOST_ALL_NO_LIB) + add_definitions(-DUSE_CUDNN) + add_definitions(-DUSE_OPENCV) + add_definitions(-DOPENCV_VERSION=3) + add_definitions(-DCMAKE_WINDOWS_BUILD) + add_definitions(-DGLOG_NO_ABBREVIATED_SEVERITIES) + add_definitions("-DGOOGLE_GLOG_DLL_DECL=__declspec(dllimport)") + add_definitions("-DGOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS=__declspec(dllimport)") + + set(CAFFE_INCLUDE_DIR "" CACHE PATH "Caffe include directory") + set(CAFFE_LIBS_DIR "" CACHE PATH "Caffe library directory") + set(CAFFE_DEPENDENCIES_INCLUDE_DIR "" CACHE PATH "Caffe's dependencies include directory") + set(CAFFE_DEPENDENCIES_LIBS_DIR "" CACHE PATH "Caffe's dependencies directory") + set(PYTHON_LIBS_DIR "" CACHE PATH "Python library directory") + + INCLUDE_DIRECTORIES(${CAFFE_INCLUDE_DIR}) + INCLUDE_DIRECTORIES(${CAFFE_DEPENDENCIES_INCLUDE_DIR}) + INCLUDE_DIRECTORIES(${CAFFE_DEPENDENCIES_INCLUDE_DIR}/boost-1_61) + INCLUDE_DIRECTORIES(${CUDA_INCLUDE_DIRS}) + INCLUDE_DIRECTORIES(${CUDNN_INCLUDE}) +endif(USE_CAFFE) + # ---------------------------------------------------------------------------- # создаем проект # ---------------------------------------------------------------------------- @@ -237,13 +349,44 @@ endif(USE_OCV_BGFG) if (CMAKE_COMPILER_IS_GNUCXX) -set(LIBS - ${OpenCV_LIBS} -# iconv -) + set(LIBS + ${OpenCV_LIBS} + # iconv + ) else(CMAKE_COMPILER_IS_GNUCXX) -set(LIBS - ${OpenCV_LIBS} -) + if(USE_CAFFE) + set(LIBS + debug ${CAFFE_LIBS_DIR}/caffe-d.lib optimized ${CAFFE_LIBS_DIR}/caffe.lib + debug ${CAFFE_LIBS_DIR}/caffeproto-d.lib optimized ${CAFFE_LIBS_DIR}/caffeproto.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_system-vc140-mt-gd-1_61.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_system-vc140-mt-1_61.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_thread-vc140-mt-gd-1_61.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_thread-vc140-mt-1_61.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_filesystem-vc140-mt-gd-1_61.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_filesystem-vc140-mt-1_61.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_chrono-vc140-mt-gd-1_61.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_date_time-vc140-mt-1_61.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_date_time-vc140-mt-gd-1_61.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_chrono-vc140-mt-1_61.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_atomic-vc140-mt-gd-1_61.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_atomic-vc140-mt-1_61.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_python-vc140-mt-gd-1_61.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/boost_python-vc140-mt-1_61.lib + ${PYTHON_LIBS_DIR}/python35.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/glogd.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/glog.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/gflagsd.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/gflags.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/libprotobufd.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/libprotobuf.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/caffehdf5_hl_D.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/caffehdf5_hl.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/caffehdf5_D.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/caffehdf5.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/caffezlibd.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/caffezlib.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/lmdbd.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/lmdb.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/leveldbd.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/leveldb.lib + debug ${CAFFE_DEPENDENCIES_LIBS_DIR}/snappy_staticd.lib optimized ${CAFFE_DEPENDENCIES_LIBS_DIR}/snappy_static.lib + ${CAFFE_DEPENDENCIES_LIBS_DIR}/libopenblas.dll.a + ${CUDA_CUDART_LIBRARY} + ${CUDA_curand_LIBRARY} + ${CUDA_CUBLAS_LIBRARIES} + ${CUDNN_LIBRARY} + ${OpenCV_LIBS} + ntdll.lib + ) + else(USE_CAFFE) + set(LIBS + ${OpenCV_LIBS} + ) + endif() endif() TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIBS}) diff --git a/Detector/BaseDetector.cpp b/Detector/BaseDetector.cpp index 4e84bdd56..c069d8f6a 100644 --- a/Detector/BaseDetector.cpp +++ b/Detector/BaseDetector.cpp @@ -4,6 +4,7 @@ #include "PedestrianDetector.h" #include "SSDMobileNetDetector.h" #include "YoloDetector.h" +#include "SSDCustomNetDetector.h" /// /// \brief CreateDetector @@ -68,6 +69,10 @@ BaseDetector* CreateDetector( detector = new YoloDetector(collectPoints, gray); break; + case tracking::SSD_CustomNet: + detector = new SSDCustomNetDetector(collectPoints, gray); + break; + default: break; } diff --git a/Detector/SSD.cpp b/Detector/SSD.cpp new file mode 100644 index 000000000..dc1e7d2bb --- /dev/null +++ b/Detector/SSD.cpp @@ -0,0 +1,323 @@ +#include "SSD.h" + +#include +#include +#include +#if defined(_MSC_VER) +#include +#endif +#include + +using namespace caffe; +using std::string; + +SSD::SSD(const string& model_file, + const string& trained_file, + const string& mean_file, + const string& mean_value, + const string& label_file, + GPUAllocator* allocator, + float conf_threshold) + : allocator_(allocator), + conf_(conf_threshold) +{ + LOG(INFO) << conf_; + Caffe::set_mode(Caffe::GPU); + + /* Load the network. */ + net_ = std::make_shared>(model_file, TEST); + net_->CopyTrainedLayersFrom(trained_file); + + CHECK_EQ(net_->num_inputs(), 1) << "Network should have exactly one input."; + CHECK_EQ(net_->num_outputs(), 1) << "Network should have exactly one output."; + + Blob* input_layer = net_->input_blobs()[0]; + num_channels_ = input_layer->channels(); + CHECK(num_channels_ == 3 || num_channels_ == 1) + << "Input layer should have 1 or 3 channels."; + input_geometry_ = Size(input_layer->width(), input_layer->height()); + + /* Load the binaryproto mean file. */ + SetMean(mean_file, mean_value); + + /* Load labels. */ + LabelMap labelMap; +#if defined (_MSC_VER) // for MSC compiler binary flag needs to be specified + int fd; + _sopen_s(&fd, label_file.c_str(), O_RDONLY | O_BINARY, _SH_DENYNO, 0); +#else + int fd = open(filename, O_RDONLY); +#endif + CHECK_NE(fd, -1) << "Unable to open labels file " << label_file; + google::protobuf::io::FileInputStream fileInput(fd); + fileInput.SetCloseOnDelete(true); + CHECK(google::protobuf::TextFormat::Parse(&fileInput, &labelMap)) << "Parse failed from: " << label_file; + + for (int i = 0; i < labelMap.item_size(); ++i) + { + const LabelMapItem& item = labelMap.item(i); + labels_.push_back(item.display_name()); + } + + //////////////////////////////// + //Retrive labels + //////////////////////////////// + /*if (!labels_.empty()) + { + std::ofstream ostream("labels.txt"); + CHECK(ostream.is_open()) << "labels.txt isn't open"; + for (size_t i = 0; i < labels_.size(); ++i) + { + ostream << i << " " << labels_[i] << std::endl; + } + ostream.close(); + }*/ + + CHECK_EQ(labels_.size(), net_->layer_by_name("detection_out")->layer_param().detection_output_param().num_classes()) + << "Number of labels is different from the output layer's parameter."; +} + +static bool PairCompare(const std::pair& lhs, + const std::pair& rhs) +{ + return lhs.first > rhs.first; +} + +/* Return the indices of the top N values of vector v. */ +static std::vector Argmax(const std::vector< std::vector >& v, int N) +{ + std::vector< std::pair > pairs; + for (size_t i = 0; i < v.size(); ++i) + pairs.push_back(std::make_pair(v[i][1], i)); + std::partial_sort(pairs.begin(), pairs.begin() + N, pairs.end(), PairCompare); + + std::vector result; + for (int i = 0; i < N; ++i) + result.push_back(pairs[i].second); + return result; +} + +/* Return the top N predictions. */ +DetectedBBoxes SSD::Detect(const Mat& img, int N) +{ + Size frameSize(img.cols, img.rows); + std::vector< std::vector > output = Predict(img); + + N = N <= 0 ? output.size() : std::min(output.size(), N); + std::vector maxN = Argmax(output, N); + DetectedBBoxes detectedBoxes; + for (int i = 0; i < N; ++i) + { + int idx = maxN[i]; + detectedBoxes.emplace_back(output[idx], labels_[cvRound(output[idx][1])], frameSize); + } + + return detectedBoxes; +} + +Mat SSD::DetectAsMat(const Mat& img) +{ + std::vector< std::vector > output = Predict(img); + cv::Mat detections(output.size(), 7, CV_32F); + + int r = 0; + for (auto objInfo : output) + { + cv::Mat obj(1, objInfo.size(), CV_32F, objInfo.data()); + obj.copyTo(detections.row(r)); + r++; + } + + return detections; +} + +const std::vector& SSD::GetLabels() const +{ + return labels_; +} + +const std::string& SSD::GetLabel(size_t idx) const +{ + return labels_[idx]; +} + +const cv::Size& SSD::GetInputGeometry() const +{ + return input_geometry_; +} + +std::vector< std::vector > SSD::Predict(const Mat& img) +{ + Blob* input_layer = net_->input_blobs()[0]; + input_layer->Reshape(1, num_channels_, + input_geometry_.height, input_geometry_.width); + /* Forward dimension change to all layers. */ + net_->Reshape(); + + std::vector input_channels; + WrapInputLayer(&input_channels); + + Preprocess(img, &input_channels); + + net_->Forward(); + + /* Copy the output layer to a std::vector */ + Blob* output_layer = net_->output_blobs()[0]; + const float* result = output_layer->cpu_data(); + const int num_det = output_layer->height(); + std::vector< std::vector > detections; + for(int k = 0; k < num_det; ++k) + { + if(result[1] < conf_) + { + //Skip invalid detection. + result += 7; + continue; + } + vector detection(result, result + 7); + detections.push_back(detection); + result += 7; + } + + return detections; +} + +/* Load the mean file in binaryproto format. */ +void SSD::SetMean(const string& mean_file, const string& mean_value) +{ + Scalar channel_mean; + if (!mean_file.empty()) + { + BlobProto blob_proto; + ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto); + + /* Convert from BlobProto to Blob */ + Blob mean_blob; + mean_blob.FromProto(blob_proto); + CHECK_EQ(mean_blob.channels(), num_channels_) + << "Number of channels of mean file doesn't match input layer."; + + /* The format of the mean file is planar 32-bit float BGR or grayscale. */ + std::vector channels; + float *data = mean_blob.mutable_cpu_data(); + for (int i = 0; i < num_channels_; ++i) + { + /* Extract an individual channel. */ + Mat channel(mean_blob.height(), mean_blob.width(), CV_32FC1, data); + channels.push_back(channel); + data += mean_blob.height() * mean_blob.width(); + } + + /* Merge the separate channels into a single image. */ + Mat packed_mean; + merge(channels, packed_mean); + + /* Compute the global mean pixel value and create a mean image + * filled with this value. */ + channel_mean = mean(packed_mean); + Mat host_mean = Mat(input_geometry_, packed_mean.type(), channel_mean); + mean_.upload(host_mean); + } + if (!mean_value.empty()) + { + CHECK(mean_file.empty()) << "Cannot specify mean_file and mean_value at the same time"; + stringstream ss(mean_value); + vector values; + string item; + while (getline(ss, item, ',')) + { + float value = std::atof(item.c_str()); + values.push_back(value); + } + CHECK(values.size() == 1 || values.size() == num_channels_) << "Specify either 1 mean_value or as many as channels: " << num_channels_; + + std::vector channels; + for (int i = 0; i < num_channels_; ++i) + { + /* Extract an individual channel. */ + Mat channel(input_geometry_.height, input_geometry_.width, CV_32FC1, Scalar(values[i])); + channels.push_back(channel); + } + + Mat packed_mean; + merge(channels, packed_mean); + + mean_.upload(packed_mean); + } +} + +/* Wrap the input layer of the network in separate GpuMat objects + * (one per channel). This way we save one memcpy operation and we + * don't need to rely on cudaMemcpy2D. The last preprocessing + * operation will write the separate channels directly to the input + * layer. */ +void SSD::WrapInputLayer(std::vector* input_channels) +{ + Blob* input_layer = net_->input_blobs()[0]; + + int width = input_layer->width(); + int height = input_layer->height(); + float* input_data = input_layer->mutable_gpu_data(); + for (int i = 0; i < input_layer->channels(); ++i) + { + GpuMat channel(height, width, CV_32FC1, input_data); + input_channels->push_back(channel); + input_data += width * height; + } +} + +void SSD::Preprocess(const Mat& host_img, + std::vector* input_channels) +{ + GpuMat img(host_img, allocator_); + /* Convert the input image to the input image format of the network. */ + GpuMat sample(allocator_); + +#if (CV_MAJOR_VERSION > 3) + if (img.channels() == 3 && num_channels_ == 1) + cuda::cvtColor(img, sample, COLOR_BGR2GRAY); + else if (img.channels() == 4 && num_channels_ == 1) + cuda::cvtColor(img, sample, COLOR_BGR2GRAY); + else if (img.channels() == 4 && num_channels_ == 3) + cuda::cvtColor(img, sample, COLOR_BGRA2BGR); + else if (img.channels() == 1 && num_channels_ == 3) + cuda::cvtColor(img, sample, COLOR_GRAY2BGR); + else + sample = img; +#else + if (img.channels() == 3 && num_channels_ == 1) + cuda::cvtColor(img, sample, CV_BGR2GRAY); + else if (img.channels() == 4 && num_channels_ == 1) + cuda::cvtColor(img, sample, CV_BGRA2GRAY); + else if (img.channels() == 4 && num_channels_ == 3) + cuda::cvtColor(img, sample, CV_BGRA2BGR); + else if (img.channels() == 1 && num_channels_ == 3) + cuda::cvtColor(img, sample, CV_GRAY2BGR); + else + sample = img; +#endif + + GpuMat sample_resized(allocator_); + if (sample.size() != input_geometry_) + cuda::resize(sample, sample_resized, input_geometry_); + else + sample_resized = sample; + + GpuMat sample_float(allocator_); + if (num_channels_ == 3) + sample_resized.convertTo(sample_float, CV_32FC3); + else + sample_resized.convertTo(sample_float, CV_32FC1); + + GpuMat sample_normalized(allocator_); + cuda::subtract(sample_float, mean_, sample_normalized); + + /* This operation will write the separate BGR planes directly to the + * input layer of the network because it is wrapped by the GpuMat + * objects in input_channels. */ + cuda::split(sample_normalized, *input_channels); + + CHECK(reinterpret_cast(input_channels->at(0).data) + == net_->input_blobs()[0]->gpu_data()) + << "Input channels are not wrapping the input layer of the network."; +} \ No newline at end of file diff --git a/Detector/SSD.h b/Detector/SSD.h new file mode 100644 index 000000000..6d315ef7d --- /dev/null +++ b/Detector/SSD.h @@ -0,0 +1,188 @@ +#ifndef SSD_H +#define SSD_H + +#include +#include +#include +#include + +#define USE_CUDNN 1 +#include +#include +#include +#include + +#include "gpu_allocator.h" + +/** + * @brief Bounding Box class + * + * Saving a object's information from SSD + * @author Shinung + */ +class BBox +{ +public: + + BBox() { } + + /** + * Constructor to parse a information from SSD + * + * 0 | 1 | 2 | 3 | 4 | 5 | 6 + * image_id | label | score | xmin | ymin | xmax | ymax + * + * @param info A object's information + * @param label A object label + * @param frameSize image size for getting top-left and bottom-right coordinate with information + * @author Shinung + */ + BBox(const std::vector& info, const std::string& label, const Size& frameSize) + { + mBox = Rect(Point(cvRound(info[3] * frameSize.width), cvRound(info[4] * frameSize.height)), + Point(cvRound(info[5] * frameSize.width), cvRound(info[6] * frameSize.height))); + + mCenter = Point(cvRound((mBox.br().x + mBox.tl().x) / 2.f), cvRound((mBox.br().y + mBox.tl().y) / 2.f)); + + mConf = info[2]; + + mLabel = std::make_pair(cvRound(info[1]), label); + } + BBox(const BBox& other) + { + mBox = other.mBox; + mCenter = other.mCenter; + mConf = other.mConf; + mLabel = other.mLabel; + } + BBox(const BBox&& rhs) + { + mBox = rhs.mBox; + mCenter = rhs.mCenter; + mConf = rhs.mConf; + mLabel = rhs.mLabel; + } + + BBox& operator=(const BBox& rhs) + { + if (this == &rhs) + { + return *this; + } + + mBox = rhs.mBox; + mCenter = rhs.mCenter; + mConf = rhs.mConf; + mLabel = rhs.mLabel; + + return *this; + } + +public: + Rect mBox; /**< A rect of object */ + Point mCenter; /**< Center coord of rect */ + float mConf; /**< Confidence(score) */ + std::pair mLabel; /**< Object label */ +}; + +/** + * Container for BBox + * @author Shinung + */ +typedef std::vector DetectedBBoxes; + +class SSD +{ +public: + + /** + * @brief SSD Constructor + * @param model_file deploy prototxt path + * @param trained_file caffemodel prototxt path + * @param mean_file "" or mean binaryproto file path + * @param mean_value "104,117,123" - Use this parameter if not having a mean file + * @param label_file labelmap prototxt path + * @param allocator Instance of GPUAllocator + * @param iou_threshold IOU threshold value + * @param ios_threshold IOS threshold value + * @param conf_threshold Confidence threshold value + */ + SSD(const std::string& model_file, + const std::string& trained_file, + const std::string& mean_file, + const std::string& mean_value, + const std::string& label_file, + GPUAllocator* allocator, + float conf_threshold); + + /** + * @brief Forwarding SSD with a image + * + * This function is not used with MultiTarget-Tracker due to return type + * The reason why I didn't overloading is to follow [popetv's coding standards](https://docs.google.com/document/d/1cT8EPgMXe0eopeHvwuFmbHG4TJr5kUmcovkr5irQZmo/edit#heading=h.r5zmbif4dbnf) + * I love his coding philosophy personally + * + * @since [forked GRE/SSD.h](https://github.com/Shinung/gpu-rest-engine/blob/ssd_gre/caffe_ssd/SSD.h) + * @param img Decoding image to cv::Mat + * @param N Limit number of detecting objects + * @return DetectedBBoxes + * @author Shinung + */ + virtual DetectedBBoxes Detect(const Mat& img, int N = 5); + + /** + * @brief Forwarding SSD with a image + * @param img Decoding image to cv::Mat + * @return cv::Mat that has raw results from SSD instead of DetectedBBoxes + * @author Shinung + */ + virtual Mat DetectAsMat(const Mat& img); + + /** + * @brief Return all labels + * @return std::vector of labels + * @author Shinung + */ + const std::vector& GetLabels() const; + + /** + * @brief Return a label by index + * @return label string + * @author Shinung + */ + const std::string& GetLabel(size_t idx) const; + + /** + * @return Size of input layer of SSD + * @author Shinung + */ + const cv::Size& GetInputGeometry() const; + +protected: + std::vector< std::vector > Predict(const Mat& img); + +private: + void SetMean(const std::string& mean_file, const std::string& mean_value); + + void WrapInputLayer(std::vector* input_channels); + + void Preprocess(const Mat& img, + std::vector* input_channels); + +private: + + /** + * @see gpu_allocator.h + * @author Shinung + */ + GPUAllocator* allocator_; + std::shared_ptr> net_; + Size input_geometry_; + int num_channels_; + GpuMat mean_; + std::vector labels_; + + float conf_; +}; + +#endif \ No newline at end of file diff --git a/Detector/SSDCustomNetDetector.cpp b/Detector/SSDCustomNetDetector.cpp new file mode 100644 index 000000000..f026f814d --- /dev/null +++ b/Detector/SSDCustomNetDetector.cpp @@ -0,0 +1,341 @@ +#include "SSDCustomNetDetector.h" +#include "nms.h" +#include "common.h" +#include "SSD.h" + +//#define NONCROP + +using namespace caffe; +using std::string; + +/** + * By using Go as the HTTP server, we have potentially more CPU threads than + * available GPUs and more threads can be added on the fly by the Go + * runtime. Therefore we cannot pin the CPU threads to specific GPUs. Instead, + * when a CPU thread is ready for inference it will try to retrieve an + * execution context from a queue of available GPU contexts and then do a + * cudaSetDevice() to prepare for execution. Multiple contexts can be allocated + * per GPU. - From [NVIDIA/gpu-rest-engine](https://github.com/NVIDIA/gpu-rest-engine) + * + * @see + * @see forked: + * @author Shinung + */ +class ExecContext +{ +public: + friend ScopedContext; + + static bool IsCompatible(int device) + { + cudaError_t st = cudaSetDevice(device); + if (st != cudaSuccess) + return false; + + cuda::DeviceInfo info; + if (!info.isCompatible()) + return false; + + return true; + } + + ExecContext(const string& model_file, + const string& trained_file, + const string& mean_file, + const string& mean_value, + const string& label_file, + float conf_threshold, + int device) + : device_(device) + { + cudaError_t st = cudaSetDevice(device_); + if (st != cudaSuccess) + throw std::invalid_argument("could not set CUDA device"); + + allocator_.reset(new GPUAllocator(1024 * 1024 * 128)); + caffe_context_.reset(new Caffe); + Caffe::Set(caffe_context_.get()); + detector_.reset(new SSD(model_file, trained_file, + mean_file, mean_value, + label_file, + allocator_.get(), + conf_threshold)); + + Caffe::Set(nullptr); + } + + SSD* CaffeClassifier() + { + return detector_.get(); + } + +private: + void Activate() + { + cudaError_t st = cudaSetDevice(device_); + if (st != cudaSuccess) + throw std::invalid_argument("could not set CUDA device"); + allocator_->reset(); + Caffe::Set(caffe_context_.get()); + } + + void Deactivate() + { + Caffe::Set(nullptr); + } + +private: + int device_; + std::unique_ptr allocator_; + std::unique_ptr caffe_context_; + std::unique_ptr detector_; +}; + +struct CustomSSD_ctx +{ + ContextPool pool; +}; + +/** + * Currently, 2 execution contexts are created per GPU. In other words, 2 + * inference tasks can execute in parallel on the same GPU. This helps improve + * GPU utilization since some kernel operations of inference will not fully use + * the GPU. From [NVIDIA/gpu-rest-engine](https://github.com/NVIDIA/gpu-rest-engine) + * + * @author Shinung + */ +constexpr static int kContextsPerDevice = 2; + +/// \brief SSDCustomNetDetector::SSDMobileNetDetector +/// \param collectPoints +/// \param gray +/// +SSDCustomNetDetector::SSDCustomNetDetector( + bool collectPoints, + cv::UMat& colorFrame +) + : + BaseDetector(collectPoints, colorFrame), + m_WHRatio(1.f), + m_inScaleFactor(0.007843f), + m_confidenceThreshold(0.5f), + m_maxCropRatio(2.0f) +{ +} + +/// +/// \brief SSDMobileNetDetector::~SSDMobileNetDetector +/// +SSDCustomNetDetector::~SSDCustomNetDetector(void) +{ + delete mCTX; +} + +bool SSDCustomNetDetector::Init(const config_t& config) +{ + auto confidenceThreshold = config.find("confidenceThreshold"); + if (confidenceThreshold != config.end()) + { + m_confidenceThreshold = std::stof(confidenceThreshold->second); + } + + auto maxCropRatio = config.find("maxCropRatio"); + if (maxCropRatio != config.end()) + { + m_maxCropRatio = std::stof(maxCropRatio->second); + if (m_maxCropRatio < 1.f) + { + m_maxCropRatio = 1.f; + } + } + + try + { + int device_count; + cudaError_t st = cudaGetDeviceCount(&device_count); + if (st != cudaSuccess) + { + throw std::invalid_argument("could not list CUDA devices"); + } + + ContextPool pool; + for (int dev = 0; dev < device_count; ++dev) + { + if (!ExecContext::IsCompatible(dev)) + { + LOG(ERROR) << "Skipping device: " << dev; + continue; + } + + for (int i = 0; i < kContextsPerDevice; ++i) + { + std::unique_ptr context( + new ExecContext( + config.find("modelConfiguration")->second, + config.find("modelBinary")->second, + "", + config.find("meanValue")->second, + config.find("labelMap")->second, + m_confidenceThreshold, + dev + ) + ); + pool.Push(std::move(context)); + } + } + + if (pool.Size() == 0) + { + throw std::invalid_argument("no suitable CUDA device"); + } + mCTX = new CustomSSD_ctx{ std::move(pool) }; + + { + ScopedContext context(mCTX->pool); + SSD* ssd = static_cast(context->CaffeClassifier()); + InWidth = ssd->GetInputGeometry().width; + InHeight = ssd->GetInputGeometry().height; + } + + /* Successful CUDA calls can set errno. */ + errno = 0; + return true; + } + catch (const std::invalid_argument& ex) + { + LOG(ERROR) << "exception: " << ex.what(); + errno = EINVAL; + return false; + } +} + +void SSDCustomNetDetector::Detect(cv::UMat& colorFrame) +{ + m_regions.clear(); + + regions_t tmpRegions; + + cv::Mat colorMat = colorFrame.getMat(cv::ACCESS_READ); + +#ifdef NONCROP + cv::Rect crop(0, 0, colorMat.cols, colorMat.rows); + DetectInCrop(colorMat, crop, tmpRegions); +#else + int cropHeight = cvRound(m_maxCropRatio * InHeight); + int cropWidth = cvRound(m_maxCropRatio * InWidth); + + if (colorFrame.cols / (float)colorFrame.rows > m_WHRatio) + { + if (m_maxCropRatio <= 0 || cropHeight >= colorFrame.rows) + { + cropHeight = colorFrame.rows; + } + cropWidth = cvRound(cropHeight * m_WHRatio); + } + else + { + if (m_maxCropRatio <= 0 || cropWidth >= colorFrame.cols) + { + cropWidth = colorFrame.cols; + } + cropHeight = cvRound(colorFrame.cols / m_WHRatio); + } + + cv::Rect crop(0, 0, cropWidth, cropHeight); + + for (; crop.y < colorMat.rows; crop.y += crop.height / 2) + { + bool needBreakY = false; + if (crop.y + crop.height >= colorMat.rows) + { + crop.y = colorMat.rows - crop.height; + needBreakY = true; + } + for (crop.x = 0; crop.x < colorMat.cols; crop.x += crop.width / 2) + { + bool needBreakX = false; + if (crop.x + crop.width >= colorMat.cols) + { + crop.x = colorMat.cols - crop.width; + needBreakX = true; + } + + DetectInCrop(colorMat, crop, tmpRegions); + + if (needBreakX) + { + break; + } + } + if (needBreakY) + { + break; + } + } +#endif + + nms3(tmpRegions, m_regions, 0.4f, + [](const CRegion& reg) -> cv::Rect { return reg.m_rect; }, + [](const CRegion& reg) -> float { return reg.m_confidence; }, + [](const CRegion& reg) -> std::string { return reg.m_type; }, + 0, 0.f); + + if (m_collectPoints) + { + for (auto& region : m_regions) + { + CollectPoints(region); + } + } +} + +/// +/// \brief SSDCustomNetDetector::DetectInCrop +/// \param colorFrame +/// \param crop +/// \param tmpRegions +/// +void SSDCustomNetDetector::DetectInCrop(cv::Mat colorFrame, const cv::Rect& crop, regions_t& tmpRegions) +{ + // get ssd instance from the pool + ScopedContext context(mCTX->pool); + SSD* ssd = static_cast(context->CaffeClassifier()); + + cv::Mat detectionMat = ssd->DetectAsMat(cv::Mat(colorFrame, crop)); + + for (int i = 0; i < detectionMat.rows; ++i) + { + float confidence = detectionMat.at(i, 2); + + if (confidence > m_confidenceThreshold) + { + size_t objectClass = (size_t)(detectionMat.at(i, 1)); + +#ifdef NONCROP + int xLeftBottom = cvRound(detectionMat.at(i, 3) * crop.width); + int yLeftBottom = cvRound(detectionMat.at(i, 4) * crop.height); + int xRightTop = cvRound(detectionMat.at(i, 5) * crop.width); + int yRightTop = cvRound(detectionMat.at(i, 6) * crop.height); +#else + int xLeftBottom = cvRound(detectionMat.at(i, 3) * crop.width) + crop.x; + int yLeftBottom = cvRound(detectionMat.at(i, 4) * crop.height) + crop.y; + int xRightTop = cvRound(detectionMat.at(i, 5) * crop.width) + crop.x; + int yRightTop = cvRound(detectionMat.at(i, 6) * crop.height) + crop.y; + + if (xLeftBottom < 0 || yLeftBottom < 0 || xRightTop < 0 || yRightTop < 0) + { + continue; + } +#endif + CHECK_LE(0, xLeftBottom) << "raw: " << detectionMat.at(i, 3); + CHECK_LE(0, yLeftBottom) << "raw: " << detectionMat.at(i, 4); + CHECK_LE(0, xRightTop) << "raw: " << detectionMat.at(i, 5); + CHECK_LE(0, yRightTop) << "raw: " << detectionMat.at(i, 6); + + cv::Rect object(cv::Point(xLeftBottom, yLeftBottom), cv::Point(xRightTop, yRightTop)); + + tmpRegions.push_back(CRegion(object, ssd->GetLabel(objectClass), confidence)); + } + } +} + diff --git a/Detector/SSDCustomNetDetector.h b/Detector/SSDCustomNetDetector.h new file mode 100644 index 000000000..7290db7f8 --- /dev/null +++ b/Detector/SSDCustomNetDetector.h @@ -0,0 +1,77 @@ +#pragma once + +#include "BaseDetector.h" + +/** + * @brief Detector class for custom caffe-ssd net + * + * This class was implemented to refer NVIDIA Gpu Rest Engine code + * + * @see [forked GRE branch](https://github.com/Shinung/gpu-rest-engine/tree/ssd_gre/caffe_ssd) + * @author Shinung + */ +class SSDCustomNetDetector : public BaseDetector +{ + typedef struct CustomSSD_ctx CustomSSD_ctx; + +public: + SSDCustomNetDetector(bool collectPoints, cv::UMat& colorFrame); + ~SSDCustomNetDetector(); + + /** + * @brief Initialize Detector and SSD net + * + * This function was implemented to refer NVIDIA GRE code. + * + * @param config Setted values in CustomSSDMobileNetExample::InitTracker + * @see Reference [code](https://github.com/Shinung/gpu-rest-engine/blob/ssd_gre/caffe_ssd/detection.cpp) + * @author Shinung + */ + virtual bool Init(const config_t& config) override; + + /** + * @brief Detecting with SSD net + * + * Forwarding SSD net with cropped gray images. + * + * @param [in] colorFrame Always input gray scale image in this parameter + * because CustomSSDMobileNetExample::GrayProcessing return only TRUE + */ + virtual void Detect(cv::UMat& colorFrame) override; + +private: + + /** + * @brief Making cropped images and fowarding SSD net + * + * @param [in] colorFrame + * @param [in] crop + * @param [out] tmpRegions + * @todo It can be bottleneck with big image + * I think to improve process time if each cropped image forward to SSD net, + * which live in context pool + * @see [detection_inference function - 149 line](https://github.com/Shinung/gpu-rest-engine/blob/ssd_gre/caffe_ssd/detection.cpp) + * @author Shinung + */ + void DetectInCrop(cv::Mat colorFrame, const cv::Rect& crop, regions_t& tmpRegions); + +private: + /** + * @brief A struct of ContextPool + * + * I just followed [NVIDIA GRE](https://github.com/NVIDIA/gpu-rest-engine) codes + * although It's not necessary for multi-threads logic in here. + * + * @see common.h + * @author Shinung + */ + CustomSSD_ctx* mCTX; + + int InWidth; + int InHeight; + float m_WHRatio; + float m_inScaleFactor; + float m_confidenceThreshold; + float m_maxCropRatio; + std::vector m_classNames; /**< Container for objects label */ +}; \ No newline at end of file diff --git a/Detector/YoloDetector.cpp b/Detector/YoloDetector.cpp index 23ac8cde1..5bb1e5178 100644 --- a/Detector/YoloDetector.cpp +++ b/Detector/YoloDetector.cpp @@ -190,7 +190,8 @@ void YoloDetector::DetectInCrop(cv::Mat colorFrame, const cv::Rect& crop, region m_net.setInput(inputBlob, "data"); //set the network input #if (CV_VERSION_MAJOR < 4) - cv::String outputName = "detection_out"; + // cv::String outputName = "detection_out"; + cv::String outputName = cv::String(); #else cv::String outputName = cv::String(); #endif diff --git a/Detector/common.h b/Detector/common.h new file mode 100644 index 000000000..255e26801 --- /dev/null +++ b/Detector/common.h @@ -0,0 +1,82 @@ +#ifndef COMMON_H +#define COMMON_H + +#include +#include +#include +#include + +/**< A simple threadsafe queue using a mutex and a condition variable. */ +template +class Queue +{ +public: + Queue() = default; + + Queue(Queue&& other) + { + std::unique_lock lock(other.mutex_); + queue_ = std::move(other.queue_); + } + + void Push(T value) + { + std::unique_lock lock(mutex_); + queue_.push(std::move(value)); + lock.unlock(); + cond_.notify_one(); + } + + T Pop() + { + std::unique_lock lock(mutex_); + cond_.wait(lock, [this]{return !queue_.empty();}); + T value = std::move(queue_.front()); + queue_.pop(); + return value; + } + + size_t Size() + { + std::unique_lock lock(mutex_); + return queue_.size(); + } + +private: + mutable std::mutex mutex_; + std::queue queue_; + std::condition_variable cond_; +}; + +/**< A pool of available contexts is simply implemented as a queue for our example. */ +template +using ContextPool = Queue>; + +/**< A RAII class for acquiring an execution context from a context pool. */ +template +class ScopedContext +{ +public: + explicit ScopedContext(ContextPool& pool) + : pool_(pool), context_(pool_.Pop()) + { + context_->Activate(); + } + + ~ScopedContext() + { + context_->Deactivate(); + pool_.Push(std::move(context_)); + } + + Context* operator->() const + { + return context_.get(); + } + +private: + ContextPool& pool_; + std::unique_ptr context_; +}; + +#endif // COMMON_H diff --git a/Detector/gpu_allocator.cpp b/Detector/gpu_allocator.cpp new file mode 100644 index 000000000..b6eb2051b --- /dev/null +++ b/Detector/gpu_allocator.cpp @@ -0,0 +1,69 @@ +#include "gpu_allocator.h" + +#include +#include +#include + +// Page offset on Kepler/Maxwell +#define ALIGNMENT (128*1024) + +GPUAllocator::GPUAllocator(size_t size) + : total_size_(size), + current_size_(0) +{ + cudaError_t rc = cudaMalloc(&base_ptr_, total_size_); + if (rc != cudaSuccess) + throw std::runtime_error("Could not allocate GPU memory"); + + current_ptr_ = base_ptr_; +} + +GPUAllocator::~GPUAllocator() +{ + cudaFree(base_ptr_); +} + +static int align_up(unsigned int v, unsigned int alignment) +{ + return ((v + alignment - 1) / alignment) * alignment; +} + +cudaError_t GPUAllocator::grow(void** dev_ptr, size_t size) +{ + if (current_size_ + size >= total_size_) + return cudaErrorMemoryAllocation; + + *dev_ptr = current_ptr_; + size_t aligned_size = align_up(size, ALIGNMENT); + current_ptr_ = (char*)current_ptr_ + aligned_size; + current_size_ += aligned_size; + + return cudaSuccess; +} + +void GPUAllocator::reset() +{ + current_ptr_ = base_ptr_; + current_size_ = 0; +} + +bool GPUAllocator::allocate(cv::cuda::GpuMat* mat, int rows, int cols, size_t elemSize) +{ + int padded_width = align_up(cols, 16); + int padded_height = align_up(rows, 16); + int total_size = elemSize * padded_width * padded_height; + + cudaError_t status = grow((void**)&mat->data, total_size); + if (status != cudaSuccess) + return false; + + mat->step = padded_width * elemSize; + mat->refcount = new int; + + return true; +} + +void GPUAllocator::free(cv::cuda::GpuMat* mat) +{ + delete mat->refcount; +} diff --git a/Detector/gpu_allocator.h b/Detector/gpu_allocator.h new file mode 100644 index 000000000..b876e9a8e --- /dev/null +++ b/Detector/gpu_allocator.h @@ -0,0 +1,44 @@ +#ifndef GPU_ALLOCATOR_H +#define GPU_ALLOCATOR_H + +#include +#include +#include + +using GpuMat = cv::cuda::GpuMat; +using namespace cv; + +/** + * A simple linear allocator class to allocate storage for cv::GpuMat objects. + * This feature was added in OpenCV 3.0. + */ +class GPUAllocator : public GpuMat::Allocator +{ +public: + GPUAllocator(size_t size); + + ~GPUAllocator(); + + void reset(); + +public: + /** + * @name GpuMat::Allocator interface + */ + ///@{ + bool allocate(GpuMat* mat, int rows, int cols, size_t elemSize); + + void free(GpuMat* mat); + ///@} + +private: + cudaError_t grow(void** dev_ptr, size_t size); + +private: + void* base_ptr_; + void* current_ptr_; + size_t total_size_; + size_t current_size_; +}; + +#endif // GPU_ALLOCATOR_H diff --git a/Tracker/Kalman.cpp b/Tracker/Kalman.cpp index 06feefd20..a37fc1471 100644 --- a/Tracker/Kalman.cpp +++ b/Tracker/Kalman.cpp @@ -566,6 +566,14 @@ cv::Rect TKalmanFilter::GetRectPrediction() { } + + if (m_lastRectResult.height < .0f) + { + std::cout << m_lastRectResult << std::endl; + std::cout << cv::Rect(static_cast(m_lastRectResult.x), static_cast(m_lastRectResult.y), static_cast(m_lastRectResult.width), static_cast(m_lastRectResult.height)) + << std::endl; + } + return cv::Rect(static_cast(m_lastRectResult.x), static_cast(m_lastRectResult.y), static_cast(m_lastRectResult.width), static_cast(m_lastRectResult.height)); } diff --git a/Tracker/track.cpp b/Tracker/track.cpp index 40021527c..65b9d8cb5 100644 --- a/Tracker/track.cpp +++ b/Tracker/track.cpp @@ -274,13 +274,6 @@ cv::Rect CTrack::GetLastRect() const } } -/// -/// \brief RectUpdate -/// \param region -/// \param dataCorrect -/// \param prevFrame -/// \param currFrame -/// void CTrack::RectUpdate( const CRegion& region, bool dataCorrect, @@ -294,23 +287,75 @@ void CTrack::RectUpdate( auto Clamp = [](int& v, int& size, int hi) -> bool { - if (size < 2) - { - size = 2; - } + if (size < 2) + { + size = 2; + } + else if (v + size > hi - 1) + { + //v = hi - 1 - size; + size = hi - 1 - v; + return true; + } + if (v < 0) { v = 0; return true; } - else if (v + size > hi - 1) - { - v = hi - 1 - size; - return true; - } return false; }; + auto ClampWithRect = [](const cv::Point& rTopLeft, const cv::Size& rSize, const cv::Size& frameSize) -> cv::Rect + { + int x = rTopLeft.x; + int y = rTopLeft.y; + int w = rSize.width; + int h = rSize.height; + + if (w < 2) + { + w = 2; + } + + if (x < 0) + { + x = 0; + } + + if (x + w > frameSize.width - 1) + { + x = frameSize.width - 1 - w; + if (x < 0) + { + x = 0; + w = frameSize.width - 1; + } + } + + if (h < 2) + { + h = 2; + } + + if (y < 0) + { + y = 0; + } + + if (y + h > frameSize.height - 1) + { + y = frameSize.height - 1 - h; + if (y < 0) + { + y = 0; + h = frameSize.height - 1; + } + } + + return cv::Rect(x, y, w, h); + }; + switch (m_externalTrackerForLost) { case tracking::TrackNone: @@ -324,82 +369,92 @@ void CTrack::RectUpdate( #ifdef USE_OCV_KCF if (!dataCorrect) { - cv::Size roiSize(std::max(2 * m_predictionRect.width, currFrame.cols / 4), std::min(2 * m_predictionRect.height, currFrame.rows / 4)); - if (roiSize.width > currFrame.cols) - { - roiSize.width = currFrame.cols; - } - if (roiSize.height > currFrame.rows) - { - roiSize.height = currFrame.rows; - } - cv::Point roiTL(m_predictionRect.x + m_predictionRect.width / 2 - roiSize.width / 2, m_predictionRect.y + m_predictionRect.height / 2 - roiSize.height / 2); - cv::Rect roiRect(roiTL, roiSize); + //cv::Size roiSize(std::max(2 * m_predictionRect.width, currFrame.cols / 4), std::min(2 * m_predictionRect.height, currFrame.rows / 4)); + cv::Size roiSize = checkSize(std::max(2 * m_predictionRect.width, currFrame.cols / 4), + std::min(2 * m_predictionRect.height, currFrame.rows / 4), + cv::Size(currFrame.cols, currFrame.rows)); + //cv::Point roiTL(m_predictionRect.x + m_predictionRect.width / 2 - roiSize.width / 2, m_predictionRect.y + m_predictionRect.height / 2 - roiSize.height / 2); + cv::Point roiTL = checkSize(m_predictionRect.x + m_predictionRect.width / 2 - roiSize.width / 2, + m_predictionRect.y + m_predictionRect.height / 2 - roiSize.height / 2, + cv::Size(currFrame.cols, currFrame.rows)); + /*cv::Rect roiRect(roiTL, roiSize); Clamp(roiRect.x, roiRect.width, currFrame.cols); - Clamp(roiRect.y, roiRect.height, currFrame.rows); - - bool inited = false; - if (!m_tracker || m_tracker.empty()) - { - CreateExternalTracker(); - - cv::Rect2d lastRect(m_predictionRect.x - roiRect.x, m_predictionRect.y - roiRect.y, m_predictionRect.width, m_predictionRect.height); - if (m_staticFrame.empty()) - { - lastRect = cv::Rect2d(m_predictionRect.x - roiRect.x, m_predictionRect.y - roiRect.y, m_predictionRect.width, m_predictionRect.height); - } - else - { - lastRect = cv::Rect2d(m_staticRect.x - roiRect.x, m_staticRect.y - roiRect.y, m_staticRect.width, m_staticRect.height); - } - - if (lastRect.x >= 0 && - lastRect.y >= 0 && - lastRect.x + lastRect.width < roiRect.width && - lastRect.y + lastRect.height < roiRect.height && - lastRect.area() > 0) - { - if (m_staticFrame.empty()) - { - m_tracker->init(cv::UMat(prevFrame, roiRect), lastRect); - } - else - { - m_tracker->init(cv::UMat(m_staticFrame, roiRect), lastRect); - } + Clamp(roiRect.y, roiRect.height, currFrame.rows);*/ + cv::Rect roiRect = ClampWithRect(roiTL, roiSize, cv::Size(currFrame.cols, currFrame.rows)); + cv::Rect frameRect(0, 0, currFrame.cols, currFrame.rows); + + /*if (!frameRect.contains(roiRect.tl()) || frameRect.contains(roiRect.br())) + { + if (m_tracker && !m_tracker.empty()) + { + m_tracker.release(); + m_outOfTheFrame = true; + } + }*/ + + bool inited = false; + if (!m_tracker || m_tracker.empty()) + { + CreateExternalTracker(); + + cv::Rect2d lastRect(m_predictionRect.x - roiRect.x, m_predictionRect.y - roiRect.y, m_predictionRect.width, m_predictionRect.height); + if (m_staticFrame.empty()) + { + lastRect = cv::Rect2d(m_predictionRect.x - roiRect.x, m_predictionRect.y - roiRect.y, m_predictionRect.width, m_predictionRect.height); + } + else + { + lastRect = cv::Rect2d(m_staticRect.x - roiRect.x, m_staticRect.y - roiRect.y, m_staticRect.width, m_staticRect.height); + } + + if (lastRect.x >= 0 && + lastRect.y >= 0 && + lastRect.x + lastRect.width < roiRect.width && + lastRect.y + lastRect.height < roiRect.height && + lastRect.area() > 0) + { + if (m_staticFrame.empty()) + { + m_tracker->init(cv::UMat(prevFrame, roiRect), lastRect); + } + else + { + m_tracker->init(cv::UMat(m_staticFrame, roiRect), lastRect); + } #if 0 - cv::Mat tmp = cv::UMat(prevFrame, roiRect).getMat(cv::ACCESS_READ).clone(); - cv::rectangle(tmp, lastRect, cv::Scalar(255, 255, 255), 2); - cv::imshow("init", tmp); + cv::Mat tmp = cv::UMat(prevFrame, roiRect).getMat(cv::ACCESS_READ).clone(); + cv::rectangle(tmp, lastRect, cv::Scalar(255, 255, 255), 2); + cv::imshow("init", tmp); #endif - inited = true; - m_outOfTheFrame = false; - } - else - { - m_tracker.release(); - m_outOfTheFrame = true; - } - } - cv::Rect2d newRect; - if (!inited && !m_tracker.empty() && m_tracker->update(cv::UMat(currFrame, roiRect), newRect)) - { + inited = true; + m_outOfTheFrame = false; + } + else + { + m_tracker.release(); + m_outOfTheFrame = true; + } + + cv::Rect2d newRect; + if (!inited && !m_tracker.empty() && m_tracker->update(cv::UMat(currFrame, roiRect), newRect)) + { #if 0 - cv::Mat tmp2 = cv::UMat(currFrame, roiRect).getMat(cv::ACCESS_READ).clone(); - cv::rectangle(tmp2, newRect, cv::Scalar(255, 255, 255), 2); - cv::imshow("track", tmp2); + cv::Mat tmp2 = cv::UMat(currFrame, roiRect).getMat(cv::ACCESS_READ).clone(); + cv::rectangle(tmp2, newRect, cv::Scalar(255, 255, 255), 2); + cv::imshow("track", tmp2); #endif - cv::Rect prect(cvRound(newRect.x) + roiRect.x, cvRound(newRect.y) + roiRect.y, cvRound(newRect.width), cvRound(newRect.height)); + cv::Rect prect(cvRound(newRect.x) + roiRect.x, cvRound(newRect.y) + roiRect.y, cvRound(newRect.width), cvRound(newRect.height)); - m_predictionRect = m_kalman->Update(prect, true); + m_predictionRect = m_kalman->Update(prect, true); - recalcPrediction = false; + recalcPrediction = false; - m_boundidgRect = cv::Rect(); - m_lastRegion.m_points.clear(); - } + m_boundidgRect = cv::Rect(); + m_lastRegion.m_points.clear(); + } + } } else { @@ -449,6 +504,11 @@ void CTrack::RectUpdate( m_outOfTheFrame |= Clamp(m_predictionRect.x, m_predictionRect.width, currFrame.cols); m_outOfTheFrame |= Clamp(m_predictionRect.y, m_predictionRect.height, currFrame.rows); + if (m_outOfTheFrame) + { + m_predictionRect = ClampWithRect(m_predictionRect.tl(), m_predictionRect.size(), cv::Size(currFrame.cols, currFrame.rows)); + } + m_predictionPoint = (m_predictionRect.tl() + m_predictionRect.br()) / 2; } diff --git a/Tracker/track.h b/Tracker/track.h index 2766a1b1c..09fd72047 100644 --- a/Tracker/track.h +++ b/Tracker/track.h @@ -225,6 +225,69 @@ class CTrack cv::Ptr m_tracker; #endif + /** + * @brief Checking wx and hy is out of frame size + * + * @param wx width or x coord + * @param hy height or y coord + * @param frameSize image size + * @return cv::Size or cv::Point + * @author Shinung + */ + template + T checkSize(int wx, int hy, const cv::Size& frameSize) + { + if (wx > frameSize.width) + { + wx = frameSize.width; + } + else if (wx < 0) + { + wx = 2; + } + + if (hy > frameSize.height) + { + hy = frameSize.height; + } + else if (hy < 0) + { + hy = 2; + } + + return T(wx, hy); + } + + /** + * + * @param region + * @param dataCorrect + * @param prevFrame + * @param currFrame + * + * @bug If predicted rect by Kalman Filter is out of frame then, It will cause crash with exception of OpenCV. + * This bug will happen when to use not well-trained model so I modified code little bit as below. + * @code{.cpp} + //cv::Size roiSize(std::max(2 * m_predictionRect.width, currFrame.cols / 4), std::min(2 * m_predictionRect.height, currFrame.rows / 4)); + cv::Size roiSize = checkSize(std::max(2 * m_predictionRect.width, currFrame.cols / 4), + std::min(2 * m_predictionRect.height, currFrame.rows / 4), + cv::Size(currFrame.cols, currFrame.rows)); + + //cv::Point roiTL(m_predictionRect.x + m_predictionRect.width / 2 - roiSize.width / 2, m_predictionRect.y + m_predictionRect.height / 2 - roiSize.height / 2); + cv::Point roiTL = checkSize(m_predictionRect.x + m_predictionRect.width / 2 - roiSize.width / 2, + m_predictionRect.y + m_predictionRect.height / 2 - roiSize.height / 2, + cv::Size(currFrame.cols, currFrame.rows)); + + //cv::Rect roiRect(roiTL, roiSize); + //Clamp(roiRect.x, roiRect.width, currFrame.cols); + //Clamp(roiRect.y, roiRect.height, currFrame.rows); + + cv::Rect roiRect = ClampWithRect(roiTL, roiSize, cv::Size(currFrame.cols, currFrame.rows)); + cv::Rect frameRect(0, 0, currFrame.cols, currFrame.rows); + * @endcode + * @see checkSize + * @author Shinung + */ void RectUpdate(const CRegion& region, bool dataCorrect, cv::UMat prevFrame, cv::UMat currFrame); void CreateExternalTracker(); diff --git a/VideoExample.cpp b/VideoExample.cpp index 9d5a98de9..9af1c04dd 100644 --- a/VideoExample.cpp +++ b/VideoExample.cpp @@ -1,5 +1,13 @@ +#include + #include "VideoExample.h" +void GlobalInitGLOG(char*** pargv) +{ + FLAGS_alsologtostderr = 1; + ::google::InitGoogleLogging(*(pargv)[0]); +} + /// /// \brief VideoExample::VideoExample /// \param parser @@ -9,8 +17,8 @@ VideoExample::VideoExample(const cv::CommandLineParser& parser) m_showLogs(true), m_fps(25), m_useLocalTracking(false), - m_captureTimeOut(60000), - m_trackingTimeOut(60000), + m_captureTimeOut(60000000), + m_trackingTimeOut(60000000), m_isTrackerInitialized(false), m_startFrame(0), m_endFrame(0), @@ -113,7 +121,7 @@ void VideoExample::Process() if (!writer.isOpened()) { - writer.open(m_outFile, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), m_fps, m_frameInfo[currFrame].m_frame.size(), true); + writer.open(m_outFile, cv::VideoWriter::fourcc('H', '2', '6', '4'), m_fps, m_frameInfo[currFrame].m_frame.size(), true); } int64 t1 = cv::getTickCount(); diff --git a/VideoExample.h b/VideoExample.h index 9655651f3..dba62b07b 100644 --- a/VideoExample.h +++ b/VideoExample.h @@ -15,6 +15,15 @@ // ---------------------------------------------------------------------- +/** + * @brief Initialize function for GLOG + * @param [in] pargv ::google::InitGoogleLogging require program name + * @author Shinung + */ +void GlobalInitGLOG(char*** pargv); + +// ---------------------------------------------------------------------- + /// /// \brief The VideoExample class /// @@ -468,10 +477,14 @@ class YoloExample : public VideoExample config_t config; //config["modelConfiguration"] = "../data/tiny-yolo.cfg"; //config["modelBinary"] = "../data/tiny-yolo.weights"; - config["modelConfiguration"] = "../data/yolov3-tiny.cfg"; - config["modelBinary"] = "../data/yolov3-tiny.weights"; - config["classNames"] = "../data/coco.names"; - config["confidenceThreshold"] = "0.5"; + //config["modelConfiguration"] = "../data/yolov3-tiny.cfg"; + //config["modelBinary"] = "../data/yolov3-tiny.weights"; + //config["classNames"] = "../data/coco.names"; + config["modelConfiguration"] = "../../data/yolov3-urbantracker.cfg"; + config["modelBinary"] = "../../data/yolov3-urbantracker_13300.weights"; + config["classNames"] = "../../data/urbantracker.names"; + + config["confidenceThreshold"] = "0.2"; config["maxCropRatio"] = "3.0"; config["dnnTarget"] = "DNN_TARGET_OPENCL_FP16"; @@ -541,3 +554,128 @@ class YoloExample : public VideoExample return false; } }; + +// ---------------------------------------------------------------------- + +/** + * @brief This class is for customized caffe library + * It is need to build caffe library + * + * I build and test with below caffe library + * + * - this branch is a caffe-ssd library ported to windows and for inference. + * - For MobilenetSSD, I build caffe-ssd with [Depthwise Convolutional Layer](https://github.com/yonghenglh6/DepthwiseConvolution) + * + * @author Shinung + */ +class CustomSSDMobileNetExample : public VideoExample +{ +public: + /** + * @brief It's needed deploy/label-map prototxt file path and caffemodel file path + * @param parser Construct with arguments in cv::CommandLineParser + * @author Shinung + */ + CustomSSDMobileNetExample(const cv::CommandLineParser& parser) + : + VideoExample(parser), + mDeploy(parser.get("deploy")), + mWeights(parser.get("weights")), + mLabelMap(parser.get("label-map")) + { + } + +protected: + /** + * @brief Tracker and Detector will be initilaized in this function. + * @param [in] frame gray image + * @see VideoExample::CaptureAndDetect + * @see tracking::Detectors + * @return true if tracker and detector is initilaized successfully + * @author Shinung + */ + bool InitTracker(cv::UMat frame) + { + config_t config; + config["modelConfiguration"] = mDeploy.c_str(); + config["modelBinary"] = mWeights.c_str(); + config["labelMap"] = mLabelMap.c_str(); + config["meanValue"] = "104,117,123"; + config["confidenceThreshold"] = "0.5"; + config["maxCropRatio"] = "3.0"; + config["dnnTarget"] = "DNN_TARGET_OPENCL_FP16"; + m_detector = std::unique_ptr(CreateDetector(tracking::Detectors::SSD_CustomNet, config, m_useLocalTracking, frame)); + if (!m_detector.get()) + { + return false; + } + m_detector->SetMinObjectSize(cv::Size(frame.cols / 20, frame.rows / 20)); + + TrackerSettings settings; + settings.m_useLocalTracking = m_useLocalTracking; + settings.m_distType = tracking::DistRects; + settings.m_kalmanType = tracking::KalmanLinear; + settings.m_filterGoal = tracking::FilterRect; + settings.m_lostTrackType = tracking::TrackKCF; // Use KCF tracker for collisions resolving + settings.m_matchType = tracking::MatchHungrian; + settings.m_dt = 0.3f; // Delta time for Kalman filter + settings.m_accelNoiseMag = 0.1f; // Accel noise magnitude for Kalman filter + settings.m_distThres = frame.rows / 10; // Distance threshold between region and object on two frames + settings.m_maximumAllowedSkippedFrames = 2 * m_fps; // Maximum allowed skipped frames + settings.m_maxTraceLength = 5 * m_fps; // Maximum trace length + + m_tracker = std::make_unique(settings); + + return true; + } + + /// + /// \brief DrawData + /// \param frame + /// + void DrawData(cv::Mat frame, int framesCounter, int currTime) + { + if (m_showLogs) + { + std::cout << "Frame " << framesCounter << ": tracks = " << m_tracker->tracks.size() << ", time = " << currTime << std::endl; + } + + for (const auto& track : m_tracker->tracks) + { + if (track->IsRobust(5, // Minimal trajectory size + 0.2f, // Minimal ratio raw_trajectory_points / trajectory_lenght + cv::Size2f(0.1f, 8.0f)) // Min and max ratio: width / height + ) + { + DrawTrack(frame, 1, *track); + + std::ostringstream label; + label << track->m_lastRegion.m_type << ": " << std::setprecision(1) << track->m_lastRegion.m_confidence; + int baseLine = 0; + cv::Size labelSize = cv::getTextSize(label.str(), cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + auto rect(track->GetLastRect()); + cv::rectangle(frame, cv::Rect(cv::Point(rect.x, rect.y - labelSize.height), cv::Size(labelSize.width, labelSize.height + baseLine)), cv::Scalar(255, 255, 255), CV_FILLED); + cv::putText(frame, label.str(), cv::Point(rect.x, rect.y), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0)); + } + } + + m_detector->CalcMotionMap(frame); + } + + /** + * @brief image color change to gray scale or not + * + * I followed SSDMobileNetExample code. + * @return always TRUE + * @author Shinung + */ + bool GrayProcessing() const + { + return false; + } + +private: + cv::String mDeploy; /**< deploy prototxt file path */ + cv::String mWeights; /**< trained caffemodel file path */ + cv::String mLabelMap; /**< label-map prototxt file path */ +}; \ No newline at end of file diff --git a/args.txt b/args.txt new file mode 100644 index 000000000..d905e2441 --- /dev/null +++ b/args.txt @@ -0,0 +1,3 @@ +../data/videos/video_1.avi -e=6 --gpu=1 --show_logs=1 -d=../data/ssd_mobilenet_dw/MobileNetSSD_deploy.prototxt -w=../data/MobileNetSSD_deploy.caffemodel -l=../data/ssd_mobilenet_dw/labelmap_voc.prototxt + +../data/videos/video_1.avi -e=6 --gpu=1 --show_logs=1 -d=../data/ssd_ids_trained/Deploy_Near.prototxt -w=../data/ssd_ids_trained/Near.caffemodel -l=../data/ssd_ids_trained/labelmap_Near.prototxt \ No newline at end of file diff --git a/data/ssd_mobilenet_dw/MobileNetSSD_deploy.prototxt b/data/ssd_mobilenet_dw/MobileNetSSD_deploy.prototxt new file mode 100644 index 000000000..bd15cdda7 --- /dev/null +++ b/data/ssd_mobilenet_dw/MobileNetSSD_deploy.prototxt @@ -0,0 +1,1912 @@ +name: "MobileNet-SSD" +input: "data" +input_shape { + dim: 1 + dim: 3 + dim: 300 + dim: 300 +} +layer { + name: "conv0" + type: "Convolution" + bottom: "data" + top: "conv0" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 32 + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv0/relu" + type: "ReLU" + bottom: "conv0" + top: "conv0" +} +layer { + name: "conv1/dw" + type: "DepthwiseConvolution" + bottom: "conv0" + top: "conv1/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 32 + pad: 1 + kernel_size: 3 + group: 32 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv1/dw/relu" + type: "ReLU" + bottom: "conv1/dw" + top: "conv1/dw" +} +layer { + name: "conv1" + type: "Convolution" + bottom: "conv1/dw" + top: "conv1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 64 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv1/relu" + type: "ReLU" + bottom: "conv1" + top: "conv1" +} +layer { + name: "conv2/dw" + type: "DepthwiseConvolution" + bottom: "conv1" + top: "conv2/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 64 + pad: 1 + kernel_size: 3 + stride: 2 + group: 64 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv2/dw/relu" + type: "ReLU" + bottom: "conv2/dw" + top: "conv2/dw" +} +layer { + name: "conv2" + type: "Convolution" + bottom: "conv2/dw" + top: "conv2" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 128 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv2/relu" + type: "ReLU" + bottom: "conv2" + top: "conv2" +} +layer { + name: "conv3/dw" + type: "DepthwiseConvolution" + bottom: "conv2" + top: "conv3/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + group: 128 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv3/dw/relu" + type: "ReLU" + bottom: "conv3/dw" + top: "conv3/dw" +} +layer { + name: "conv3" + type: "Convolution" + bottom: "conv3/dw" + top: "conv3" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 128 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv3/relu" + type: "ReLU" + bottom: "conv3" + top: "conv3" +} +layer { + name: "conv4/dw" + type: "DepthwiseConvolution" + bottom: "conv3" + top: "conv4/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + stride: 2 + group: 128 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv4/dw/relu" + type: "ReLU" + bottom: "conv4/dw" + top: "conv4/dw" +} +layer { + name: "conv4" + type: "Convolution" + bottom: "conv4/dw" + top: "conv4" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 256 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv4/relu" + type: "ReLU" + bottom: "conv4" + top: "conv4" +} +layer { + name: "conv5/dw" + type: "DepthwiseConvolution" + bottom: "conv4" + top: "conv5/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + group: 256 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv5/dw/relu" + type: "ReLU" + bottom: "conv5/dw" + top: "conv5/dw" +} +layer { + name: "conv5" + type: "Convolution" + bottom: "conv5/dw" + top: "conv5" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 256 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv5/relu" + type: "ReLU" + bottom: "conv5" + top: "conv5" +} +layer { + name: "conv6/dw" + type: "DepthwiseConvolution" + bottom: "conv5" + top: "conv6/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + stride: 2 + group: 256 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv6/dw/relu" + type: "ReLU" + bottom: "conv6/dw" + top: "conv6/dw" +} +layer { + name: "conv6" + type: "Convolution" + bottom: "conv6/dw" + top: "conv6" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv6/relu" + type: "ReLU" + bottom: "conv6" + top: "conv6" +} +layer { + name: "conv7/dw" + type: "DepthwiseConvolution" + bottom: "conv6" + top: "conv7/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + group: 512 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv7/dw/relu" + type: "ReLU" + bottom: "conv7/dw" + top: "conv7/dw" +} +layer { + name: "conv7" + type: "Convolution" + bottom: "conv7/dw" + top: "conv7" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv7/relu" + type: "ReLU" + bottom: "conv7" + top: "conv7" +} +layer { + name: "conv8/dw" + type: "DepthwiseConvolution" + bottom: "conv7" + top: "conv8/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + group: 512 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv8/dw/relu" + type: "ReLU" + bottom: "conv8/dw" + top: "conv8/dw" +} +layer { + name: "conv8" + type: "Convolution" + bottom: "conv8/dw" + top: "conv8" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv8/relu" + type: "ReLU" + bottom: "conv8" + top: "conv8" +} +layer { + name: "conv9/dw" + type: "DepthwiseConvolution" + bottom: "conv8" + top: "conv9/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + group: 512 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv9/dw/relu" + type: "ReLU" + bottom: "conv9/dw" + top: "conv9/dw" +} +layer { + name: "conv9" + type: "Convolution" + bottom: "conv9/dw" + top: "conv9" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv9/relu" + type: "ReLU" + bottom: "conv9" + top: "conv9" +} +layer { + name: "conv10/dw" + type: "DepthwiseConvolution" + bottom: "conv9" + top: "conv10/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + group: 512 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv10/dw/relu" + type: "ReLU" + bottom: "conv10/dw" + top: "conv10/dw" +} +layer { + name: "conv10" + type: "Convolution" + bottom: "conv10/dw" + top: "conv10" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv10/relu" + type: "ReLU" + bottom: "conv10" + top: "conv10" +} +layer { + name: "conv11/dw" + type: "DepthwiseConvolution" + bottom: "conv10" + top: "conv11/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + group: 512 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv11/dw/relu" + type: "ReLU" + bottom: "conv11/dw" + top: "conv11/dw" +} +layer { + name: "conv11" + type: "Convolution" + bottom: "conv11/dw" + top: "conv11" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv11/relu" + type: "ReLU" + bottom: "conv11" + top: "conv11" +} +layer { + name: "conv12/dw" + type: "DepthwiseConvolution" + bottom: "conv11" + top: "conv12/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + stride: 2 + group: 512 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv12/dw/relu" + type: "ReLU" + bottom: "conv12/dw" + top: "conv12/dw" +} +layer { + name: "conv12" + type: "Convolution" + bottom: "conv12/dw" + top: "conv12" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 1024 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv12/relu" + type: "ReLU" + bottom: "conv12" + top: "conv12" +} +layer { + name: "conv13/dw" + type: "DepthwiseConvolution" + bottom: "conv12" + top: "conv13/dw" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 1024 + pad: 1 + kernel_size: 3 + group: 1024 + engine: CAFFE + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv13/dw/relu" + type: "ReLU" + bottom: "conv13/dw" + top: "conv13/dw" +} +layer { + name: "conv13" + type: "Convolution" + bottom: "conv13/dw" + top: "conv13" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 1024 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv13/relu" + type: "ReLU" + bottom: "conv13" + top: "conv13" +} +layer { + name: "conv14_1" + type: "Convolution" + bottom: "conv13" + top: "conv14_1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 256 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv14_1/relu" + type: "ReLU" + bottom: "conv14_1" + top: "conv14_1" +} +layer { + name: "conv14_2" + type: "Convolution" + bottom: "conv14_1" + top: "conv14_2" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv14_2/relu" + type: "ReLU" + bottom: "conv14_2" + top: "conv14_2" +} +layer { + name: "conv15_1" + type: "Convolution" + bottom: "conv14_2" + top: "conv15_1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 128 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv15_1/relu" + type: "ReLU" + bottom: "conv15_1" + top: "conv15_1" +} +layer { + name: "conv15_2" + type: "Convolution" + bottom: "conv15_1" + top: "conv15_2" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv15_2/relu" + type: "ReLU" + bottom: "conv15_2" + top: "conv15_2" +} +layer { + name: "conv16_1" + type: "Convolution" + bottom: "conv15_2" + top: "conv16_1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 128 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv16_1/relu" + type: "ReLU" + bottom: "conv16_1" + top: "conv16_1" +} +layer { + name: "conv16_2" + type: "Convolution" + bottom: "conv16_1" + top: "conv16_2" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv16_2/relu" + type: "ReLU" + bottom: "conv16_2" + top: "conv16_2" +} +layer { + name: "conv17_1" + type: "Convolution" + bottom: "conv16_2" + top: "conv17_1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 64 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv17_1/relu" + type: "ReLU" + bottom: "conv17_1" + top: "conv17_1" +} +layer { + name: "conv17_2" + type: "Convolution" + bottom: "conv17_1" + top: "conv17_2" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv17_2/relu" + type: "ReLU" + bottom: "conv17_2" + top: "conv17_2" +} +layer { + name: "conv11_mbox_loc" + type: "Convolution" + bottom: "conv11" + top: "conv11_mbox_loc" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 12 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv11_mbox_loc_perm" + type: "Permute" + bottom: "conv11_mbox_loc" + top: "conv11_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv11_mbox_loc_flat" + type: "Flatten" + bottom: "conv11_mbox_loc_perm" + top: "conv11_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv11_mbox_conf_new" + type: "Convolution" + bottom: "conv11" + top: "conv11_mbox_conf" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 63 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv11_mbox_conf_perm" + type: "Permute" + bottom: "conv11_mbox_conf" + top: "conv11_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv11_mbox_conf_flat" + type: "Flatten" + bottom: "conv11_mbox_conf_perm" + top: "conv11_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv11_mbox_priorbox" + type: "PriorBox" + bottom: "conv11" + bottom: "data" + top: "conv11_mbox_priorbox" + prior_box_param { + min_size: 60.0 + aspect_ratio: 2.0 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + offset: 0.5 + } +} +layer { + name: "conv13_mbox_loc" + type: "Convolution" + bottom: "conv13" + top: "conv13_mbox_loc" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 24 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv13_mbox_loc_perm" + type: "Permute" + bottom: "conv13_mbox_loc" + top: "conv13_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv13_mbox_loc_flat" + type: "Flatten" + bottom: "conv13_mbox_loc_perm" + top: "conv13_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv13_mbox_conf_new" + type: "Convolution" + bottom: "conv13" + top: "conv13_mbox_conf" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 126 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv13_mbox_conf_perm" + type: "Permute" + bottom: "conv13_mbox_conf" + top: "conv13_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv13_mbox_conf_flat" + type: "Flatten" + bottom: "conv13_mbox_conf_perm" + top: "conv13_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv13_mbox_priorbox" + type: "PriorBox" + bottom: "conv13" + bottom: "data" + top: "conv13_mbox_priorbox" + prior_box_param { + min_size: 105.0 + max_size: 150.0 + aspect_ratio: 2.0 + aspect_ratio: 3.0 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + offset: 0.5 + } +} +layer { + name: "conv14_2_mbox_loc" + type: "Convolution" + bottom: "conv14_2" + top: "conv14_2_mbox_loc" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 24 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv14_2_mbox_loc_perm" + type: "Permute" + bottom: "conv14_2_mbox_loc" + top: "conv14_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv14_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv14_2_mbox_loc_perm" + top: "conv14_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv14_2_mbox_conf_new" + type: "Convolution" + bottom: "conv14_2" + top: "conv14_2_mbox_conf" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 126 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv14_2_mbox_conf_perm" + type: "Permute" + bottom: "conv14_2_mbox_conf" + top: "conv14_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv14_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv14_2_mbox_conf_perm" + top: "conv14_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv14_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv14_2" + bottom: "data" + top: "conv14_2_mbox_priorbox" + prior_box_param { + min_size: 150.0 + max_size: 195.0 + aspect_ratio: 2.0 + aspect_ratio: 3.0 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + offset: 0.5 + } +} +layer { + name: "conv15_2_mbox_loc" + type: "Convolution" + bottom: "conv15_2" + top: "conv15_2_mbox_loc" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 24 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv15_2_mbox_loc_perm" + type: "Permute" + bottom: "conv15_2_mbox_loc" + top: "conv15_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv15_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv15_2_mbox_loc_perm" + top: "conv15_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv15_2_mbox_conf_new" + type: "Convolution" + bottom: "conv15_2" + top: "conv15_2_mbox_conf" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 126 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv15_2_mbox_conf_perm" + type: "Permute" + bottom: "conv15_2_mbox_conf" + top: "conv15_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv15_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv15_2_mbox_conf_perm" + top: "conv15_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv15_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv15_2" + bottom: "data" + top: "conv15_2_mbox_priorbox" + prior_box_param { + min_size: 195.0 + max_size: 240.0 + aspect_ratio: 2.0 + aspect_ratio: 3.0 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + offset: 0.5 + } +} +layer { + name: "conv16_2_mbox_loc" + type: "Convolution" + bottom: "conv16_2" + top: "conv16_2_mbox_loc" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 24 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv16_2_mbox_loc_perm" + type: "Permute" + bottom: "conv16_2_mbox_loc" + top: "conv16_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv16_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv16_2_mbox_loc_perm" + top: "conv16_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv16_2_mbox_conf_new" + type: "Convolution" + bottom: "conv16_2" + top: "conv16_2_mbox_conf" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 126 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv16_2_mbox_conf_perm" + type: "Permute" + bottom: "conv16_2_mbox_conf" + top: "conv16_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv16_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv16_2_mbox_conf_perm" + top: "conv16_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv16_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv16_2" + bottom: "data" + top: "conv16_2_mbox_priorbox" + prior_box_param { + min_size: 240.0 + max_size: 285.0 + aspect_ratio: 2.0 + aspect_ratio: 3.0 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + offset: 0.5 + } +} +layer { + name: "conv17_2_mbox_loc" + type: "Convolution" + bottom: "conv17_2" + top: "conv17_2_mbox_loc" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 24 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv17_2_mbox_loc_perm" + type: "Permute" + bottom: "conv17_2_mbox_loc" + top: "conv17_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv17_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv17_2_mbox_loc_perm" + top: "conv17_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv17_2_mbox_conf_new" + type: "Convolution" + bottom: "conv17_2" + top: "conv17_2_mbox_conf" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 0.0 + } + convolution_param { + num_output: 126 + kernel_size: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv17_2_mbox_conf_perm" + type: "Permute" + bottom: "conv17_2_mbox_conf" + top: "conv17_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv17_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv17_2_mbox_conf_perm" + top: "conv17_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv17_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv17_2" + bottom: "data" + top: "conv17_2_mbox_priorbox" + prior_box_param { + min_size: 285.0 + max_size: 300.0 + aspect_ratio: 2.0 + aspect_ratio: 3.0 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + offset: 0.5 + } +} +layer { + name: "mbox_loc" + type: "Concat" + bottom: "conv11_mbox_loc_flat" + bottom: "conv13_mbox_loc_flat" + bottom: "conv14_2_mbox_loc_flat" + bottom: "conv15_2_mbox_loc_flat" + bottom: "conv16_2_mbox_loc_flat" + bottom: "conv17_2_mbox_loc_flat" + top: "mbox_loc" + concat_param { + axis: 1 + } +} +layer { + name: "mbox_conf" + type: "Concat" + bottom: "conv11_mbox_conf_flat" + bottom: "conv13_mbox_conf_flat" + bottom: "conv14_2_mbox_conf_flat" + bottom: "conv15_2_mbox_conf_flat" + bottom: "conv16_2_mbox_conf_flat" + bottom: "conv17_2_mbox_conf_flat" + top: "mbox_conf" + concat_param { + axis: 1 + } +} +layer { + name: "mbox_priorbox" + type: "Concat" + bottom: "conv11_mbox_priorbox" + bottom: "conv13_mbox_priorbox" + bottom: "conv14_2_mbox_priorbox" + bottom: "conv15_2_mbox_priorbox" + bottom: "conv16_2_mbox_priorbox" + bottom: "conv17_2_mbox_priorbox" + top: "mbox_priorbox" + concat_param { + axis: 2 + } +} +layer { + name: "mbox_conf_reshape" + type: "Reshape" + bottom: "mbox_conf" + top: "mbox_conf_reshape" + reshape_param { + shape { + dim: 0 + dim: -1 + dim: 21 + } + } +} +layer { + name: "mbox_conf_softmax" + type: "Softmax" + bottom: "mbox_conf_reshape" + top: "mbox_conf_softmax" + softmax_param { + axis: 2 + } +} +layer { + name: "mbox_conf_flatten" + type: "Flatten" + bottom: "mbox_conf_softmax" + top: "mbox_conf_flatten" + flatten_param { + axis: 1 + } +} +layer { + name: "detection_out" + type: "DetectionOutput" + bottom: "mbox_loc" + bottom: "mbox_conf_flatten" + bottom: "mbox_priorbox" + top: "detection_out" + include { + phase: TEST + } + detection_output_param { + num_classes: 21 + share_location: true + background_label_id: 0 + nms_param { + nms_threshold: 0.45 + top_k: 100 + } + code_type: CENTER_SIZE + keep_top_k: 100 + confidence_threshold: 0.25 + } +} diff --git a/data/ssd_mobilenet_dw/labelmap_voc.prototxt b/data/ssd_mobilenet_dw/labelmap_voc.prototxt new file mode 100644 index 000000000..b5c177b72 --- /dev/null +++ b/data/ssd_mobilenet_dw/labelmap_voc.prototxt @@ -0,0 +1,105 @@ +item { + name: "none_of_the_above" + label: 0 + display_name: "background" +} +item { + name: "aeroplane" + label: 1 + display_name: "aeroplane" +} +item { + name: "bicycle" + label: 2 + display_name: "bicycle" +} +item { + name: "bird" + label: 3 + display_name: "bird" +} +item { + name: "boat" + label: 4 + display_name: "boat" +} +item { + name: "bottle" + label: 5 + display_name: "bottle" +} +item { + name: "bus" + label: 6 + display_name: "bus" +} +item { + name: "car" + label: 7 + display_name: "car" +} +item { + name: "cat" + label: 8 + display_name: "cat" +} +item { + name: "chair" + label: 9 + display_name: "chair" +} +item { + name: "cow" + label: 10 + display_name: "cow" +} +item { + name: "diningtable" + label: 11 + display_name: "diningtable" +} +item { + name: "dog" + label: 12 + display_name: "dog" +} +item { + name: "horse" + label: 13 + display_name: "horse" +} +item { + name: "motorbike" + label: 14 + display_name: "motorbike" +} +item { + name: "person" + label: 15 + display_name: "person" +} +item { + name: "pottedplant" + label: 16 + display_name: "pottedplant" +} +item { + name: "sheep" + label: 17 + display_name: "sheep" +} +item { + name: "sofa" + label: 18 + display_name: "sofa" +} +item { + name: "train" + label: 19 + display_name: "train" +} +item { + name: "tvmonitor" + label: 20 + display_name: "tvmonitor" +} diff --git a/data/urbantracker.names b/data/urbantracker.names new file mode 100644 index 000000000..20f19188f --- /dev/null +++ b/data/urbantracker.names @@ -0,0 +1,7 @@ +unknown +car +pedestrian +motocycle +bicycle +bus +truck diff --git a/data/yolov3-urbantracker.cfg b/data/yolov3-urbantracker.cfg new file mode 100644 index 000000000..f93142efb --- /dev/null +++ b/data/yolov3-urbantracker.cfg @@ -0,0 +1,788 @@ +[net] +# Testing +batch=64 +subdivisions=16 +# Training +# batch=64 +# subdivisions=16 +width=416 +height=416 +channels=3 +momentum=0.9 +decay=0.0005 +angle=0 +saturation = 1.5 +exposure = 1.5 +hue=.1 + +learning_rate=0.001 +burn_in=1000 +max_batches = 500200 +policy=steps +steps=400000,450000 +scales=.1,.1 + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=leaky + +# Downsample + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=32 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +###################### + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=36 +activation=linear + + +[yolo] +mask = 6,7,8 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=7 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +random=1 + + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 61 + + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=36 +activation=linear + + +[yolo] +mask = 3,4,5 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=7 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +random=1 + + + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 36 + + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=36 +activation=linear + + +[yolo] +mask = 0,1,2 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=7 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +random=1 diff --git a/defines.h b/defines.h index 8f6bf2520..a42462360 100644 --- a/defines.h +++ b/defines.h @@ -69,7 +69,8 @@ enum Detectors Pedestrian_HOG, Pedestrian_C4, SSD_MobileNet, - Yolo + Yolo, + SSD_CustomNet /**< It's for creating SSDCustomNetDetector */ }; /// diff --git a/dll_lists_debug.txt b/dll_lists_debug.txt new file mode 100644 index 000000000..306f1abe5 --- /dev/null +++ b/dll_lists_debug.txt @@ -0,0 +1,37 @@ +build/Debug/boost_chrono-vc140-mt-gd-1_61.dll* +build/Debug/boost_filesystem-vc140-mt-gd-1_61.dll* +build/Debug/boost_python-vc140-mt-gd-1_61.dll* +build/Debug/boost_system-vc140-mt-gd-1_61.dll* +build/Debug/boost_thread-vc140-mt-gd-1_61.dll* +build/Debug/caffehdf5_D.dll* +build/Debug/caffehdf5_hl_D.dll* +build/Debug/caffezlibd1.dll* +build/Debug/cublas64_80.dll* +build/Debug/cudart64_80.dll* +build/Debug/cudnn64_5.dll* +build/Debug/curand64_80.dll* +build/Debug/gflagsd.dll* +build/Debug/glogd.dll* +build/Debug/libgcc_s_seh-1.dll* +build/Debug/libgfortran-3.dll* +build/Debug/libopenblas.dll* +build/Debug/libquadmath-0.dll* +build/Debug/opencv_bgsegm342d.dll* +build/Debug/opencv_calib3d342d.dll* +build/Debug/opencv_core342d.dll* +build/Debug/opencv_cudaarithm342d.dll* +build/Debug/opencv_cudafilters342d.dll* +build/Debug/opencv_cudaimgproc342d.dll* +build/Debug/opencv_cudawarping342d.dll* +build/Debug/opencv_dnn342d.dll* +build/Debug/opencv_features2d342d.dll* +build/Debug/opencv_flann342d.dll* +build/Debug/opencv_highgui342d.dll* +build/Debug/opencv_imgcodecs342d.dll* +build/Debug/opencv_imgproc342d.dll* +build/Debug/opencv_objdetect342d.dll* +build/Debug/opencv_tracking342d.dll* +build/Debug/opencv_video342d.dll* +build/Debug/opencv_videoio342d.dll* +build/Debug/python35.dll* +build/Debug/VCRUNTIME140.dll* diff --git a/dll_lists_release.txt b/dll_lists_release.txt new file mode 100644 index 000000000..f607fb16f --- /dev/null +++ b/dll_lists_release.txt @@ -0,0 +1,37 @@ +build/Release/boost_chrono-vc140-mt-1_61.dll* +build/Release/boost_filesystem-vc140-mt-1_61.dll* +build/Release/boost_python-vc140-mt-1_61.dll* +build/Release/boost_system-vc140-mt-1_61.dll* +build/Release/boost_thread-vc140-mt-1_61.dll* +build/Release/caffehdf5.dll* +build/Release/caffehdf5_hl.dll* +build/Release/caffezlib1.dll* +build/Release/cublas64_80.dll* +build/Release/cudart64_80.dll* +build/Release/cudnn64_5.dll* +build/Release/curand64_80.dll* +build/Release/gflags.dll* +build/Release/glog.dll* +build/Release/libgcc_s_seh-1.dll* +build/Release/libgfortran-3.dll* +build/Release/libopenblas.dll* +build/Release/libquadmath-0.dll* +build/Release/opencv_bgsegm342.dll* +build/Release/opencv_calib3d342.dll* +build/Release/opencv_core342.dll* +build/Release/opencv_cudaarithm342.dll* +build/Release/opencv_cudafilters342.dll* +build/Release/opencv_cudaimgproc342.dll* +build/Release/opencv_cudawarping342.dll* +build/Release/opencv_dnn342.dll* +build/Release/opencv_features2d342.dll* +build/Release/opencv_flann342.dll* +build/Release/opencv_highgui342.dll* +build/Release/opencv_imgcodecs342.dll* +build/Release/opencv_imgproc342.dll* +build/Release/opencv_objdetect342.dll* +build/Release/opencv_tracking342.dll* +build/Release/opencv_video342.dll* +build/Release/opencv_videoio342.dll* +build/Release/python35.dll* +build/Release/VCRUNTIME140.dll* diff --git a/doc.zip b/doc.zip new file mode 100644 index 000000000..929692063 Binary files /dev/null and b/doc.zip differ diff --git a/lib_lists_debug.txt b/lib_lists_debug.txt new file mode 100644 index 000000000..b1de7702c --- /dev/null +++ b/lib_lists_debug.txt @@ -0,0 +1,92 @@ +D:\Roy\libcaffe\caffeForInference\caffe\build\install\lib\caffe-d.lib +D:\Roy\libcaffe\caffeForInference\caffe\build\install\lib\caffeproto-d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_system-vc140-mt-gd-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_thread-vc140-mt-gd-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_filesystem-vc140-mt-gd-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_chrono-vc140-mt-gd-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_date_time-vc140-mt-gd-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_atomic-vc140-mt-gd-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_python-vc140-mt-gd-1_61.lib +C:\ProgramData\Anaconda3\libs\python35.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\glogd.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\Lib\gflagsd.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\libprotobufd.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\caffehdf5_hl_D.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\caffehdf5_D.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\caffezlibd.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\lmdbd.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\leveldbd.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\snappy_staticd.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\libopenblas.dll.a +C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64\cudart.lib +C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64\curand.lib +C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64\cublas.lib +C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64\cublas_device.lib +C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64\cudnn.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudabgsegm342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudaobjdetect342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudastereo342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_stitching342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_superres342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_videostab342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_aruco342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_bgsegm342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_bioinspired342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_ccalib342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_dnn_objdetect342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_dpm342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_face342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_fuzzy342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_hfs342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_img_hash342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_line_descriptor342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_optflow342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_reg342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_rgbd342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_saliency342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_stereo342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_structured_light342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_surface_matching342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_tracking342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_xfeatures2d342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_ximgproc342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_xobjdetect342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_xphoto342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudafeatures2d342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_shape342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudacodec342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudaoptflow342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudalegacy342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudawarping342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_photo342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudaimgproc342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudafilters342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudaarithm342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_calib3d342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_phase_unwrapping342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_video342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_datasets342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_plot342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_text342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_dnn342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_features2d342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_flann342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_highgui342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_ml342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_videoio342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_imgcodecs342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_objdetect342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_imgproc342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_core342d.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudev342d.lib +ntdll.lib +kernel32.lib +user32.lib +gdi32.lib +winspool.lib +shell32.lib +ole32.lib +oleaut32.lib +uuid.lib +comdlg32.lib +advapi32.lib \ No newline at end of file diff --git a/lib_lists_release.txt b/lib_lists_release.txt new file mode 100644 index 000000000..5c6e3c35d --- /dev/null +++ b/lib_lists_release.txt @@ -0,0 +1,92 @@ +D:\Roy\libcaffe\caffeForInference\caffe\build\install\lib\caffe.lib +D:\Roy\libcaffe\caffeForInference\caffe\build\install\lib\caffeproto.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_system-vc140-mt-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_thread-vc140-mt-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_filesystem-vc140-mt-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_date_time-vc140-mt-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_chrono-vc140-mt-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_atomic-vc140-mt-1_61.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\boost_python-vc140-mt-1_61.lib +C:\ProgramData\Anaconda3\libs\python35.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\glog.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\gflags.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\libprotobuf.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\caffehdf5_hl.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\caffehdf5.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\caffezlib.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\lmdb.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\leveldb.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\snappy_static.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib\libopenblas.dll.a +C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64\cudart.lib +C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64\curand.lib +C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64\cublas.lib +C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64\cublas_device.lib +C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64\cudnn.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudabgsegm342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudaobjdetect342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudastereo342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_stitching342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_superres342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_videostab342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_aruco342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_bgsegm342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_bioinspired342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_ccalib342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_dnn_objdetect342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_dpm342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_face342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_fuzzy342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_hfs342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_img_hash342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_line_descriptor342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_optflow342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_reg342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_rgbd342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_saliency342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_stereo342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_structured_light342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_surface_matching342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_tracking342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_xfeatures2d342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_ximgproc342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_xobjdetect342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_xphoto342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudafeatures2d342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_shape342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudacodec342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudaoptflow342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudalegacy342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudawarping342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_photo342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudaimgproc342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudafilters342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudaarithm342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_calib3d342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_phase_unwrapping342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_video342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_datasets342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_plot342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_text342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_dnn342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_features2d342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_flann342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_highgui342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_ml342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_videoio342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_imgcodecs342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_objdetect342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_imgproc342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_core342.lib +D:\Roy\libcaffe\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\x64\vc14\lib\opencv_cudev342.lib +ntdll.lib +kernel32.lib +user32.lib +gdi32.lib +winspool.lib +shell32.lib +ole32.lib +oleaut32.lib +uuid.lib +comdlg32.lib +advapi32.lib \ No newline at end of file diff --git a/main.cpp b/main.cpp index cde124e6c..f798fd4d7 100644 --- a/main.cpp +++ b/main.cpp @@ -27,12 +27,16 @@ const char* keys = "{ o out | | Name of result video file | }" "{ sl show_logs |1 | Show Trackers logs | }" "{ g gpu |0 | Use OpenCL acceleration | }" + "{ d deploy |0 | Specify neural network deploy file(.prototxt) | }" + "{ w weights |0 | Specify weights of neural network file(.caffemodel) | }" + "{ l label-map |0 | Specify label map of neural network file(.prototxt) | }" }; // ---------------------------------------------------------------------- int main(int argc, char** argv) { + GlobalInitGLOG(&argv); Help(); cv::CommandLineParser parser(argc, argv, keys); @@ -84,6 +88,19 @@ int main(int argc, char** argv) break; } + case 6: + { + if (!parser.has("deploy") || !parser.has("weights") || !parser.has("label-map")) + { + std::cout << "deploy, weights and label-map file should specify if using custom SSD net" << std::endl; + return -1; + } + + CustomSSDMobileNetExample custom_ssd_detector(parser); + custom_ssd_detector.Process(); + break; + } + default: std::cerr << "Wrong example number!" << std::endl; break; diff --git a/run-code.py b/run-code.py new file mode 100644 index 000000000..f0f6dc6ea --- /dev/null +++ b/run-code.py @@ -0,0 +1,145 @@ +import os +import shutil + +''' + tip: configure the main setting +''' + +detector_list = ['yolo', 'ssd', 'dw'] +codec = 'h264' +dst_ext = 'mp4' if codec == 'h264' else 'avi' + +def run_code(detector, threshold, video_num): + + # ---------------- main setting ---------------- # + + # base path setting + base_video_path = os.path.join('D:\\Roy\\GitHub\\Multitarget-tracker\\data\\') + base_code_path = os.path.join('D:\\Roy\\GitHub\\Multitarget-tracker\\') + + # execute file setting + exefile = 'MultitargetTracker_{0}_{1:.1f}.exe'.format(detector, threshold) + + # sorce video folder name setting + src_folder_name = 'videos' + src_video_name = 'video_{0}.avi'.format(video_num) + + # ------------- end of main setting ------------- # + + # execute file error checking + if not os.path.isfile(exefile): + adding_path = os.path.join(os.getcwd(), 'build', 'Release') + exefile = os.path.join(adding_path, exefile) + if not os.path.isfile(exefile): + print("ERROR: There's no {} file in current path".format(exefile)) + exit(-1) + + # detector keyword checking + if detector not in detector_list: + print("ERROR: There's no {} detector in my list".format(detector)) + exit(-1) + elif detector=='yolo': + example = 5 + extra_setting = '' + + elif detector == 'ssd': + example = 6 + + # extra setting for ssd + base_data_path = os.path.join(base_code_path, 'data') + deploy_name = 'ssd_ids_trained\\Deploy_Near.prototxt' + weight_name = 'ssd_ids_trained\\Near.caffemodel' + labelmap_name = 'ssd_ids_trained\\labelmap_Near.prototxt' + + deploy_path = os.path.join(base_data_path, deploy_name) + weight_path = os.path.join(base_data_path, weight_name) + labelmap_path = os.path.join(base_data_path, labelmap_name) + + extra_setting = "--deploy={0} --weights={1} --label-map={2}".format(deploy_path, weight_path, labelmap_path) + + elif detector == 'dw': + example = 6 + + # extra setting for ssd dw + base_data_path = os.path.join(base_code_path, 'data') + deploy_name = 'ssd_mobilenet_dw\\MobileNetSSD_deploy.prototxt' + weight_name = 'ssd_mobilenet_dw\\SSD_MOBILENET_V1_DW_VOC_iter_120000.caffemodel' + labelmap_name = 'ssd_mobilenet_dw\\labelmap_voc.prototxt' + + deploy_path = os.path.join(base_data_path, deploy_name) + weight_path = os.path.join(base_data_path, weight_name) + labelmap_path = os.path.join(base_data_path, labelmap_name) + + extra_setting = "--deploy={0} --weights={1} --label-map={2}".format(deploy_path, weight_path, labelmap_path) + + # base video path error checking + if not os.path.isdir(base_video_path): + print("ERROR: There's no folder : ".format(base_video_path)) + exit(-1) + + # sorce video path setting from sorce video name + src_folder_path = os.path.join(base_video_path, src_folder_name) + src_video_path = os.path.join(src_folder_path, src_video_name) + + # sorce video path error checking + if not os.path.isdir(src_folder_path): + print("ERROR: There's no folder : ".format(src_folder_path)) + exit(-1) + # sorce video file non-exist case checking + elif not os.path.isfile(src_video_path): + print("ERROR: There's no video file : ".format(src_video_path)) + exit(-1) + + dst_folder_name = src_folder_name + '_tracker_{0}_{1:.1f}'.format(detector, threshold) + dst_folder_path = os.path.join(base_video_path, dst_folder_name) + dst_video_name = 'video_{0}_{1}_{2:.1f}.{3}'.format(video_num, detector, threshold, dst_ext) + dst_video_path = os.path.join(dst_folder_path, dst_video_name) + + tmp_dst_foler_path = os.path.join(dst_folder_path, 'temp') + tmp_dst_video_path = os.path.join(tmp_dst_foler_path, dst_video_name) + + + # destination video folder checking. + if not os.path.isdir(dst_folder_path): + print("warning: There's no folder : ".format(dst_folder_path)) + os.makedirs(dst_folder_path) + print("So I created this one..") + + # make temp folder for converting video + if not os.path.isdir(tmp_dst_foler_path): + os.makedirs(tmp_dst_foler_path) + + # make command and combine with extra setting + command = "{0} {1} --example={2} --out={3} --end_delay=100 ".format(exefile, src_video_path, example, tmp_dst_video_path) + full_command = command + extra_setting + + # execute the full command + try: + print(full_command) + os.system(full_command) + except: + print("Command execute error !") + + # move the video file to out of the temp folder and delete temp folder + try: + if os.path.isfile(tmp_dst_video_path): + if os.path.isfile(dst_video_path): + os.remove(dst_video_path) + shutil.move(tmp_dst_video_path, dst_video_path) + os.rmdir(tmp_dst_foler_path) + except: + print("Unknown error !") + + + + + +if __name__=='__main__': + + # run_code(detector, threshold, video_num) + + #for i in range(1,3): + # run_code('ssd', 0.5, i) + + run_code('ssd', 0.5, 3) +