前言
公司组建机器视觉开发小组,使用国产相机和标准工控机为硬件,采用开源的OpenCV算法库,后来又采购了Halcon的开发授权,做了几个视觉防错和机器视觉定位、引导的项目,效果还不错。只是开发的程序都是基于windows平台的,想实现跨平台不太容易,就考虑使用服务器Api的形式,实现现有算法的跨平台使用,而且,小组也采购了几台视觉服务器,通过服务器Api实现机器视觉的私有云计算,开发服务器Api的潜在的应用价值还真不小。开展这个项目的收益细数如下:
- 实现基于windows的应用跨平台
- 私有云计算,算力可扩充
- Halcon授权的充分利用,halcon是一机一授权,采用服务器运算的话,可以只对服务器购买授权而无须对每个终端授权。
一、框架
整个过程有很多细节,这里只是简述技术方案的主要构成部分:
- 由于自主开发的视觉程序是用VC++写的,各模块都比较熟练,视觉处理部分沿用VC++来写,生成标准C的DLL程序给服务器调用。
- 服务器后台采用Django,同时利用python的标准库ctypes实现对C函数的调用。
- 前台面对的客户端是浏览器和使用delphi或者微软的xamarin开发的安卓、iOS的app,就做了html测试网页和http提交的Api接口。
- 基本的流程是客户端(网页或者app)通过http上传照片,提交视觉程序处理的请求,Django接到请求,能过ctypes库调用VC++开发的视觉程序,然后将处理结果应答给客户端。
二、搭建过程
2.1. Django服务器搭建
2.1.1. 在服务器上开一台虚拟机,这里是windows server2008,启用IIS,安装python和django,IIS部署Django网上有相关的教程,这里就不搬运了。
2.1.2. 创建Django工程
D:\py\Djg>
django-admin startproject mysite .
python manage.py migrate
2.1.3. 运行测试
python manage.py runserver
2.1.4. 创建程序
python manage.py startapp filesaver
2.1.5. 告诉Django应用刚才创建的app
mysite/settings.py > INSTALLED_APPS : ‘filesaver’,
2.1.6. 创建url,在mysite/urls.py > urlpatterns = []增加:
“url(r’^filesaver/’, filesaver),”
2.1.7 Django静态文件处理也有相关的教程(互联网是技术搬运工)。
2.1.8. 修改文件夹filesaver里面的views.py文件
代码如下:
# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
import os
import time
from ctypes import *
from django.shortcuts import HttpResponse
@csrf_exempt
def uploadfile(request):
if request.method == "POST":
try:
file = request.FILES.get("myfile", None) # 接收上传的文件
imgPath = os.path.join(os.getcwd(), 'media\\ImgRcv')
imgPath = os.path.join(imgPath, file.name)
destination = open(imgPath, 'wb')
for chunk in file.chunks():
destination.write(chunk)
destination.close()
dllPath=os.path.join(os.getcwd(),"filesaver\\Dll2.dll")
pResult=0
pDll=windll.LoadLibrary(dllPath)
# 传入文件名字符串
str4cIn=file.name
pstr4cIn = c_wchar_p(str4cIn)
strOut = "----------------------------------------"
pstr4cOut = c_wchar_p(strOut)
pstr4cOutLen =c_wchar_p("45")
pResult=pDll.add2(pstr4cIn,len(str4cIn),pstr4cOut,len(strOut))
data=pstr4cOut.value[0:17]
return render(request,'filesaver/success.html',{'data': data, 'image':file.name})
except Exception as e:
return HttpResponse(e)
return HttpResponse("NOT_POST_REQUEST")
2.1.9 这里有几个坑,ctype传入传出参数需要通过指针来完成,pstr4c = c_wchar_p(str4c)便是将python的指针转换成C的指针,这样,在c和python中都可以操作这个变量了。此例子中的pstr4cIn、pstr4cOut分别是传入c函数和从c函数传出的字符串指针,对就c函数(见2.2)中pyStr和pyStr2指针。
2.2 VC++开发用于ctypes调用的函数库
代码如下(示例):
#pragma once
#include <HalconCpp.h>
using namespace HalconCpp;
extern "C"
{
__declspec(dllexport) int __stdcall add2(char* pyStr, int pyStrLen, char* pyStr2, int pyStrLen2);
}
int __stdcall add2(char *pyStr, int pyStrLen, char* pyStr2, int pyStrLen2)
{
int nRet = 0;
// python string 转 string
char* cStr = new char[pyStrLen];
for (size_t i = 0; i < pyStrLen; i++)
cStr[i] = pyStr[i * 2];//下标乘2跳过'\0'
std::string rst = "dddddddddddddddd";
char* rslt = (char*)rst.data();
for (size_t i = 0; i < strlen(rslt); i++)
pyStr2[i * 2] = rslt[i];
// Local iconic variables
HObject ho_Letters;
HObject ho_rect1, ho_ImageReduced;
ReadImage(&ho_Letters, "a.jpg");
GenRectangle2(&ho_rect1, 100, 100, 0, 1500, 350);
ReduceDomain(ho_Letters, ho_rect1, &ho_ImageReduced);
return 1;
}
该函数与python中的函数的对照一目了然了。
三、基本的html请求测试
3.1 基本的html前端代码
移动app的测试代码这里不提供了,Django下的index.html页测试代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>file saver</title>
</head>
<body>
<hr/>
<h3 align="left">照片上传API_1测试</h3>
<form name="api1form" enctype="multipart/form-data" action="/uploadfile/" method="post">
<p><input type="file" name="myfile" /></p>
<p><input type="submit" value=" 测 试 " /></p>
</form>
<hr/>
</body>
</html>
3.2 验证效果截图
总结
本文介绍的基于Django Api服务器搭建过程和python对于标准c函数库的调用方法ctypes,可用于机器视觉开发中跨平台应用问题解决及其它类似的使用场景。