目录

Normalize

ExtractMat

GCHandleType


Normalize

static float[] mean = { 0.485f, 0.456f, 0.406f };
 static float[] std = { 0.229f, 0.224f, 0.225f };
  
 public static void Normalize(Mat src)
 {
     src.ConvertTo(src, MatType.CV_32FC3,  1.0 / 255 );
  
     Mat[] bgr = src.Split();
     for (int i = 0; i < bgr.Length; ++i)
     {
         bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1 / std[i], (0.0 - mean[i]) / std[i]);
     }
  
     Cv2.Merge(bgr, src);
  
     foreach (Mat channel in bgr)
     {
         channel.Dispose();
     }
 }

ExtractMat

public static float[] ExtractMat(Mat src)
 {
     OpenCvSharp.Size size = src.Size();
     int channels = src.Channels();
     float[] result = new float[size.Width * size.Height * channels];
     GCHandle resultHandle = default;
     try
     {
         resultHandle = GCHandle.Alloc(result, GCHandleType.Pinned);
         IntPtr resultPtr = resultHandle.AddrOfPinnedObject();
         for (int i = 0; i < channels; ++i)
         {
              Mat cmat =  new Mat(
                 src.Height, src.Width,
                 MatType.CV_32FC1,
                 resultPtr + i * size.Width * size.Height * sizeof(float));
  
             Cv2.ExtractChannel(src, cmat, i);
             cmat.Dispose();
         }
     }
     finally
     {
         resultHandle.Free();
     }
  
     return result;
 }
static float[] mean = { 0.485f, 0.456f, 0.406f };
static float[] std = { 0.229f, 0.224f, 0.225f };
 
public static void Normalize(Mat src)
{
    src.ConvertTo(src, MatType.CV_32FC3,  1.0 / 255 );
 
    Mat[] bgr = src.Split();
    for (int i = 0; i < bgr.Length; ++i)
    {
        bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1 / std[i], (0.0 - mean[i]) / std[i]);
    }
 
    Cv2.Merge(bgr, src);
 
    foreach (Mat channel in bgr)
    {
        channel.Dispose();
    }
}
 
public static float[] ExtractMat(Mat src)
{
    OpenCvSharp.Size size = src.Size();
    int channels = src.Channels();
    float[] result = new float[size.Width * size.Height * channels];
    GCHandle resultHandle = default;
    try
    {
        resultHandle = GCHandle.Alloc(result, GCHandleType.Pinned);
        IntPtr resultPtr = resultHandle.AddrOfPinnedObject();
        for (int i = 0; i < channels; ++i)
        {
             Mat cmat =  new Mat(
                src.Height, src.Width,
                MatType.CV_32FC1,
                resultPtr + i * size.Width * size.Height * sizeof(float));
 
            Cv2.ExtractChannel(src, cmat, i);
            cmat.Dispose();
        }
    }
    finally
    {
        resultHandle.Free();
    }
 
    return result;
}

GCHandleType

Normal:对象被标记为完全不被GC管理的状态,但会被GC移动内存位置,需要我们手动调用Free来释放对应的GC对象

Pinned:对象被标记为完全不被GC管理的状态,不被GC回收也不被GC移动内存地址,需要我们手动调用Free来释放对应的GC对象

Weak:如果对象被标记为“不可达”(没有被任何对象使用,需要清除的状态)时(但是其对象的内存还未真的被回收),Weak所指向的对象就会标记为null;不需要我们手动调用Free来释放对应的GC对象

WeakTrackResurrection:如果对象在最終處理期間重新恢復狀態控制代碼不歸零;也就是说只有GC对象最终被回收,在此之前,我们都能够通过Handle获取到实际对象,不需要我们手动调用Free来释放对应的GC对象