Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error using Marshal.Copy method #112

Closed
omdxp opened this issue May 28, 2019 · 25 comments
Closed

Error using Marshal.Copy method #112

omdxp opened this issue May 28, 2019 · 25 comments
Assignees
Labels

Comments

@omdxp
Copy link

omdxp commented May 28, 2019

Summary of your issue

Well, I was trying your example WebcamFacePose and then I got an error while using Marshal.Copy method that it said: "Argument 1 : cannot convert from 'System.Array' to 'int[]'"

Environment

.NET Framework 4.6.1

@takuya-takeuchi
Copy link
Owner

It is similar with #87?

@takuya-takeuchi
Copy link
Owner

@Omar-Belghaouti
Does it occur everytime?

If the 1st argument of Marshal.Copy is Int32[], 2nd argment must be Int32.
https://docs.microsoft.com/ja-jp/dotnet/api/system.runtime.interopservices.marshal.copy?view=netframework-4.6.1

But in https://github.com/takuya-takeuchi/DlibDotNet/blob/master/examples/WebcamFacePose/Program.cs#L52 , 1st is IntPtr and 2nd is byte[].
It should occur compile error before executing.

@omdxp
Copy link
Author

omdxp commented May 28, 2019

No it's not throwing an exception, it's not running at all. When I use temp.Data as an argument it get me that error above.

The thing is I have a program written in python that use dlib library to detect hand with a trained model as below:

import dlib
import cv2

detector = dlib.simple_object_detector('hand.svm')

cv2.namedWindow('frame', cv2.WINDOW_NORMAL)

cap = cv2.VideoCapture(0)
rscale = 2.0

while (True):
    ret, frame = cap.read()
    width, height, _ = frame.shape

    ft = cv2.resize(frame, (int(frame.shape[1] / rscale), int(frame.shape[0] / rscale)))
    dets = detector(ft)

    for d in dets:
        cv2.rectangle(frame, (int(d.left()*rscale),
                              int(d.top()*rscale)),
                              (int(d.right()*rscale),
                              int(d.bottom()*rscale)),
                              (255, 0, 0), 5)

    cv2.imshow('frame', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

And I want to do it with DlibDotNet

@omdxp
Copy link
Author

omdxp commented May 28, 2019

Is this a way to avoid that error?

var temp = new Mat();
                    capture.Read(temp);

                    byte[] data = (byte[])temp.Data;
                    var array = new byte[temp.Width * temp.Height * temp.ElementSize];

                    int size = Marshal.SizeOf(data[0]) * data.Length;

                    IntPtr pnt = Marshal.AllocHGlobal(size);

                    try
                    {
                        Marshal.Copy(data, 0, pnt, data.Length);

                        Marshal.Copy(pnt, array, 0, array.Length);
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(pnt);
                    }

@takuya-takeuchi
Copy link
Owner

byte[] data = (byte[])temp.Data;

Is it correct? It must be compile error.

@omdxp
Copy link
Author

omdxp commented May 28, 2019

No it execute normally

@takuya-takeuchi
Copy link
Owner

Wait. What is Mat? I think Mat does not have ElementSize.

@omdxp
Copy link
Author

omdxp commented May 28, 2019

I forgot to tell you that I'm using EmguCV wrapper not OpenCVSharp

@takuya-takeuchi
Copy link
Owner

Ops, I have never used EmguCV.
But EmguCV.Mat look like to have DataPointer property.
http://www.emgu.com/wiki/files/3.1.0/document/html/a4426997-e646-4f87-8ce7-793a6c62fc1b.htm

It may help you.

Marshal.Copy(temp.DataPointer, array, 0, array.Length);

@omdxp
Copy link
Author

omdxp commented May 28, 2019

Thank you, I'll try it and tell you the results

@takuya-takeuchi
Copy link
Owner

Or
http://www.emgu.com/wiki/files/3.1.0/document/html/3fbad597-8949-3c0e-1477-a41a6f3a330c.htm

@omdxp
Copy link
Author

omdxp commented May 28, 2019

I tried the first method temp.DataPointer and it works fine

@omdxp
Copy link
Author

omdxp commented May 28, 2019

Could you add an example of hand detection using DlibDotNet the way as I did it in Python?

@omdxp
Copy link
Author

omdxp commented May 28, 2019

Both methods works fine

@takuya-takeuchi
Copy link
Owner

I may be able to write sample code to detect hand.
But

  • I do not know where is model file to detect human hand

Where did you get hand.svm file from? If license of model file is unknown, I can not accept your request?

@omdxp
Copy link
Author

omdxp commented May 28, 2019

Here's the link :
https://github.com/TahaAnwar/opensource
It is the file "myhanddetector2.svm"

@takuya-takeuchi
Copy link
Owner

simple_object_detector is object_detector<scan_fhog_pyramid<pyramid_down<6>>>.
You can refere examples\FHogObjectDetector\Program.cs.

// Then you can recall it using the deserialize() function.
using (var tmp = new ScanFHogPyramid<PyramidDown, DefaultFHogFeatureExtractor>(6))
using (var detector2 = new ObjectDetector<ScanFHogPyramid<PyramidDown, DefaultFHogFeatureExtractor>>(tmp))
    detector2.Deserialize("face_detector.svm");

@omdxp
Copy link
Author

omdxp commented May 28, 2019

Okay thanks, I'll try it. I really appreciate your help

@omdxp
Copy link
Author

omdxp commented May 28, 2019

Here's what 's happening, when I used Deserialize method, the Operator method gives me this compile error:

The type arguments for method 'ObjectDetector<ScanFHogPyramid<PyramidDown, DefaultFHogFeatureExtractor>>.Operator<U>(Matrix<U>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

What should the type argument be?

@takuya-takeuchi
Copy link
Owner

takuya-takeuchi commented May 28, 2019

ObjectDetector<ScanFHogPyramid<PyramidDown, DefaultFHogFeatureExtractor>>.Operator(Matrix matrix) accept Matrix.
U should be struct. eg; byte, int , RgbPixel.

detector2.Operator(new Matrix<byte>());

You can pass image data.

@omdxp
Copy link
Author

omdxp commented May 28, 2019

It's done. I don't know if this is the perfect code for this but can you take look?

capture = new VideoCapture(0);
using (var win = new ImageWindow())
                {
                    using (var tmp = new ScanFHogPyramid<PyramidDown, DefaultFHogFeatureExtractor>(6))
                    using (var detector = new ObjectDetector<ScanFHogPyramid<PyramidDown, DefaultFHogFeatureExtractor>>(tmp))
                    {
                        detector.Deserialize("hand.svm");
                        while (!win.IsClosed())
                        {
                            var temp = new Mat();
                            capture.Read(temp);

                            var array = new byte[temp.Width * temp.Height * temp.ElementSize];
                            Marshal.Copy(temp.DataPointer, array, 0, array.Length);

                            using (var cimg = Dlib.LoadImageData<RgbPixel>(array, (uint)temp.Height, (uint)temp.Width, (uint)(temp.Width * temp.ElementSize)))
                            {
                                // Detect hands
                                var dets = detector.Operator(new DlibDotNet.Matrix<RgbPixel>(cimg));
                                
                                // Display it all on the screen
                                win.ClearOverlay();
                                win.SetImage(cimg);
                                win.AddOverlay(dets, new RgbPixel { Red = 255 });
                            }

                        }
                    }
                }

@omdxp
Copy link
Author

omdxp commented May 28, 2019

But I noticed something, it is very slow comparing to my python program. Why is that?

@takuya-takeuchi
Copy link
Owner

var dets = detector.Operator(new DlibDotNet.Matrix<RgbPixel>(cimg));

you should use using statement for Matrix.

@takuya-takeuchi
Copy link
Owner

You did not use GPU?
DlibDotNet.Native does not use Intel MKL. Python dlib could use it.
So if use on cpu, DlibDotNet works on low performance.
Please refer #35.

You can build DlibDotNet.Native by using Intel MKL.

@omdxp
Copy link
Author

omdxp commented May 28, 2019

Yes, I've used it on CPU, Thanks for your help.

@omdxp omdxp closed this as completed May 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants