Closed omdxp closed 5 years ago
It is similar with #87?
@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.
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
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);
}
byte[] data = (byte[])temp.Data;
Is it correct? It must be compile error.
No it execute normally
Wait. What is Mat? I think Mat does not have ElementSize.
I forgot to tell you that I'm using EmguCV wrapper not OpenCVSharp
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);
Thank you, I'll try it and tell you the results
I tried the first method temp.DataPointer and it works fine
Could you add an example of hand detection using DlibDotNet the way as I did it in Python?
Both methods works fine
I may be able to write sample code to detect hand. But
Where did you get hand.svm file from? If license of model file is unknown, I can not accept your request?
Here's the link : https://github.com/TahaAnwar/opensource It is the file "myhanddetector2.svm"
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");
Okay thanks, I'll try it. I really appreciate your help
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?
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.
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 });
}
}
}
}
But I noticed something, it is very slow comparing to my python program. Why is that?
var dets = detector.Operator(new DlibDotNet.Matrix<RgbPixel>(cimg));
you should use using statement for Matrix.
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 https://github.com/takuya-takeuchi/DlibDotNet/issues/35.
You can build DlibDotNet.Native by using Intel MKL.
Yes, I've used it on CPU, Thanks for your help.
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