C# OpenCvSharp与Opencv4.x(DLL)混合开发

2021/10/20 11:10:25

本文主要是介绍C# OpenCvSharp与Opencv4.x(DLL)混合开发,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

**

C# OpenCvSharp与Opencv4.x(DLL)混合开发

**
**
这里只能解决宽度为4的倍数图片,不是4的倍数会出现图片扭曲,网上找了很多都不能解决,一般工业相机都是4的倍数,不是也可以自定义调节

第一部分:开发环境

**
1.Win10 X64
2.vs2019
3.Opencv4.5.2
4.OpenCvSharp4.0
**

第二部分:c++ Opencv4.5.2 动态库

**

#include<opencv2/opencv.hpp>
using namespace cv;
extern "C" _declspec(dllexport) uchar * ReadImage(char*, int&, int&, int&);
extern "C" _declspec(dllexport) uchar * ShowImage(uchar*, int&, int&, int&);
extern "C" _declspec(dllexport) void ReleaseUChar(uchar*);
uchar* ReadImage(char* ImagePath, int& Width, int& Height, int& Channels)
{
	Mat src = imread(ImagePath);
	if (src.empty()) return NULL;
	Width = src.size().width;
	Height = src.size().height;
	Channels = src.channels();
	size_t memsize = (long long)Width * (long long)Height * (long long)Channels;
	
	//不能直接返回src.data
	//重新申请内存,然后将src.data拷贝到申请的内存空间再返回
	//由于不能在这里释放内存,所以加一个释放内存函数ReleaseUChar,C#使用完再调用释放函数
	
	uchar* data = new uchar[memsize];//ReleaseUChar释放内存
	memcpy(data, src.data, memsize);//拷贝
	return data;
}
uchar* ShowImage(uchar* ImageData, int& Width, int& Height, int& Channels)
{
	Mat src;
	switch (Channels)
	{
	case 1:
		src = Mat(Height, Width, CV_8UC1, ImageData);
		break;
	case 3:
		src = Mat(Height, Width, CV_8UC3, ImageData);
		break;
	default:
		return NULL;
	}
	
	Mat dst;
	cvtColor(src, dst, COLOR_BGR2GRAY);
	if (dst.empty()) return NULL;
	Width = dst.size().width;
	Height = dst.size().height;
	Channels = dst.channels();
	size_t memsize = (long long)Width * (long long)Height * (long long)Channels;
	uchar* data = new uchar[memsize];//ReleaseUChar释放内存
	memcpy(data, src.data, memsize);//拷贝
	return data;
}
void ReleaseUChar(uchar* p)
{
	delete[] p;//释放
}

**

第二部分:c# OpenCvSharp4.0 开发

**

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.Extensions;

[DllImport("xxx.dll")]
private extern static IntPtr ReadImage(string ImagePath, ref int Width, ref int Height, ref int Channels);

[DllImport("xxx.dll")]
private extern static IntPtr ShowImage(byte[] ImgData, ref int Width, ref int Height, ref int Channels);

//ReadImage ShowImage函数的返回都要使用ReleaseUChar释放
[DllImport("xxx.dll")]
private extern static void ReleaseUChar(IntPtr p);

//加载图片 C++ Mat数据传递给C#
void FunctionReadImage()
{
	IntPtr ImgData = IntPtr.Zero;
	int Width = 0, Height = 0, Channels = 0;
	ImgData = ReadImage("宽度为4的倍数.jpg", ref Width, ref Height, ref Channels);
	if (ImgData == IntPtr.Zero) return;
	//Channels表示通道数 如果为1 MatType.CV_8UC1
    using (Mat src = new Mat(Height, Width, MatType.CV_8UC3, ImgData))
    {
        pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
        pictureBox1.Image = null;
        pictureBox1.Image = BitmapConverter.ToBitmap(src);
    }
	ReleaseUChar(ImgData);//释放内存
}

//将图片转灰度图 主要体现C++ Mat与c# Mat互调
void FunctionShowImage()
{
    using (Mat img = new Mat("宽度为4的倍数.jpg"))
    {
        using (Bitmap bmp = BitmapConverter.ToBitmap(img))
        {
            int Width = bmp.Width, Height = bmp.Height;
            BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, Width, Height), 	ImageLockMode.ReadWrite, bmp.PixelFormat);
            IntPtr ptr = bmpdata.Scan0;
            int Channels = bmpdata.Stride / Width;
            int bytes = Width * Height * Channels;
            byte[] rgbvalues = new byte[bytes];
            Marshal.Copy(ptr, rgbvalues, 0, bytes);
            IntPtr ImgData = IntPtr.Zero;
            ImgData = ShowImage(rgbvalues, ref Width, ref Height, ref Channels);
            if (ImgData == IntPtr.Zero) return;
            //Channels表示通道数 如果为1 MatType.CV_8UC1
            using (Mat src = new Mat(Height, Width, MatType.CV_8UC1, ImgData))
            {
                pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
                pictureBox1.Image = null;
                pictureBox1.Image = BitmapConverter.ToBitmap(src);
            }
            ReleaseUChar(ImgData);//释放内存
        }
    }
}


这篇关于C# OpenCvSharp与Opencv4.x(DLL)混合开发的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程