ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-10-20 10:02:56  阅读:304  来源: 互联网

标签:src OpenCvSharp Width C# Height Channels int Opencv4 Mat


**

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);//释放内存
        }
    }
}

标签:src,OpenCvSharp,Width,C#,Height,Channels,int,Opencv4,Mat
来源: https://blog.csdn.net/liushuiyouyi1991/article/details/120859460

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有