写这篇博客是因为最近要完成一些小任务,想把自己做的记录下来,希望能不断进步吧。如果有不对的地方,希望大家指正。
在这里我用的是VS2017 + Unity2018.2 + OpenCV3.4.0,其他的过程应该也会相同吧,大家自己琢磨琢磨好了。
一,下载OpenCV的并配置VS2017环境
1,OpenCV中的下载和配置可以参考这一篇博客,写的很详细也很有用。
https://blog.csdn.net/nicewe/article/details/79173346
值得注意的是,在这里面运行时要选择的x64编辑器,所以之后再写DLL动态库的时候我们也要采用x64的编辑器,不能使用的x86编译器了。具体分析可以参考这篇博客,写的很详细。
https://blog.csdn.net/Nicholas_Liu2017/article/details/78790650
简单来说就是86编译器编译出来的是32位,64位编译出来的是64位.x86编译器不能加载64位的DLL文件,而64可以加载64位的或者32位的DLL文件。
二,使用VS2017创建DLL文件
这个项目我同样想要调用一篇博客,人家写的很详细了,感谢大牛们为我这样的小白做出的贡献。
https://blog.csdn.net/cynophile/article/details/79749524
里面写的很详细了,按照步骤来不会有问题的。当然,具体情况具体分析,有一个地方需要更正。在最后生成解决方案那里,博客里面写的是在调试文件夹下,但实际上在我们这里最后生成的DLL文件在\ DLL1 \ 64 \调试文件夹里面,结果如下图。
这是因为在这里面我们也需要用x64编译器进行编译,不然就用不了opencv库。顺便说一下,如果我们按照第一点说的做了,在这里是不需要再去配置opencv环境的,直接使用的x64编译器就好了,如下图。这里的三个文件都是需要自己创建的。
OK,到这里,我们应该已经成功生成了一个DLL动态库了,但是,这不是我们想要的DLL动态库,大家可以安装那篇博客里面写的去测试是否可以成功调用之前生成的源DLL1动态库,如果你不打算这么做的话,其实也没啥问题。
三,编写DLL动态库文件
在这里,我将会带大家实现高斯模糊这一简单功能。其实只需要修改我们之前在生成的dll动态库中所编写的程序。
1,首先是export.h文件,大家照着把代码敲进去吧,这里我为大家找了一篇博客来解释下面代码的意思。
https://blog.csdn.net/liitdar/article/details/80055236
2,然后是dll1.h文件,这边有一个很重要的地方,就是
extern "C" EXPORT_API void Gauss();
这个地方要注意前面的extern“c”,如果按照第二点里面讲的去做,那个是没有这个extern“c”的,那么就会导致后面在unity调用dll动态库的时候找不到文件入口,这是因为C ++源代码中的函数在编译成DLL后,函数的名称就发生了改变。会在函数的前后产生一些字符,所以找不到方法的入口点这时候我们去网上搜就会发现很多人使用一个叫EXESCOPE的反编译软件来查看C ++编译后的函数名称是什么。但是这个软件英文版的在网上不太好找,中文版的还不行,乱下还容易出一堆垃圾捆绑软件。所以我找了另一种简单便捷的方法就是上面的。
3,最后是dll1.cpp文件,这里就是简单的实现高斯函数。
为了方便大家,我这里贴上代码。
// Dll1.cpp : 定义 DLL 应用程序的导出函数。
#include "stdafx.h"
#include "dll1.h"
#include
#include
#include"opencv2/imgproc/imgproc.hpp"
#include
using namespace cv;
/*
高斯模糊:void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT)
src – 输入图片,可以使是任意通道数,该函数对通道是独立处理的,但是深度只能是CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
dst – 输出图片,和输入图片相同大小和深度。
ksize – 高斯内核大小。ksize.width和ksize.height允许不相同但他们必须是正奇数。或者等于0,由参数sigma的乘机决定。
sigmaX – 高斯内核在X方向的标准偏差。
sigmaY – 高斯内核在Y方向的标准偏差。如果sigmaY为0,他将和sigmaX的值相同,如果他们都为0,那么他们由ksize.width和ksize.height计算得出。
borderType – 用于判断图像边界的模式。
*为了结果的正确性着想,最好是把第三个参数Size,第四个参数sigmaX和第五个参数sigmaY全部指定到。
**/
void Gauss() {
cvNamedWindow("高斯模糊原图", 0);
cvNamedWindow("高斯模糊效果图", 0);
Mat imageSrc = imread("D:\\C++demo\\lena.jpg");
imshow("高斯模糊原图", imageSrc);
Mat imageChange;
//高斯模糊处理
GaussianBlur(imageSrc, imageChange, Size(7, 7), 0, 0);
//显示效果图
imshow("高斯模糊效果图", imageChange);
waitKey(6000 * 100);
}
四,统一调用的DLL动态库文件
很正常的,我们新建一个统一项目,随便你取什么名字。
接着我们在资产文件夹下新建一个插件文件夹,将我们之前生成的DLL动态库文件拷贝到插件文件夹下,如上图。
然后我们在Assets文件夹下新建一个C#脚本。
我们对脚本文件进行编写,注意类类名和文件名要相同。
unity中的脚本文件必须要将脚本附着在某个物体上才能执行。点击脚本拖到Main Camera的Inspector下。
这里我注明下,调用c ++ / c编写的dll文件要使用[DllImport(“
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class testdll : MonoBehaviour
{
[DllImport("Dll1")]
private static extern void Gauss();
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void OnGUI()
{
if (GUILayout.Button("test c++ dll"))
{
Gauss();
Debug.Log("dll");
}
}
}
当你完成上面的步骤的话,你就可以实现最后的效果啦。