Alexey
2018-06-24 24c889d85705643ca4860dea88827a7f1893b731
Merge pull request #1085 from tinohager/master

.NET/C# support integration
3 files modified
1 files added
142 ■■■■■ changed files
.gitignore 3 ●●●● patch | view | raw | blame | history
build/darknet/YoloWrapper.cs 83 ●●●●● patch | view | raw | blame | history
src/yolo_v2_class.cpp 45 ●●●●● patch | view | raw | blame | history
src/yolo_v2_class.hpp 11 ●●●●● patch | view | raw | blame | history
.gitignore
@@ -14,7 +14,8 @@
decaf/
submission/
cfg/
darknet
build/darknet/*
!build/darknet/YoloWrapper.cs
.fuse*
# OS Generated #
build/darknet/YoloWrapper.cs
New file
@@ -0,0 +1,83 @@
using System;
using System.Runtime.InteropServices;
namespace Darknet
{
    public class YoloWrapper : IDisposable
    {
        private const string YoloLibraryName = "yolo_cpp_dll.dll";
        [DllImport(YoloLibraryName, EntryPoint = "init")]
        public static extern int InitializeYolo(string configurationFilename, string weightsFilename, int gpu);
        [DllImport(YoloLibraryName, EntryPoint = "detect_image")]
        public static extern int DetectImage(string filename, ref BboxContainer container);
        [DllImport(YoloLibraryName, EntryPoint = "detect_mat")]
        public static extern int DetectImage(IntPtr pArray, int nSize, ref BboxContainer container);
        [DllImport(YoloLibraryName, EntryPoint = "dispose")]
        public static extern int DisposeYolo();
        [StructLayout(LayoutKind.Sequential)]
        public struct bbox_t
        {
            public UInt32 x, y, w, h;    // (x,y) - top-left corner, (w, h) - width & height of bounded box
            public float prob;                 // confidence - probability that the object was found correctly
            public UInt32 obj_id;        // class of object - from range [0, classes-1]
            public UInt32 track_id;      // tracking id for video (0 - untracked, 1 - inf - tracked object)
            public UInt32 frames_counter;
        };
        [StructLayout(LayoutKind.Sequential, Size = 10)]
        public struct BboxContainer
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public bbox_t[] candidates;
        }
        public YoloWrapper(string configurationFilename, string weightsFilename, int gpu)
        {
            InitializeYolo(configurationFilename, weightsFilename, gpu);
        }
        public void Dispose()
        {
            DisposeYolo();
        }
        public bbox_t[] Detect(string filename)
        {
            var container = new BboxContainer();
            var count = DetectImage(filename, ref container);
            return container.candidates;
        }
        public bbox_t[] Detect(byte[] imageData)
        {
            var container = new BboxContainer();
            var size = Marshal.SizeOf(imageData[0]) * imageData.Length;
            var pnt = Marshal.AllocHGlobal(size);
            try
            {
                // Copy the array to unmanaged memory.
                Marshal.Copy(imageData, 0, pnt, imageData.Length);
                DetectImage(pnt, imageData.Length, ref container);
            }
            catch (Exception exception)
            {
                return null;
            }
            finally
            {
                // Free the unmanaged memory.
                Marshal.FreeHGlobal(pnt);
            }
            return container.candidates;
        }
    }
}
src/yolo_v2_class.cpp
@@ -22,6 +22,51 @@
#define FRAMES 3
int max_objects() { return C_SHARP_MAX_OBJECTS; }
static Detector* detector;
//static std::unique_ptr<Detector> detector;
int init(const char *configurationFilename, const char *weightsFilename, int gpu) {
    std::string configurationFilenameString;
    configurationFilenameString = configurationFilename;
    std::string weightsFilenameString;
    weightsFilenameString = weightsFilename;
    detector = new Detector(configurationFilenameString, weightsFilenameString, gpu);
    return 1;
}
int detect_image(const char *filename, bbox_t_container &container) {
    std::string filenameString;
    filenameString = filename;
    std::vector<bbox_t> detection = detector->detect(filenameString);
    for (size_t i = 0; i < detection.size() && i < C_SHARP_MAX_OBJECTS; ++i)
        container.candidates[i] = detection[i];
    return detection.size();
}
int detect_mat(const uint8_t* data, const size_t data_length, bbox_t_container &container) {
#ifdef OPENCV
    std::vector<char> vdata(data, data + data_length);
    cv::Mat image = imdecode(cv::Mat(vdata), 1);
    std::vector<bbox_t> detection = detector->detect(image);
    for (size_t i = 0; i < detection.size() && i < C_SHARP_MAX_OBJECTS; ++i)
        container.candidates[i] = detection[i];
    return detection.size();
#else
    return -1;
#endif  // OPENCV
}
int dispose() {
    detector->~Detector();
    //detector.reset();
    return 1;
}
#ifdef GPU
void check_cuda(cudaError_t status) {
    if (status != cudaSuccess) {
src/yolo_v2_class.hpp
@@ -28,6 +28,11 @@
    float *data;                // pointer to the image data
};
#define C_SHARP_MAX_OBJECTS 1000
struct bbox_t_container {
    bbox_t candidates[C_SHARP_MAX_OBJECTS];
};
#ifdef __cplusplus
#include <memory>
#include <vector>
@@ -40,6 +45,12 @@
#include "opencv2/imgproc/imgproc_c.h"  // C
#endif  // OPENCV
extern "C" YOLODLL_API int max_objects();
extern "C" YOLODLL_API int init(const char *configurationFilename, const char *weightsFilename, int gpu);
extern "C" YOLODLL_API int detect_image(const char *filename, bbox_t_container &container);
extern "C" YOLODLL_API int detect_mat(const uint8_t* data, const size_t data_length, bbox_t_container &container);
extern "C" YOLODLL_API int dispose();
class Detector {
    std::shared_ptr<void> detector_gpu_ptr;
    std::deque<std::vector<bbox_t>> prev_bbox_vec_deque;