SciSharp / NumSharp

High Performance Computation for N-D Tensors in .NET, similar API to NumPy.
https://github.com/SciSharp
Apache License 2.0
1.36k stars 189 forks source link

Converting Mat to NDArray in OpenCvSharp #371

Closed masoudnick closed 4 years ago

masoudnick commented 4 years ago

Hi all, how can i convert OpenCvSharp.Mat to NumSharp.NDArray?

Oceania2018 commented 4 years ago

@masoudnick There is an example for MatToNdarray.

masoudnick commented 4 years ago

@Oceania2018 ok, thanks a lot. But I've faced to another problem, I'm working on Object Detection using a custom model that already trained.The model run on frames of a video. In python my application works very good and fast. in C# (TensorFlow.NET),as you said, I'm using MatToNdarray and convert frames to NDarray but i don't khnow why my application is very slow. What should I do?

Nucs commented 4 years ago

@masoudnick, I'll take I look into how OpenCvSharp.Mat works and will post here an optimized version.

Nucs commented 4 years ago
static unsafe void Main(string[] args)
{
    Mat src = new Mat("olga.jpg", ImreadModes.AnyColor);
    NDArray nd = WrapWithNDArray(src); //shaped (1, src.Height, src.Width, Channels)
    Bitmap bmp = nd.ToBitmap(); //using NumSharp.Bitmap
    bmp.Save("./olga-reconstructed.jpg");
}

//this method copies Mat to a new NDArray
public static unsafe NDArray ToNDArray(Mat src)
{
    var nd = new NDArray(NPTypeCode.Byte, (1, src.Height, src.Width, src.Type().Channels), fillZeros: false);
    new UnmanagedMemoryBlock<byte>(src.DataPointer, nd.size)
        .CopyTo(nd.Unsafe.Address);

    return nd;
}

//this method wraps without copying Mat.
public static unsafe NDArray WrapWithNDArray(Mat src)
{
    Shape shape = (1, src.Height, src.Width, src.Type().Channels);
    var storage = new UnmanagedStorage(new ArraySlice<byte>(new UnmanagedMemoryBlock<byte>(src.DataPointer, shape.Size, () => Donothing(src))), shape); //we pass donothing as it keeps reference to src preventing its disposal by GC
    return new NDArray(storage);
}

[MethodImpl(MethodImplOptions.NoOptimization)]
private static void Donothing(Mat m)
{
    var a = m;
}
masoudnick commented 4 years ago

@Nucs Thanks for your response. I used your suggested code.But my problem is still not solved and program implementation process is very slow.

Nucs commented 4 years ago

WrapWithNDArray is very fast, it is likely not to be the problem. You'll have to find where the bottleneck is in your code and let us know in a new issue. Finding bottlenecks is not easy, I personally use dotTrace for the task. I suggest you to search for tutorials on how to analyze code bottlenecks with it.