c#与opencv Mat交互总结

6 篇文章 0 订阅
3 篇文章 0 订阅

这里有两种方案,第一种方案是采用OpencvCSharp,最后OpencvCSharp.Mat.CvPtr即是Mat **img

接下来可以采用C#调用c++ dll的方法实现交互

第二种方案即将OpencvCSharp 的转换方法提取出来,Mat对应的C#中的就是一个Intptr;

以下是C#的核心Src:

public static Bitmap GetBitmapfromImgptr(IntPtr imgptr)
{
    int w = 0;
    int h = 0;
    int channel = 0;
    int type = 0;
    IntPtr ptr = GetDataAndInfo(imgptr,ref w,ref h,ref channel, ref type);
    int stride = channel * w;
    PixelFormat format;
    switch (type)
    {
        case 1:
            format = PixelFormat.Format8bppIndexed;
            break;
        case 3:
            format = PixelFormat.Format24bppRgb;
            break;
        default:
            return null;
    }
        
    return getBitmapByData(ptr, w, h, stride, format);
}
public static void BitmaptoImgptr(Bitmap bitmap,out IntPtr intPtr)
{
    int stride;
    byte[] source = GetBGRValues(bitmap, out stride);
    int channel = Image.GetPixelFormatSize(bitmap.PixelFormat) / 8;
    GetImg(source, bitmap.Width, bitmap.Height, channel,out intPtr);
}
[DllImport("opencvbase.dll", EntryPoint = "GetImg", CharSet = CharSet.Auto)]
public static extern void GetImg(byte[] src, int w, int h, int channel, out IntPtr intPtr);
[DllImport("opencvbase.dll", EntryPoint = "GetDataAndInfo", CharSet = CharSet.Auto)]
public static extern IntPtr GetDataAndInfo(IntPtr imgptr, ref int w, ref int h, ref int channel, ref int type);
public static Bitmap getBitmapByData(IntPtr ptr, int w, int h, int stride, PixelFormat format)
{

    int rowBytes = w * Image.GetPixelFormatSize(format) / 8;
    byte[] rgbValues = new byte[stride * h];
    for (var i = 0; i < h; i++)
    {

        Marshal.Copy(ptr, rgbValues, i * stride, rowBytes);
        ptr += rowBytes; // next row
    }

    GCHandle hObject = GCHandle.Alloc(rgbValues, GCHandleType.Pinned);
    IntPtr ptrnew= hObject.AddrOfPinnedObject();

    Bitmap bitmap = new Bitmap(w, h, stride, format, ptrnew);
    if (format == PixelFormat.Format8bppIndexed)
    {
        bitmap.Palette = getGrayPalette();
    }
    hObject.Free();
    return bitmap;
}
public static byte[] GetBGRValues(Bitmap bmp, out int stride)
{
    var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    var bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
    stride = bmpData.Stride;

    var rowBytes = bmpData.Width * Image.GetPixelFormatSize(bmp.PixelFormat) / 8;
    var imgBytes = bmp.Height * rowBytes;
    byte[] rgbValues = new byte[imgBytes];
    IntPtr ptr = bmpData.Scan0;
    for (var i = 0; i < bmp.Height; i++)
    {
        Marshal.Copy(ptr, rgbValues, i * rowBytes, rowBytes);  
        ptr += bmpData.Stride; // next row
    }
    bmp.UnlockBits(bmpData);

    return rgbValues;
}

C++ Dll 核心Src:

extern "C" DLL_EXPORY void* GetDataAndInfo(void *imgptr,int &w,int &h,int &channel,int &imgtype)
{
	Mat *img = (Mat *)imgptr;
	w = img->cols;
	h = img->rows;
	channel = img->channels();
	switch (img->type())
	{
	case CV_8UC1:
		imgtype = 1;
		break;
	case CV_8UC3:
		imgtype = 3;
		break;
	case CV_8UC2:
		imgtype = 2;
		break;
	case CV_8UC4:
		imgtype = 4;
		break;
	}
	return img->data;
}
extern "C" DLL_EXPORY void  GetImg(unsigned char* src, int w, int h, int channel, cv::Mat **img)
{
	int format;
	switch (channel)
	{
	case 1:
		format = CV_8UC1;
		break;
	case 2:
		format = CV_8UC2;
		break;
	case 3:
		format = CV_8UC3;
		break;
	default:
		format = CV_8UC4;
		break;
	}
	if (*img !=nullptr)
	{
		delete *img;
	}
	*img= new Mat(h, w, format, src);
}

以上只实现的常用CV_8U系的图片转换,对于其他类型,可以查看OpencvCSharp.extensions.BitmapConverter

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陶醉鱼

感觉写的不错就给个打赏哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值