功能要求非常简单,连接扫描仪,调用扫描仪扫描常见规格的试管盒。识别每个试管底部/顶部的Data Matrix。

技术选择

目标平台是Windows,理论上C#之类是最合适的,然而基于熟练度,只能Java/Go二选一,最终选择了Go。

连接/调用扫描仪

支持twain协议即可,选择twain

Data Matrix 识别

简单分割图片成M x N个小图片,依次进行识别,选择了dmtx

图像处理

为了提高dmtx的识别能力,需要对扫描的图片做一定的处理(反色,锐化,对比度,亮度调整……),用哪个library都一样。

GUI框架

因为组件原因选择了fyne

一些复杂的地方

windows下通过cgo调用libdmtx

通过DLL调用dtwain

大致就是这个套路

dTwain, e := syscall.LoadLibrary("dtwain64u.dll") //载入dll
selectSourcePtr, e = syscall.GetProcAddress(dTwain, "DTWAIN_SelectSource") //获取函数地址
acquireR1, acquireR2, callErr := syscall.SyscallN(
		acquirePtr,                          //method
		source,                              //Source
		ptr(name),                           //FileNames
		uintptr(imageType),                  //FileType ,100 for BMP ,1000 for PNG <http://www.dynarithmic.com/onlinehelp5/dtwain/dtwain_file_transfer_constants.htm>
		66,                                  //FileControlFlag
		1000,                                //PixelType <http://www.dynarithmic.com/onlinehelp5/dtwain/index.html?dtwain_pixel_type_constants.htm>
		1,                                   //NumPages
		0,                                   //bShowUI
		0,                                   //bCloseSource
		uintptr(unsafe.Pointer(&errorCode)), //pStatus
	) //调用函数

遇到的一些问题

  1. dtwain和网上很容易找到的virtual scanner不兼容,无法正确获取扫描图片(比如 这个)但是真机并无问题。
  2. 集成了dtwain之后,如果使用goroutine去调用,会无响应。不会弹出dtwain的UI去做扫描,最终是把扫描的代码单独打包成一个可执行文件,然后通过外部调用的方法来绕过这一问题。
  3. 调用外部可执行文件,可能会弹出一个黑色的console窗口。(这点在本机无法复现

最终成品如下

dms

实现的功能有:

  1. 自定义模板(包括图像处理和尺寸处理)
  2. 自动/手动多次扫描提高识别率
  3. 对单个识别失败的code手动图像调整
  4. 结果导出