Darknet: use yolo_cpp_dll.dll in c# project

Created on 4 Jul 2017  路  24Comments  路  Source: AlexeyAB/darknet

Hi Alexey, i have trouble when include dll into c# project, i add this code into yolo_v2_class.cpp:
`//-------------------------------------------------------------------------------------------------------
struct array_bbox_t
{
int *boxArraySize;
std::vector *boxArray;
};

extern "C" {
YOLODLL_API void initDetector();
YOLODLL_API array_bbox_t detectFrame(image_t img, float thresh);
}

static Detector *instance = NULL;
YOLODLL_API void initDetector() {
instance = new Detector("yolo-voc.cfg", "yolo-voc.weights");
};

YOLODLL_API array_bbox_t detectFrame(image_t img, float thresh) {
std::vector detectOut = instance->detect(img, thresh);
int size = (int)detectOut.size();
array_bbox_t res;
res.boxArraySize = &size;
res.boxArray = &detectOut;
return res;
}
//------------------------------------------------------------------------------------------------------`

my c# code:
`class YoloBredge
{
[DllImport("yolo_cpp_dll.dll")]
public static extern void initDetector();

    [DllImport("yolo_cpp_dll.dll")]
    private static unsafe extern IntPtr detectFrame(image_t img, float thresh);


    struct image_t
    {
        public int h;                      // height
        public int w;                      // width
        public int c;                      // number of chanels (3 - for RGB)
        public unsafe float* data;         // pointer to the image data            
    };

    struct bbox_t
    {
        int x, y, w, h;    // (x,y) - top-left corner, (w, h) - width & height of bounded box
        float prob;                 // confidence - probability that the object was found correctly
        int obj_id;        // class of object - from range [0, classes-1]
        int track_id;      // tracking id for video (0 - untracked, 1 - inf - tracked object)
    };

    private static image_t convertImage(Bitmap bmp)
    {
        BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        image_t res = new image_t();
        res.h = bmp.Height;
        res.w = bmp.Width;
        res.c = 3;
        unsafe
        {
            res.data = (float*)data.Scan0;
        }
        bmp.UnlockBits(data);
        return res;
    }

    public struct array_bbox_t
    {
        public IntPtr boxArraySize;
        public IntPtr boxArray;
    }

    public YoloBredge()
    {
        initDetector();
        IntPtr pr = detectFrame(convertImage(new Bitmap("2.jpg")), 0.2f);
        if (pr == IntPtr.Zero)
        {
            throw new Exception("native error!");
        }
        array_bbox_t r = (array_bbox_t)Marshal.PtrToStructure(pr, typeof(array_bbox_t));
        bbox_t[] points = new bbox_t[checked((int)(long)r.boxArraySize)];
        for (int i = 0; i < points.Length; ++i)
        {
            points[i] = (bbox_t)Marshal.PtrToStructure(r.boxArray + Marshal.SizeOf(typeof(bbox_t)) * i, typeof(bbox_t));
        }



    }`

when i set breakpoint and see "r" then r.boxArraySize and r.boxArray is zero, i dont know why?

All 24 comments

Hi I have tried your C# project it failed at
IntPtr pr = detectFrame(convertImage(new Bitmap("2.jpg")), 0.2f);
with an access violation error on it
Do you have any idea with that?

I solved this problem:
step 1 - i find point bitmap data:
BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); IntPtr sourcePoint = data.Scan0;
and send sourcePoint to dll with height and width image
step 2 - in dll i create cv::Mat image:
cv::Mat original = cv::Mat(width, height, CV_8UC4, imgData);
step 3 after detect i return result to c#:
std::vector<bbox_t> detectOut = instance->detect(original, thresh); *hItems = reinterpret_cast<intptr_t>(&detectOut); *itemsFound = detectOut.data(); *itemCount = detectOut.size();
sorry for my English =)

Hi I have tried to catch you idea but it seems not really working with the dll , if it is possible could you share you sample codes ? my email [email protected] Cheers :)

replace cpp and hpp files in darknet project and build it, copy dll into c# Debug/Release dir use YoloBridge for detect objects, as:
Bitmap source = new Bitmap("9.jpg"); var b = new YoloBridge(); bbox_t[] result = b.detect(source); b = null;

YoloBridge.zip

Sorry for another trouble shoot.... I have tried exactly you have told, put the dll into c# Debug/Release dir had run the C# app when it goes to var b= new YoloBridge(); it came out an error that System.EntryPointNotFoundException Could not load DLL "yolo_cpp_dll.dll": Can not find the specified module. I have check it for many way but it seems not work still. Maybe I am missing some dependency or ?

Have you copied all the cuda and opencv dlls from darknet into your c # project? also need copy .cfg and .weights files

Thank you :) I work it out it with the opencv dll

Hi I find a problem with the output of detected bbox_t item that it's coordinate are based on the re-sized image rather than the original image size, And the input Image has to be re-size to a square ratio otherwise there would be no output item or failed with detect?

Hi, I do not know why the detection does not work if the picture has a different screen size ratio, if you solve this problem, please share the result =)

OK it seems this is a problem to solve :)

Hi I got a way to fix the problem but maybe not the best
the general idea is to find the distort ratio and repair the result data to Image size

int BoxSize = ImgWidth < ImgHeight ? ImgWidth : ImgHeight;
float ratioX = (float)BoxSize / (float)ImgWidth;
float ratioY = (float)BoxSize / (float)ImgHeight;
int x = (int)(box.x / ratioX); int y = (int)(box.y / ratioY); int w = (int)(box.w / ratioX); int h = (int)(box.h / ratioY);

I tried your code (in the zip file), but all I get is The program '' has exited with code -1 (0xffffffff). when it reaches instance = new Detector(cfgPath, weightsPath);.

Any ideas?

This works for the old version of the code, at the beginning of this topic.

@Nfear Did you replace files yolo_v2_class.cpp and yolo_v2_class.hpp in Darknet /src/ from zip-archive before compile DLL?

@AlexeyAB Yes I have. It seems it cannot find opencv2/opencv.hpp

EDIT:

Managed to fix the opencv import by changing the path, but I get the same -1 error code as before when calling initDetector. If I call closeDetector it doesn't crash.

@Nfear Hey, how did you fix that path issue?

Edit:
Found the solution on here
https://stackoverflow.com/questions/21500725/visual-studio-2012-opencv2-opencv-hpp-no-such-file-or-directory-c1083

Edit:
You will also need to include OpenCV2.4.9.* using NuGet packages to get the .lib files

@Nfear Hey, did you ever manage to figure out the initDetector issue? I am having the same problem.
https://github.com/AlexeyAB/darknet/issues/118#issuecomment-322406280

My program crashes/closes the second I run the initDetector function.

Edit:
I did change the version of OpenCV to 249 from 2413 in detector.c, but that did not help.

Edit:
I tried to use this version and it did not work either ( July 14th commit )
https://github.com/AlexeyAB/darknet/tree/9920410ba9cc756c46d6ee84f7b7a2a9fe941448
https://github.com/AlexeyAB/darknet/issues/118#issuecomment-322224781

@xinvestoriginal I do not have any cuda dlls only the opencv ones that I got after I compiled the yolo_cpp_dll.dll

Edit:
I tried to copy in cudnn64_6.dll to the folder, but my issue still persists.
https://github.com/AlexeyAB/darknet/issues/118#issuecomment-326766277

It would be nice if someone could upload their compiled yolo_cpp_dll.dll and or the versions of cuda, cudnn, and opencv that they were using. Thanks

Make sure you have a CUDA compatible GPU. I had to build yolo_cpp_dll_no_gpu to get it to run. Easiest way for me to get meaningful errors was to set the project output type to Console Application.

AlexyAB and xinvestoriginal , Help needed, please :)
I can't marriage Cpp dll and C# app.
Strange result coming up. I have right expected results for installed/compiled app. For all possible CMDs. It means the environment installed correct and app compiled well
Except one. Could you, please look into YoloBridge.zip "add-on" and confirm you have identical results.
In my environment I have:

############# ORIGINAL yolo_console_dll.exe Console App
    . . . . . . . .
    29 conv   1024  3 x 3 / 1    13 x  13 x1280   ->    13 x  13 x1024
    30 conv    125  1 x 1 / 1    13 x  13 x1024   ->    13 x  13 x 125
    31 detection
    Loading weights from yolo-voc.weights...Done!
    object names loaded
    input image or video filename: data/dog.jpg
    car -   obj_id = 6,  x = 443, y = 73,  w = 247, h = 98,  prob = 0.751
    bicycle -   obj_id = 1,  x = 208, y = 149, w = 350, h = 281, prob = 0.779
    dog -   obj_id = 11, x = 105, y = 191, w = 216, h = 350, prob = 0.904
    input image or video filename:
    . . . . . . . . .

################### ORIGINAL yolo_console_dll.exe Console App ###################
YoloBridge for dog.jpg in the same environment comes up with this:
opencv_3.3/yolo_cpp_dll: ObjId: 8, Accuracy: 0.28%, Rect: P(24,142), S(606,614), TrackId: 0
opencv_2.4.13/yolo_cpp_dll: ObjId: 8, Accuracy: 0.28%, Rect: P(24,142), S(606,614), TrackId: 0

Well, I get only one detcted object (3 expected), with absolutely different results. I'm not strong in Cpp and couldn't overcome "attempt to read or write protected memory...", "cannot marshal return value", "external component has thrown an exception" etc ...
I tried with and without GPU modes, diff openCV versions - results are the same ...
It looks like bitmap data changed/corrupted/misformatted somehow getting IntPtr .
and/or bbox_t* itemsFound (on C# side) gets only 1 item (array expected)
Please advise with your advice :)

Do/did you have identical results?
What do you think, please ?

I'm having a strange problem.

I'm using the dll with a c# service perfectly in visual studio 2015 in debug mode. Everything runs great.

If I try to compile as a release I can install the service but receive a 1067 error when I'm trying to start the service.

I isolated the error and it's being caused by the initdetector.

Why is it happening only in release mode. I compiled correctly as release the dll. it's x64 also both the dll and service.

If anyone can help me.

Thanks.

I have the same problem with the yolo_cpp_dll.dll i have compiled without gpu support. I have this error System.EntryPointNotFoundException.

We have create a own project without gpu support. But i search a version with gpu support.
https://github.com/AlturosDestinations/Alturos.Yolo

Now Alturos.Yolo use AlexeyAB yolo dll with gpu support

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Jacky3213 picture Jacky3213  路  3Comments

jasleen137 picture jasleen137  路  3Comments

shootingliu picture shootingliu  路  3Comments

Cipusha picture Cipusha  路  3Comments

hemp110 picture hemp110  路  3Comments