diff --git a/.gitignore b/.gitignore index aec8d07..917df1e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,7 @@ src/Socket/a.out src/C++/Driver/cmake_install.cmake src/C++/Socket/a.out src/C++/Driver/Makefile -src/C++/Driver/vgcore* +vgcore* src/C++/Driver/cmake_install.cmake src/C++/Driver/Makefile src/C++/Driver/log diff --git a/docs/code/OpenCV.md b/docs/code/OpenCV.md index 29bc401..5b087a2 100644 --- a/docs/code/OpenCV.md +++ b/docs/code/OpenCV.md @@ -1,8 +1,20 @@ # OpenCV +## Requirements +For the camera we want it to detect what is happening on the video feed and identify it so it can identify dangers. +## Issues + +* OpenCL not grabbing gpu +* Solution: https://github.com/Smorodov/Multitarget-tracker/issues/93 ## Installation ### Dependencies * glew -* opencv \ No newline at end of file +* opencv + + + + +## Sources +* https://github.com/UnaNancyOwen/OpenCVDNNSample/tree/master \ No newline at end of file diff --git a/src/C++/MQTT/CMakeLists.txt b/src/C++/MQTT/CMakeLists.txt deleted file mode 100644 index 1f31293..0000000 --- a/src/C++/MQTT/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -set(CMAKE_CXX_STANDARD 23) - -# Find the Paho MQTT C++ library -find_library(PAHO_MQTTPP_LIBRARY paho-mqttpp3 PATHS /usr/local/lib) -find_library(PAHO_MQTT_LIBRARY paho-mqtt3a PATHS /usr/local/lib) - -# Include the headers -include_directories(/usr/local/include) - -# Add the executable -add_executable(my_program main.cpp) - -# Link the libraries -target_link_libraries(my_program ${PAHO_MQTTPP_LIBRARY} ${PAHO_MQTT_LIBRARY}) diff --git a/src/C++/MQTT/main.cpp b/src/C++/MQTT/main.cpp deleted file mode 100644 index 94747e9..0000000 --- a/src/C++/MQTT/main.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include // For std::this_thread::sleep_for -#include // For std::chrono::seconds - -// Define the address of the MQTT broker, the client ID, and the topic to subscribe to. -const std::string ADDRESS("mqtt://localhost:1883"); // Broker address (Raspberry Pi) -const std::string CLIENT_ID("raspberry_pi_client"); -const std::string TOPIC("home/commands"); - -// Define a callback class that handles incoming messages and connection events. -class callback : public virtual mqtt::callback { - // Called when a message arrives on a subscribed topic. - void message_arrived(mqtt::const_message_ptr msg) override { - std::cout << "Received message: '" << msg->get_topic()<< "' : " << msg->to_string() << std::endl; - } - - // Called when the connection to the broker is lost. - void connection_lost(const std::string& cause) override { - std::cerr << "Connection lost. Reason: " << cause << std::endl; - } - - // Called when a message delivery is complete. - void delivery_complete(mqtt::delivery_token_ptr token) override { - std::cout << "Message delivered!" << std::endl; - } -}; - -int main() { - // Create an MQTT async client and set up the callback class. - mqtt::async_client client(ADDRESS, CLIENT_ID); - callback cb; - client.set_callback(cb); - - // Set up the connection options (such as username and password). - mqtt::connect_options connOpts; - connOpts.set_clean_session(true); - connOpts.set_user_name("ishak"); - connOpts.set_password("kobuki"); - connOpts.set_mqtt_version(MQTTVERSION_3_1_1); - - try { - // Try to connect to the broker and wait until successful. - std::cout << "Connecting to broker..." << std::endl; - client.connect(connOpts)->wait(); // Connect with the provided options - std::cout << "Connected!" << std::endl; - - // Subscribe to the specified topic and wait for confirmation. - std::cout << "Subscribing to topic: " << TOPIC << std::endl; - client.subscribe(TOPIC, 1)->wait(); // Subscribe with QoS level 1 - - // Keep the program running to continue receiving messages from the broker. - while (true) { - std::this_thread::sleep_for(std::chrono::seconds(1)); // Sleep to reduce CPU usage - } - - } catch (const mqtt::exception &exc) { - // Catch any MQTT exceptions and display the error message. - std::cerr << "Error: " << exc.what() << std::endl; - return 1; - } - - return 0; // Return 0 to indicate successful execution -} diff --git a/src/C++/OpenCV/CMakeLists.txt b/src/C++/OpenCV/CMakeLists.txt index 0cc8e30..ac79831 100644 --- a/src/C++/OpenCV/CMakeLists.txt +++ b/src/C++/OpenCV/CMakeLists.txt @@ -1,9 +1,44 @@ -cmake_minimum_required(VERSION 2.8) -project( main ) +cmake_minimum_required( VERSION 3.6 ) + +# Require C++11 (or later) +set( CMAKE_CXX_STANDARD 23 ) +set( CMAKE_CXX_STANDARD_REQUIRED ON ) +set( CMAKE_CXX_EXTENSIONS OFF ) +set(BUILD_MODE Debug) +# Create Project +project( Sample ) +add_executable( YOLOv4 util.h main.cpp ) + +# Set StartUp Project +set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "YOLOv4" ) + +# Find Package +# OpenCV find_package( OpenCV REQUIRED ) -include_directories( ${OpenCV_INCLUDE_DIRS} ) -add_executable( main main.cpp ) -target_link_libraries( main ${OpenCV_LIBS} ) + +if( OpenCV_FOUND ) + # Additional Include Directories + include_directories( ${OpenCV_INCLUDE_DIRS} ) + + # Additional Dependencies + target_link_libraries( YOLOv4 ${OpenCV_LIBS} ) +endif() + +# Download Model +set( MODEL https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights ) +file( DOWNLOAD + "${MODEL}" + "${CMAKE_CURRENT_LIST_DIR}/yolov4.weights" + EXPECTED_HASH SHA256=e8a4f6c62188738d86dc6898d82724ec0964d0eb9d2ae0f0a9d53d65d108d562 + SHOW_PROGRESS +) -#sauce: https://docs.opencv.org/4.x/db/df5/tutorial_linux_gcc_cmake.html \ No newline at end of file +# Download Config +set( CONFIG https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov4.cfg ) +file( DOWNLOAD + "${CONFIG}" + "${CMAKE_CURRENT_LIST_DIR}/yolov4.cfg" + EXPECTED_HASH SHA256=a6d0f8e5c62cc8378384f75a8159b95fa2964d4162e33351b00ac82e0fc46a34 + SHOW_PROGRESS +) diff --git a/src/C++/OpenCV/OpenCV.cpp b/src/C++/OpenCV/OpenCV.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/C++/OpenCV/OpenCV.hpp b/src/C++/OpenCV/OpenCV.hpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/C++/OpenCV/YOLOv4 b/src/C++/OpenCV/YOLOv4 new file mode 100755 index 0000000..943662c Binary files /dev/null and b/src/C++/OpenCV/YOLOv4 differ diff --git a/src/C++/OpenCV/coco.names b/src/C++/OpenCV/coco.names new file mode 100644 index 0000000..ca76c80 --- /dev/null +++ b/src/C++/OpenCV/coco.names @@ -0,0 +1,80 @@ +person +bicycle +car +motorbike +aeroplane +bus +train +truck +boat +traffic light +fire hydrant +stop sign +parking meter +bench +bird +cat +dog +horse +sheep +cow +elephant +bear +zebra +giraffe +backpack +umbrella +handbag +tie +suitcase +frisbee +skis +snowboard +sports ball +kite +baseball bat +baseball glove +skateboard +surfboard +tennis racket +bottle +wine glass +cup +fork +knife +spoon +bowl +banana +apple +sandwich +orange +broccoli +carrot +hot dog +pizza +donut +cake +chair +sofa +pottedplant +bed +diningtable +toilet +tvmonitor +laptop +mouse +remote +keyboard +cell phone +microwave +oven +toaster +sink +refrigerator +book +clock +vase +scissors +teddy bear +hair drier +toothbrush diff --git a/src/C++/OpenCV/main.cpp b/src/C++/OpenCV/main.cpp index 587ca89..2f340fe 100644 --- a/src/C++/OpenCV/main.cpp +++ b/src/C++/OpenCV/main.cpp @@ -1,31 +1,209 @@ -#include -#include -#include -#include "opencv4/opencv2/imgproc/imgproc.hpp" #include #include +#include +#include +#include +#include +#include -using namespace cv; -using namespace std; +#include "util.h" +// Helper function to check if a file exists +bool fileExists(const std::string &path) +{ + return std::filesystem::exists(path); +} -int main() { - Mat myImage; //Declaring a matrix to load the frames - namedWindow("Video Player"); //Declaring the video to show the video// - VideoCapture cap(0); //Declaring an object to capture stream of frames from default camera// - if (!cap.isOpened()){ //This section prompt an error message if no video stream is found// - cout << "No video stream detected" << endl; - system("pause"); - return-1; - } - while (true){ - cap >> myImage; // - if (myImage.empty()){ //Breaking the loop if no video frame is detected// - break; - } - imshow("Video Player", myImage); //Showing the video// - char c = (char)waitKey(25); //Allowing 25 milliseconds frame processing time and initiating break condition// - } - cap.release(); //Releasing the buffer memory// - return 0; -} \ No newline at end of file +// Function to read class names from a file +std::vector _readClassNameList(const std::string &path) +{ + std::vector classes; + + // Check if file exists + if (!fileExists(path)) + { + throw std::runtime_error("Class names file not found: " + path); + } + + // Try to open and read file + std::ifstream file(path); + if (!file.is_open()) + { + throw std::runtime_error("Unable to open class names file: " + path); + } + + std::string line; + while (std::getline(file, line)) + { + if (!line.empty()) + { + classes.push_back(line); + } + } + + if (classes.empty()) + { + throw std::runtime_error("No classes found in file: " + path); + } + + return classes; +} + +int main(int argc, char *argv[]) +{ + try + { + // Open Video Capture + cv::VideoCapture capture = cv::VideoCapture(0); + if (!capture.isOpened()) + { + std::cerr << "Failed to open camera device" << std::endl; + return -1; + } + + // Read Class Name List and Color Table + const std::string list = "coco.names"; + const std::vector classes = _readClassNameList(list); + const std::vector colors = getClassColors(classes.size()); + + // Debug: Print the size of the colors vector + std::cout << "Number of colors: " << colors.size() << std::endl; + + // Read Darknet + const std::string model = "yolov4.weights"; + const std::string config = "yolov4.cfg"; + cv::dnn::Net net = cv::dnn::readNet(model, config); + if (net.empty()) + { + std::cerr << "Failed to load network" << std::endl; + return -1; + } + + // Set Preferable Backend + net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV); + + // Set Preferable Target + net.setPreferableTarget(cv::dnn::DNN_TARGET_OPENCL); + + while (true) + { + // Read Frame + cv::Mat frame; + capture >> frame; + if (frame.empty()) + { + cv::waitKey(0); + break; + } + if (frame.channels() == 4) + { + cv::cvtColor(frame, frame, cv::COLOR_BGRA2BGR); + } + + // Create Blob from Input Image + cv::Mat blob = cv::dnn::blobFromImage(frame, 1 / 255.f, cv::Size(416, 416), cv::Scalar(), true, false); + + // Set Input Blob + net.setInput(blob); + + // Run Forward Network + std::vector detections; + net.forward(detections, getOutputsNames(net)); + + // Draw Region + std::vector class_ids; + std::vector confidences; + std::vector rectangles; + for (cv::Mat &detection : detections) + { + if (detection.empty()) + { + std::cerr << "Detection matrix is empty!" << std::endl; + continue; + } + for (int32_t i = 0; i < detection.rows; i++) + { + cv::Mat region = detection.row(i); + + // Retrieve Max Confidence and Class Index + cv::Mat scores = region.colRange(5, detection.cols); + cv::Point class_id; + double confidence; + cv::minMaxLoc(scores, 0, &confidence, 0, &class_id); + + // Check Confidence + constexpr float threshold = 0.2; + if (threshold > confidence) + { + continue; + } + + // Retrieve Object Position + const int32_t x_center = static_cast(region.at(0) * frame.cols); + const int32_t y_center = static_cast(region.at(1) * frame.rows); + const int32_t width = static_cast(region.at(2) * frame.cols); + const int32_t height = static_cast(region.at(3) * frame.rows); + const cv::Rect rectangle = cv::Rect(x_center - (width / 2), y_center - (height / 2), width, height); + + // Add Class ID, Confidence, Rectangle + class_ids.push_back(class_id.x); + confidences.push_back(confidence); + rectangles.push_back(rectangle); + } + } + + // Remove Overlap Rectangles using Non-Maximum Suppression + constexpr float confidence_threshold = 0.5; // Confidence + constexpr float nms_threshold = 0.5; // IoU (Intersection over Union) + std::vector indices; + cv::dnn::NMSBoxes(rectangles, confidences, confidence_threshold, nms_threshold, indices); + + // Draw Rectangle + for (const int32_t &index : indices) + { + // Bounds checking + if (class_ids[index] >= colors.size()) + { + std::cerr << "Color index out of bounds: " << class_ids[index] << " (max: " << colors.size() - 1 << ")" << std::endl; + continue; + } + + const cv::Rect rectangle = rectangles[index]; + const cv::Scalar color = colors[class_ids[index]]; + + // Debug: Print the index and color + std::cout << "Drawing rectangle with color index: " << class_ids[index] << std::endl; + + constexpr int32_t thickness = 3; + cv::rectangle(frame, rectangle, color, thickness); + + std::string label = classes[class_ids[index]] + ": " + std::to_string(static_cast(confidences[index] * 100)) + "%"; + + int baseLine; + cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + int top = std::max(rectangle.y, labelSize.height); + cv::rectangle(frame, cv::Point(rectangle.x, top - labelSize.height), + cv::Point(rectangle.x + labelSize.width, top + baseLine), color, cv::FILLED); + cv::putText(frame, label, cv::Point(rectangle.x, top), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 255, 255), 1); + } + + // Show Image + cv::imshow("Object Detection", frame); + const int32_t key = cv::waitKey(1); + if (key == 'q') + { + break; + } + } + + cv::destroyAllWindows(); + return 0; + } + catch (const std::exception &e) + { + std::cerr << "Error: " << e.what() << std::endl; + return -1; + } +} + +// cloned and fixed from https://github.com/UnaNancyOwen/OpenCVDNNSample/tree/master \ No newline at end of file diff --git a/src/C++/OpenCV/util.h b/src/C++/OpenCV/util.h new file mode 100644 index 0000000..cfbf904 --- /dev/null +++ b/src/C++/OpenCV/util.h @@ -0,0 +1,61 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include +#include +#include +#include +#include + +// Get Output Layers Name +std::vector getOutputsNames( const cv::dnn::Net& net ) +{ + static std::vector names; + if( names.empty() ){ + std::vector out_layers = net.getUnconnectedOutLayers(); + std::vector layers_names = net.getLayerNames(); + names.resize( out_layers.size() ); + for( size_t i = 0; i < out_layers.size(); ++i ){ + names[i] = layers_names[out_layers[i] - 1]; + } + } + return names; +} + +// Get Output Layer Type +std::string getOutputLayerType( cv::dnn::Net& net ) +{ + const std::vector out_layers = net.getUnconnectedOutLayers(); + const std::string output_layer_type = net.getLayer( out_layers[0] )->type; + return output_layer_type; +} + +// Read Class Name List +std::vector readClassNameList( const std::string list_path ) +{ + std::vector classes; + std::ifstream ifs( list_path ); + if( !ifs.is_open() ){ + return classes; + } + std::string class_name = ""; + while( std::getline( ifs, class_name ) ){ + classes.push_back( class_name ); + } + return classes; +} + +// Get Class Color Table for Visualize +std::vector getClassColors( const int32_t number_of_colors ) +{ + cv::RNG random; + std::vector colors; + for( int32_t i = 0; i < number_of_colors; i++ ){ + cv::Scalar color( random.uniform( 0, 255 ), random.uniform( 0, 255 ), random.uniform( 0, 255 ) ); + colors.push_back( color ); + } + return colors; +} + +#endif // __UTIL__ diff --git a/src/C++/OpenCV/yolov4.cfg b/src/C++/OpenCV/yolov4.cfg new file mode 100644 index 0000000..a7be12b --- /dev/null +++ b/src/C++/OpenCV/yolov4.cfg @@ -0,0 +1,1158 @@ +[net] +batch=64 +subdivisions=8 +# Training +#width=512 +#height=512 +width=608 +height=608 +channels=3 +momentum=0.949 +decay=0.0005 +angle=0 +saturation = 1.5 +exposure = 1.5 +hue=.1 + +learning_rate=0.0013 +burn_in=1000 +max_batches = 500500 +policy=steps +steps=400000,450000 +scales=.1,.1 + +#cutmix=1 +mosaic=1 + +#:104x104 54:52x52 85:26x26 104:13x13 for 416 + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=mish + +# Downsample + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=2 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -2 + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=32 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -1,-7 + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +# Downsample + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=2 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -2 + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -1,-10 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +# Downsample + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=2 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -2 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -1,-28 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +# Downsample + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=2 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -2 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -1,-28 + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +# Downsample + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=2 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -2 + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -1,-16 + +[convolutional] +batch_normalize=1 +filters=1024 +size=1 +stride=1 +pad=1 +activation=mish + +########################## + +[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 + +### SPP ### +[maxpool] +stride=1 +size=5 + +[route] +layers=-2 + +[maxpool] +stride=1 +size=9 + +[route] +layers=-4 + +[maxpool] +stride=1 +size=13 + +[route] +layers=-1,-3,-5,-6 +### End SPP ### + +[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 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = 85 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -1, -3 + +[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 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = 54 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -1, -3 + +[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=255 +activation=linear + + +[yolo] +mask = 0,1,2 +anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401 +classes=80 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +scale_x_y = 1.2 +iou_thresh=0.213 +cls_normalizer=1.0 +iou_normalizer=0.07 +iou_loss=ciou +nms_kind=greedynms +beta_nms=0.6 +max_delta=5 + + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +size=3 +stride=2 +pad=1 +filters=256 +activation=leaky + +[route] +layers = -1, -16 + +[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=255 +activation=linear + + +[yolo] +mask = 3,4,5 +anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401 +classes=80 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +scale_x_y = 1.1 +iou_thresh=0.213 +cls_normalizer=1.0 +iou_normalizer=0.07 +iou_loss=ciou +nms_kind=greedynms +beta_nms=0.6 +max_delta=5 + + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +size=3 +stride=2 +pad=1 +filters=512 +activation=leaky + +[route] +layers = -1, -37 + +[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=255 +activation=linear + + +[yolo] +mask = 6,7,8 +anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401 +classes=80 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +random=1 +scale_x_y = 1.05 +iou_thresh=0.213 +cls_normalizer=1.0 +iou_normalizer=0.07 +iou_loss=ciou +nms_kind=greedynms +beta_nms=0.6 +max_delta=5 + diff --git a/src/C++/OpenCV/yolov4.weights b/src/C++/OpenCV/yolov4.weights new file mode 100644 index 0000000..921f440 Binary files /dev/null and b/src/C++/OpenCV/yolov4.weights differ