【1】 背景和思路
(1)目的:用OpenCV库完成图像处理算法的开发,并将其封装成dll库,然后c#项目调用封装好的dll库。
(2) 思路:
注意: 一定要将c++和c#中的解决方案配置设置为一样
c++
c# c#更改项目属性中的平台目标为x64
1 c++环境下创建空项目/动态链接库
(注创建空项目则需要将配置类型由.exe转换为.dll,动态链接库则不需要)。
【项目属性】→ 【配置属性】→【常规】→【目标文件扩展名】,将.exe,改为.dll
2 完成.h和.cpp文件中算法的设计 。
3 编写模板定义文件。
4 生成dll文件。
5 将c++中的dll文件复制到c#项目文件中的bin目录下的release文件目录下。
6 编写c#文件。
【2】实现步骤及代码
环境配置:vs2017 opencv4.3.0(本文默认OpenCV环境已经配置完成)
【2.1】建立c++空项目
【2.2】编写c++算法
.h文件代码
#pragma once
extern "C" __declspec(dllexport) void AutoFocusA();
extern "C" __declspec(dllexport) void ThresholdImage();
.cpp文件代码
#include"CplusImagepro.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include "opencv2/core/core.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/highgui/highgui.hpp"
#include<opencv.hpp>
using namespace std;
using namespace cv;
void AutoFocusA()
{
string pattern = "C:/Users/Administrator/Pictures/opencvpicture/*.jpg";
vector<Mat> images;
vector<String> pic; // 必须cv的String
glob(pattern, pic, false);
size_t count = pic.size();
cout << count << endl; //显示一共有多少张图片
for (int i = 0; i < count; i++)
{
images.push_back(imread(pic[i]));
Mat imageSource = images[i];
Mat imageGrey;
cvtColor(imageSource, imageGrey, COLOR_RGB2GRAY);
Mat imageSobel;
Laplacian(imageGrey, imageSobel, CV_16U); //Laplacian梯度法,数值越大表示图像越清晰
double meanValue = 0.0;
meanValue = mean(imageSobel)[0]; //图片清晰度
//double to string
stringstream meanValueStream;
string meanValueString; //字符串
meanValueStream << meanValue;
meanValueStream >> meanValueString;
meanValueString = "Articulation(Laplacian Method): " + meanValueString;
putText(imageSource, meanValueString, Point(20, 20), FONT_HERSHEY_COMPLEX, 0.7, Scalar(255, 0, 0), 2);
imshow("Articulation", imageSource);
waitKey(1000);
cout << meanValue << endl; //显示图片的清晰度
//将清晰度数据存为xml文件
FileStorage mul_wr("D:\\pikaqiu.xml", FileStorage::APPEND);
mul_wr << "meanValue" << meanValue;
mul_wr.release();
}
}
void ThresholdImage()
{
string pattern = "C:/Users/Administrator/Pictures/opencvpicture/beads.jpg";
Mat image = imread(pattern);
Mat grayImage,thresholdImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
threshold(grayImage, thresholdImage,100,150,1);
imshow("testimage", thresholdImage);
waitKey(1000);
}
.def文件代码(模板定义文件)
LIBRARY demo
EXPORTS AutoFocusA
EXPORTS ThresholdImage
【2.3】生成dll库
【2.4】 dll库的复制
【2.5】 c#文件创建
【2.6】C#程序编写
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace Test1
{
class Program
{
[DllImport("CplusImagepro.dll")] //新增
private extern static void AutoFocusA(); //新增
[DllImport("CplusImagepro.dll")] //新增
private extern static void ThresholdImage();
static void Main(string[] args)
{
Console.WriteLine("C#调用dll");
//AutoFocusA();
ThresholdImage();
Console.Read();
}
}
}
【2.7】 c#环境配置
【2.8】结果展示
3 结果分析
(1)注意c++编程环境下的解决方案配置和c#环境的解决方案配置。一定要保持一样,要不会报错。
(2)模板定义文件:模块定义 (.def) 文件为链接器提供有关被链接程序的导出、属性及其他方面的信息。
(3)此处采用的是非托管形式,所以代码加载了两次dll文件,如果是托管形式的,则只需要加载一次就好。