文章目录

  • 前言
  • 演示视频
  • 一、项目文件目录讲解
  • 二、Qt Designer设置ui界面
    • 0.qrc资源文件的设置
    • 1.CtuImageMatching.ui的设置
    • 2.CameraSetting.ui的设置
    • 3.Calibration.ui的设置
    • 4.Helper.ui的设置
  • 三、使用命令把qt文件转成py文件
  • 四、py文件解析
    • 1.CtuImageMatching.py重要函数解析
    • 2.CameraSetting.py重要函数解析
    • 3.Calibration.py重要函数解析
    • 4.Helper.py重要函数解析
    • 5.RobotVision.py主界面重要函数
      • 1.初始化函数
      • 2.halcon窗体初始化
      • 3.绘制ROI区域,例子分为绘制矩形
      • 4.ROI运算逻辑
      • 5.创建模板
      • 6.查找模板,实现模板匹配
      • 7.读取条形码
      • 8.读取二维码
      • 9.读取OCR
      • 10.基于python+pyqt的通信:Tcp的服务器及客户端
  • 总结

前言

本文主要实现基于python做一个视觉定位识别的功能,halcon版本使用的是halcon12.0,调用halcon的dll来实现二次开发,下边从头开始设置。
编程环境:python3.8
pyqt5.15
halcon12.0
IDE: VisualStudio Code


演示视频

本次项目的效果视频:

基于python+pyqt+halcon实现多算法的模板匹配


一、项目文件目录讲解


1、Resources:文件夹存放的是图片路径,一些资源文件都放在这里
2、Calibration.py、Calibration.ui:这里是视觉功能里边的qt标定界面的ui文件以及转换为py的文件。
3、CameraSetting.py、CameraSetting.ui:这里是视觉功能里边的qt相机设置界面的ui文件以及转换为py的文件。
4、CtuImageMatching.py、CtuImageMatching.ui:这里是视觉功能里边的qt视觉软件的界面的ui文件以及转换为py的文件。
5、CtuImageMatching.qrc:Qt设计的资源文件
6、CtuImageMatchingqrc.py:Qt资源文件的转化为的py文件
7、Helper.py、Helper.ui:这里是视觉功能里边的qt帮助界面的ui文件以及转换为py的文件。
8、RobotVision.py:软件主事件功能,main函数的入口位置,整个视觉软件入口位置


备注:鉴于程序写的比较仓促,因此窗体事件与窗体写在一个文件里边,与窗体事件无关的写在了RobotVision.py中,这种思路不可取,因此如果要重新设计这个目录的时候,都需要用写事件的类继承窗体类,这样改窗体就不用和修改那么多。


二、Qt Designer设置ui界面

一下界面只需要用Qt Designer进行编辑即可,基本上不需要代码部分

0.qrc资源文件的设置


这里需要把Resources文件夹里边的资源文件添加进来。

1.CtuImageMatching.ui的设置

先上图,只需要按照这个来设置即可:







从主界面上可以看出,本视觉软件所具有的功能。

2.CameraSetting.ui的设置

先上图,只需要按照这个来设置即可:

从界面上可以看出,本相机设置具有的功能。

3.Calibration.ui的设置

先上图,只需要按照这个来设置即可:

从界面上可以看出,本标定设置具有的功能。

4.Helper.ui的设置

先上图,只需要按照这个来设置即可:

从界面上可以看出,本帮助界面具有的功能,这里暂时就一个QLabel用来放了个二维码。

三、使用命令把qt文件转成py文件

在CMD命令行中输入一下命令,这里直接上命令代码:

pyrcc5 -o CtuImageMatchingqrc.py CtuImageMatching.qrc
pyuic5 -o CtuImageMatching.py CtuImageMatching.ui
pyuic5 -o CameraSetting.py CameraSetting.ui
pyuic5 -o Calibration.py Calibration.ui
pyuic5 -o Helper.py Helper.ui

四、py文件解析

1.CtuImageMatching.py重要函数解析

首先在主界面,我这里先弄了一个管理整个流程的一个变量的类,变量的意义如代码块的解释

class CurrentControl:def __init__(self):self.setPartPosition = 0.0    # 图片在位置的左上角的位置,为了解决图像居中界面self.ROIRunType = 0   # 目前软件选中的ROI的计算类型:并集、交集、差集、self.ModelNum = 0    # 当前软件使用的模板号(定位的模板号)self.FindModelFun = 0    # 当前软件选择的模板的算法self.CurrentBarCodeType = 6   # 当前软件识别哪种二维码self.CurrentDataCodeType = 0  # 当前软件识别哪种一维码self.hv_WindowHandle = None   # 当前现实图片的窗体self.ho_Image = None   #当前的图像变量self.ROITemp = None    # 绘制ROI的经过运算的变量self.ho_Width = None   # 图像的宽度self.ho_Height = None   # 图像的高度

定义模板的类型,这里是以一个模板单位做一个属性变量:

class ModelCom:def __init__(self):self.EffectiveFlag = False          # 该模板是否有效self.modelNum = -1                  # 模板号self.TemplateAlgorithm = -1         # 匹配算法self.h_img = None                   # 创建模板原图self.h_roi = None                   # 创建模板ROIself.hv_ModelID = None              # 模板匹配IDself.ShapeModelRegions = None       # 模板轮廓self.hv_Orgin_Row = HTuple(-1)      # 模板锚点的行self.hv_Orgin_Column = HTuple(-1)   # 模板锚点的列self.hv_Target_Row = HTuple(-1)     # 锚点的行self.hv_Target_Column = HTuple(-1)  # 锚点的列self.TargetFlag = False             # 设置锚点的标志self.h_SearchROI = None             # 搜索区域self.SearchROIFlag = False          # 拥有搜索区域的标志self.startAngle = -90                 #模板起始角度self.endAngle = 180                   #角度范围self.Level = -1                       #对比度self.Score = 50                       #模板分数self.DeformationNum = 0               #允许变形self.MatchNum = 1                     #匹配个数self.FindModelTimeOut = 1000          #匹配超时事件

定义识别一维码、二维码、ocr的变量属性

class CodeModel:def __init__(self):self.BarCodeROI = None         # 条形码搜索区域self.BarCodeROIFlag = False    # 是否已经设置条形码搜索区域self.QRCodeROI = None          # 二维码搜索区域self.QRCodeROIFlag = False     # 是否已经设置了二维码搜索区域self.OCRCodeROI = None         # OCR的搜索区域self.OCRCodeROIFlag = False    # 是否设置了OCR搜索区域

2.CameraSetting.py重要函数解析

首先设立相机设置页的事件

def CameraInit(self):self.Btn_SertchCarmer.clicked.connect(self.on_Btn_SertchCarmer)    # 查找相机self.Btn_ConnectCarmer.clicked.connect(self.on_Btn_ConnectCarmer)  # 连接相机self.Check_AutoExporeTimeOut.clicked.connect(self.on_Check_AutoExporeTimeOut)   # 自动曝光self.Slider_ExporeTime.valueChanged.connect(self.Slider_ExporeTime_valueChange) # 曝光滑块的事件self.Slider_Gray.valueChanged.connect(self.Slider_Gray_valueChanged)   # 增益滑块事件self.Check_AutoBlanceWhite.clicked.connect(self.Check_AutoBlanceWhite_clicked)  # 是否白平衡self.Btn_ShowImage.clicked.connect(self.on_Btn_ShowImage)   # 预览相机和停止预览按钮self.Btn_GetImage.clicked.connect(self.Btn_GetImage_clicked)  # 快照按钮self.Lab_TenLine.clicked.connect(self.Lab_TenLine_clicked)   # 显示的时候是否显示十字self.Btn_SetROI.clicked.connect(self.Btn_SetROI_clicked)    # 设置ROI,这里类似放大图像self.HalconCameraInitTimer = QTimer(self.layoutWidget)             # 预览图像的定时器self.HalconCameraInitTimer.singleShot(100, self.InitHalconCamera)self.workerTimer1 = QTimer(self.layoutWidget)     # 十字显示的定时器self.workerTimer1.timeout.connect(self.TenLine)#线程self.workerThread = PyThread()self.workerThread.Set_ThreadSleep(0.1)     # 预览图像的线程self.workerThread.threadSignal.connect(self.GetImage)

初始化显示图像的halcon窗体

def InitHalconCamera(self):try:HOperatorSet.CloseWindow(self.hv_WindowHandle)except Exception as e:passHOperatorSet.SetWindowAttr(HTuple("background_color"), HTuple("black"))winID = self.Lab_HShowWindow.winId()self.hv_WindowHandle = HOperatorSet.OpenWindow(HTuple(0), HTuple(0), HTuple(self.Lab_HShowWindow.geometry().width()), HTuple(self.Lab_HShowWindow.geometry().height()), HTuple(winID), HTuple(""), HTuple(""), self.hv_WindowHandle)HOperatorSet.SetColor(self.hv_WindowHandle, HTuple("red"))HOperatorSet.SetDraw(self.hv_WindowHandle, HTuple("margin"))HOperatorSet.SetLineWidth(self.hv_WindowHandle, HTuple(1))

查找相机函数

def on_Btn_SertchCarmer(self):conf = configparser.ConfigParser()conf.read(self.filePath + "\\DefaultSetting.ini")cameraType = conf.get("CameraType","CameraInterface")conf.clear()deviceNames = "DirectShow"if cameraType == "0":deviceNames = "DirectShow"elif cameraType == "1":deviceNames = "GigEVision2"elif cameraType == "2":deviceNames = "GenICamTL"else:passName = Query = Information = ValueList = info_BoardsList = hv_Length = NoneHOperatorSet.InfoFramegrabber(HTuple(deviceNames),HTuple("device"),HTuple(Information),HTuple(ValueList))hv_Length = HOperatorSet.TupleLength(ValueList,HTuple(hv_Length))length1 = hv_Length[0].Iself.Com_CameraList.clear()for i in range(0,length1):strDevice = ValueList[i].Sif deviceNames != "DirectShow":strDevice = re.findall(r'device:(.*?) ',strDevice)[0]if strDevice == "":strDevice = ValueList[i].Sif strDevice == "default":breakfill_name = deviceNames.replace("\"","") + ":" + strDeviceself.Com_CameraList.addItem(fill_name)print(fill_name)

连接相机函数

def OpenCamera(self):Information = ValueList = Nonestr = self.Com_CameraList.currentText()ColorZone = ""try:Driver = str.split(":")if self.Com_ColorZone.count() <=0:if Driver[0] == "DirectShow":ColorZone = "gray"else:ColorZone = "default"else:ColorZone = self.Com_ColorZone.currentText()HOperatorSet.InfoFramegrabber(HTuple(Driver[0]), HTuple("defaults"), HTuple(Information), HTuple(ValueList))self.hv_AcqHandle = HOperatorSet.OpenFramegrabber(HTuple(Driver[0]), HTuple(ValueList[0].I), HTuple(ValueList[1].I), HTuple(ValueList[2].I), HTuple(ValueList[3].I), HTuple(ValueList[4].I), HTuple(ValueList[5].I), HTuple(ValueList[6].S), HTuple(ValueList[7].I), HTuple(ColorZone), HTuple(-1), HTuple(ValueList[10].S), HTuple(ValueList[11].S), HTuple(Driver[1]), HTuple(0), HTuple(ValueList[13].I), self.hv_AcqHandle)print(self.hv_AcqHandle)HOperatorSet.GrabImageStart(self.hv_AcqHandle, HTuple(-1))self.ho_Image = HOperatorSet.GrabImageAsync(self.ho_Image, self.hv_AcqHandle, HTuple(-1))HOperatorSet.GetImageSize(self.ho_Image, self.ho_Width, self.ho_Height)HOperatorSet.SetPart(self.hv_WindowHandle, HTuple(0), HTuple(0), HTuple(self.ho_Height[0].I - 1), HTuple(self.ho_Width[0].I - 1))self.GetCameraInfo(Driver[0])self.OpenCarmerFlag = Trueself.EnableCamera(self.OpenCarmerFlag)return Trueexcept Exception as e:self.CloseCamera()return False

获取已经连接相机的属性

def GetCameraInfo(self,driverName):# 像素格式try:hv_Value = hv_Length = Nonehv_Value = HOperatorSet.GetFramegrabberParam(self.hv_AcqHandle,HTuple("PixelFormat"),hv_Value)print(hv_Value)hv_Length = HOperatorSet.TupleLength(hv_Value, HTuple(hv_Length))length = hv_Length[0].Ifor i in range(0,length):self.Com_PixFormat.addItem(hv_Value[i].S)except Exception as e:pass#颜色空间try:if self.Com_ColorZone.count()<=0:Information = ValueList = hv_Length = NoneHOperatorSet.InfoFramegrabber(HTuple(driverName),HTuple("color_space"),Information,ValueList)hv_Length = HOperatorSet.TupleLength(ValueList, HTuple(hv_Length))length = hv_Length[0].Ifor i in range(0,length):self.Com_ColorZone.addItem(ValueList[i].S)except Exception as e:pass#曝光时间try:hv_Value = Noneif driverName == 'DirectShow':self.Slider_ExporeTime.setMinimum(-13)self.Slider_ExporeTime.setMaximum(-1)self.Slider_ExporeTime.setValue(-1)self.Lab_ExporeTimeOutValue.setText(str(self.Slider_ExporeTime.value()))self.Check_AutoExporeTimeOut.setChecked(True)self.Check_AutoExporeTimeOut.setEnabled(True)self.Slider_ExporeTime.setEnabled(False)HOperatorSet.SetFramegrabberParam(self.hv_AcqHandle, HTuple("exposure"), HTuple("auto"))else:hv_Value = HOperatorSet.GetFramegrabberParam(self.hv_AcqHandle, HTuple("ExposureTime"), hv_Value)extime = hv_Value[0].Dself.Slider_ExporeTime.setMinimum(0)self.Slider_ExporeTime.setMaximum(600000)self.Slider_ExporeTime.setValue(extime)self.Lab_ExporeTimeOutValue.setText(str(self.Slider_ExporeTime.value()))self.Check_AutoExporeTimeOut.setChecked(False)self.Check_AutoExporeTimeOut.setEnabled(False)self.Slider_ExporeTime.setEnabled(True)except Exception as e:pass#增益try:hv_Value = Nonehv_Value = HOperatorSet.GetFramegrabberParam(self.hv_AcqHandle, HTuple("Gain"), hv_Value)gain = hv_Value[0].Dself.Slider_Gray.setMinimum(0)self.Slider_Gray.setMaximum(24)self.Slider_Gray.setValue(gain)self.Lab_GrayValue.setText(str(self.Slider_Gray.value()))self.Slider_Gray.setEnabled(True)except Exception as e:pass

设置相机属性

#设置白平衡
def on_Check_AutoExporeTimeOut(self):Driver = self.Com_CameraList.currentText().split(":")if self.Check_AutoExporeTimeOut.isChecked():if Driver[0] == "DirectShow":self.Slider_ExporeTime.setEnabled(False)try:HOperatorSet.SetFramegrabberParam(self.hv_AcqHandle, HTuple("exposure"), HTuple("auto"))except Exception as e:passelse:self.Slider_ExporeTime.setEnabled(True)# 设置相机曝光时间
def Slider_ExporeTime_valueChange(self,value):Driver = self.Com_CameraList.currentText().split(":")if self.Check_AutoExporeTimeOut.isChecked() == False:exposure = self.Slider_ExporeTime.value()self.Lab_ExporeTimeOutValue.setText(str(exposure))try:if Driver[0] == "DirectShow":HOperatorSet.SetFramegrabberParam(self.hv_AcqHandle, HTuple("exposure"), HTuple(exposure))else:HOperatorSet.SetFramegrabberParam(self.hv_AcqHandle, HTuple("ExposureTime"), HTuple(exposure))except Exception as e:pass# 设置增益
def Slider_Gray_valueChanged(self):gain = self.Slider_Gray.value()self.Lab_GrayValue.setText(str(gain))try:HOperatorSet.SetFramegrabberParam(self.hv_AcqHandle, HTuple("Gain"), HTuple(gain))except Exception as e:pass

显示图像

def GetImage(self):if self.OpenCarmerFlag == True:try:self.ho_Image = HOperatorSet.GrabImageAsync(self.ho_Image, self.hv_AcqHandle, HTuple(-1))HOperatorSet.DispObj(self.ho_Image, self.hv_WindowHandle)self.workerThread.FinishFlag = Falseexcept Exception as e:pass

3.Calibration.py重要函数解析

这里主要是使用仿射变换实现坐标转换,比如像素坐标转机器人坐标,首先定义坐标变量的数据,目前只写了3点标定,

class CameraCalibrationPoint:def __init__(self):self.P1_Image_X = -1self.P1_Image_Y = -1self.P1_Robot_X = -1self.P1_Robot_Y = -1self.P2_Image_X = -1self.P2_Image_Y = -1self.P2_Robot_X = -1self.P2_Robot_Y = -1self.P3_Image_X = -1self.P3_Image_Y = -1self.P3_Robot_X = -1self.P3_Robot_Y = -1self.RobotHommatFlag = False     # 是否保存了转换数据self.RobotHommat = None          # 转换矩阵

用到的事件绑定

def BindEvent(self):self.CalibrationNum_ComBo.currentIndexChanged.connect(self.CalibrationNum_ComBo_currentIndexChanged)   # 标定的工位号self.Btn_SaveCalib.clicked.connect(self.Btn_SaveCalib_clicked)    # 保存标定数据self.pushButton_2.clicked.connect(self.pushButton_2_clicked)    # 测试转换数据

标定数据保存

def AffineTran(self,CurrentNum):concat = concat1 = concat2 = concat3 = Nonetry:concat = HOperatorSet.TupleConcat(concat, HTuple(self.MyPoint[CurrentNum].P1_Image_X), concat)concat1 = HOperatorSet.TupleConcat(concat1, HTuple(self.MyPoint[CurrentNum].P1_Image_Y), concat1)concat2 = HOperatorSet.TupleConcat(concat2, HTuple(self.MyPoint[CurrentNum].P1_Robot_X), concat2)concat3 = HOperatorSet.TupleConcat(concat3, HTuple(self.MyPoint[CurrentNum].P1_Robot_Y), concat3)concat = HOperatorSet.TupleConcat(concat, HTuple(self.MyPoint[CurrentNum].P2_Image_X), concat)concat1 = HOperatorSet.TupleConcat(concat1, HTuple(self.MyPoint[CurrentNum].P2_Image_Y), concat1)concat2 = HOperatorSet.TupleConcat(concat2, HTuple(self.MyPoint[CurrentNum].P2_Robot_X), concat2)concat3 = HOperatorSet.TupleConcat(concat3, HTuple(self.MyPoint[CurrentNum].P2_Robot_Y), concat3)concat = HOperatorSet.TupleConcat(concat, HTuple(self.MyPoint[CurrentNum].P3_Image_X), concat)concat1 = HOperatorSet.TupleConcat(concat1, HTuple(self.MyPoint[CurrentNum].P3_Image_Y), concat1)concat2 = HOperatorSet.TupleConcat(concat2, HTuple(self.MyPoint[CurrentNum].P3_Robot_X), concat2)concat3 = HOperatorSet.TupleConcat(concat3, HTuple(self.MyPoint[CurrentNum].P3_Robot_Y), concat3)self.MyPoint[CurrentNum].RobotHommat = HOperatorSet.VectorToHomMat2d(concat,concat1,concat2,concat3,self.MyPoint[CurrentNum].RobotHommat)self.MyPoint[CurrentNum].RobotHommatFlag = Trueself.label_5.setText("OK")except Exception as e:self.MyPoint[CurrentNum].RobotHommatFlag = Falseself.label_5.setText("NG")

测试转换坐标

def PixelToRobot(self,id,x,y):if self.MyPoint[id].RobotHommatFlag == True:try:Qx = Qy = NoneHOperatorSet.AffineTransPoint2d(self.MyPoint[id].RobotHommat,HTuple(float(x)),HTuple(float(y)),HTuple(Qx),HTuple(Qy))return Qx[0].D,Qy[0].Dexcept:return -1,-1return -1,-1

4.Helper.py重要函数解析

这个文件比较简单,主要就显示一张图片而已

class Ui_Helper(object):def setupUi(self, Helper):Helper.setObjectName("Helper")Helper.resize(439, 438)icon = QtGui.QIcon()icon.addPixmap(QtGui.QPixmap(":/CtuImageMatching/Resources/37.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)Helper.setWindowIcon(icon)self.gridLayout = QtWidgets.QGridLayout(Helper)self.gridLayout.setContentsMargins(11, 11, 11, 11)self.gridLayout.setSpacing(6)self.gridLayout.setObjectName("gridLayout")self.label = QtWidgets.QLabel(Helper)self.label.setText("")self.label.setPixmap(QtGui.QPixmap(":/CtuImageMatching/Resources/38.png"))self.label.setScaledContents(True)self.label.setObjectName("label")self.gridLayout.addWidget(self.label, 0, 0, 1, 1)self.retranslateUi(Helper)QtCore.QMetaObject.connectSlotsByName(Helper)def retranslateUi(self, Helper):_translate = QtCore.QCoreApplication.translateHelper.setWindowTitle(_translate("Helper", "联系我们:Tel:189xxxx2753"))

5.RobotVision.py主界面重要函数

此文件绑定的函数比较多,这里主要讲解重要函数

1.初始化函数

此方法主要是对整个软件的初始化部分,包括各个变量的初始化

def __init__(self, parent=None):super(RobotVision, self).__init__(parent)self.ui = Ui_CtuImageMatchingClass()self.ui.setupUi(self)self.BindEvent()self.RootPath = os.getcwd()self.FilePath = self.RootPath + "\\VisionModel"try:os.mkdir(self.FilePath)except:passfileIni = self.FilePath + "\\DefaultSetting.ini"if os.path.exists(fileIni) == False:conf = configparser.ConfigParser()conf.add_section("CameraType")conf.set("CameraType", "CameraInterface", "0")with open(fileIni, 'w') as conffile:conf.write(conffile)self.CameraWindow = CameraMainWindow()self.Camera = Ui_CameraSetting(self.FilePath)self.Camera.setupUi(self.CameraWindow)self.CalibWindow = CalibrationMainWindow()self.Calib = Ui_Calibration(self.FilePath)self.Calib.setupUi(self.CalibWindow)self.MyHelperWindow = HelperMainWindow()self.MyHelp = Ui_Helper()self.MyHelp.setupUi(self.MyHelperWindow)self.VisionFunCode = ""HOperatorSet.SetSystem(HTuple("clip_region"),HTuple("false"))self.ReadCodeROI()self.ReadModel(0,self.ui.MaxModelNum)self.VisionFunFlag = Trueself.DrawFlag = False

2.halcon窗体初始化

这里主要初始化halcon窗体,是主页面的显示位置

def InitHalcon(self):try:HOperatorSet.CloseWindow(self.ui.MyCurrentControl.hv_WindowHandle)except Exception as e:passHOperatorSet.SetWindowAttr(HTuple("background_color"), HTuple("white"))winID = self.ui.ImageLab.winId()self.ui.MyCurrentControl.hv_WindowHandle = HOperatorSet.OpenWindow(HTuple(0), HTuple(0), HTuple(self.ui.ImageLab.geometry().width()), HTuple(self.ui.ImageLab.geometry().height()), HTuple(winID), HTuple(""), HTuple(""), self.ui.MyCurrentControl.hv_WindowHandle)HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("red"))HOperatorSet.SetDraw(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("margin"))HOperatorSet.SetLineWidth(self.ui.MyCurrentControl.hv_WindowHandle, HTuple(1))self.GetImagePixelTimer = QTimer(self)self.GetImagePixelTimer.timeout.connect(self.GetImagePixel)self.GetImagePixelTimer.start(50)# 线程self.workerThreadGetMore = PyThread()self.workerThreadGetMore.Set_ThreadSleep(0.1)self.workerThreadGetMore.threadSignal.connect(self.GetMoreImage)

3.绘制ROI区域,例子分为绘制矩形

绘制矩形ROI

def on_Rectangle1Action(self):if self.HObjectIsNull(self.ui.MyCurrentControl.ho_Image):returnhv_Row1 = Nonehv_Column1 = Nonehv_Row2 = Nonehv_Column2 = NoneROITemp = NoneHOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("red"))HOperatorSet.DrawRectangle1(self.ui.MyCurrentControl.hv_WindowHandle, HTuple(hv_Row1), HTuple(hv_Column1), HTuple(hv_Row2), HTuple(hv_Column2))ROITemp = HOperatorSet.GenRectangle1(ROITemp,hv_Row1,hv_Column1,hv_Row2,hv_Column2)if self.HObjectIsNull(self.ui.MyCurrentControl.ROITemp) == True:self.ui.MyCurrentControl.ROITemp = ROITempelse:self.RunROI(ROITemp)self.ShowRunROI()

4.ROI运算逻辑

这里主要是ROI的运算规则:并集、交集、差集

def RunROI(self,ROIObj):if self.ui.MyCurrentControl.ROIRunType == 0:self.ui.MyCurrentControl.ROITemp = HOperatorSet.Union2(self.ui.MyCurrentControl.ROITemp,ROIObj,self.ui.MyCurrentControl.ROITemp)returnif self.ui.MyCurrentControl.ROIRunType == 1:self.ui.MyCurrentControl.ROITemp = HOperatorSet.Intersection(self.ui.MyCurrentControl.ROITemp, ROIObj, self.ui.MyCurrentControl.ROITemp)returnif self.ui.MyCurrentControl.ROIRunType == 2:self.ui.MyCurrentControl.ROITemp = HOperatorSet.Difference(self.ui.MyCurrentControl.ROITemp, ROIObj, self.ui.MyCurrentControl.ROITemp)return

5.创建模板

这里是创建模板的函数,这里以创建灰度模板为例子

# 创建模板进入的主函数
def CreateModelAction_triggered(self):if self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].EffectiveFlag:if QMessageBox.information(self, '提示', '已经存在模板是否替换:模板'+str(self.ui.MyCurrentControl.ModelNum+1), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) == 65536:self.ui.MyCurrentControl.ROITemp = HOperatorSet.GenEmptyObj(self.ui.MyCurrentControl.ROITemp)returnif self.HObjectIsNull(self.ui.MyCurrentControl.ho_Image) or self.HObjectIsNull(self.ui.MyCurrentControl.ROITemp):QMessageBox.information(self, '提示','无图或者无ROI', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)returnself.InitModel(self.ui.MyCurrentControl.ModelNum,self.ui.MyCurrentControl.ModelNum+1)#把参数保存在内存中self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].h_img = self.ui.MyCurrentControl.ho_Imageself.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].h_roi = self.ui.MyCurrentControl.ROITempself.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].TemplateAlgorithm = self.ui.MyCurrentControl.FindModelFunself.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].modelNum = self.ui.MyCurrentControl.ModelNumself.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].startAngle = self.ui.StartAngleBox.value()self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].endAngle = self.ui.AngleSizeBox.value()if self.ui.AutoLeval_Check.isChecked():self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].Level = -1else:self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].Level = self.ui.LevalBox.value()self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].FindModelTimeOut = int(self.ui.FindModelTimeOut_Edit.text())self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].Score = self.ui.ScoreBox.value()self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].MatchNum = self.ui.MatchNum_Combo.currentIndex()self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].DeformationNum = self.ui.Def_ComBo.currentIndex()Res = Falseif self.ui.MyCurrentControl.FindModelFun == 0:Res = self.Create_ShapeModel()elif self.ui.MyCurrentControl.FindModelFun == 1:Res = self.Create_GrayModel()elif self.ui.MyCurrentControl.FindModelFun == 2:Res = self.Create_NCCModel()elif self.ui.MyCurrentControl.FindModelFun == 3:Res = self.Create_ChangeShapeModel()else:passif Res == False:self.InitModel(self.ui.MyCurrentControl.ModelNum,self.ui.MyCurrentControl.ModelNum + 1)self.ui.MyCurrentControl.ROITemp = HOperatorSet.GenEmptyObj(self.ui.MyCurrentControl.ROITemp)self.ui.statusBar.showMessage("模板创建失败!")else:self.ui.statusBar.showMessage("模板创建成功!")self.WriteData(self.ui.MyCurrentControl.ModelNum)self.WriteImageROI(self.ui.MyCurrentControl.ModelNum)
# 创建灰度模板
def Create_GrayModel(self):if self.HObjectIsNull(self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].h_img) or self.HObjectIsNull(self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].h_roi):return Falsehv_ImageReduced = hv_Orgin_Area = Nonehv_ImageReduced = HOperatorSet.ReduceDomain(self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].h_img, self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].h_roi, hv_ImageReduced)try:self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].hv_ModelID = HOperatorSet.CreateTemplateRot(hv_ImageReduced,HTuple(4),HTuple(self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].startAngle).TupleRad(), HTuple(self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].endAngle).TupleRad(),HTuple(0.0982),HTuple("sort"),HTuple("original"),self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].hv_ModelID)except Exception as e:return FalseHOperatorSet.ClearWindow(self.ui.MyCurrentControl.hv_WindowHandle)HOperatorSet.DispObj(self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].h_img, self.ui.MyCurrentControl.hv_WindowHandle)HOperatorSet.AreaCenter(self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].h_roi, HTuple(hv_Orgin_Area),HTuple(self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].hv_Orgin_Row),HTuple(self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].hv_Orgin_Column))HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("blue"))HOperatorSet.DispObj(self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].h_roi,self.ui.MyCurrentControl.hv_WindowHandle)HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("green"))HOperatorSet.DispCross(self.ui.MyCurrentControl.hv_WindowHandle,self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].hv_Orgin_Row,self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].hv_Orgin_Column,HTuple(self.ui.MyCurrentControl.ho_Width[0].I / 24), HTuple(0))self.ui.MyCurrentControl.ROITemp = HOperatorSet.GenEmptyObj(self.ui.MyCurrentControl.ROITemp)self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].EffectiveFlag = Truereturn True

6.查找模板,实现模板匹配

这里主要实现模板匹配,根据不同的算法实现不同的模板匹配结果

# 模板匹配的总入口
def RunModelAction_triggered(self):if self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].EffectiveFlag == False:if QMessageBox.information(self, '提示', '当前模板号无模板', QMessageBox.Yes) == 65536:returnEachRes = []if self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].TemplateAlgorithm == 0:EachRes = self.FindModel_Shape(self.ui.MyCurrentControl.ModelNum)elif self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].TemplateAlgorithm == 1:EachRes = self.FindModel_Gray(self.ui.MyCurrentControl.ModelNum)elif self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].TemplateAlgorithm == 2:EachRes = self.FindModel_NCC(self.ui.MyCurrentControl.ModelNum)elif self.ui.MyModelCom[self.ui.MyCurrentControl.ModelNum].TemplateAlgorithm == 3:EachRes = self.FindModel_ChangeShape(self.ui.MyCurrentControl.ModelNum)else:passif len(EachRes) == 0:self.ui.statusBar.showMessage("模板匹配失败!")else:self.ui.statusBar.showMessage(EachRes[0])

以灰度匹配为例

def FindModel_Gray(self,ModelNum):pp = []if self.HObjectIsNull(self.ui.MyCurrentControl.ho_Image) or self.ui.MyModelCom[ModelNum].hv_ModelID is None:return pphv_RowCheck = hv_ColumnCheck = hv_AngleCheck = hv_Error = hMat2D = ho_ImageAffinTrans = NoneScore = self.ui.MyModelCom[ModelNum].Score / 100.0hv_img = self.ui.MyCurrentControl.ho_Imageif self.ui.MyModelCom[ModelNum].SearchROIFlag:hv_img = HOperatorSet.ReduceDomain(hv_img, self.ui.MyModelCom[ModelNum].h_SearchROI, hv_img)try:HOperatorSet.BestMatchRotMg(hv_img,self.ui.MyModelCom[ModelNum].hv_ModelID,HTuple(self.ui.MyModelCom[ModelNum].startAngle).TupleRad(), HTuple(self.ui.MyModelCom[ModelNum].endAngle).TupleRad(),HTuple(100-Score),HTuple("true"),HTuple(4),hv_RowCheck,hv_ColumnCheck,hv_AngleCheck,hv_Error)except Exception as e:return pptry:length = int(hv_Error.TupleLength())if length>0:if (Score*100) > (100-hv_Error[0].D):return ppif self.ui.MyModelCom[ModelNum].TargetFlag == True:RowTrans = ColumnTrans = NonehMat2D = HOperatorSet.VectorAngleToRigid(self.ui.MyModelCom[ModelNum].hv_Orgin_Row, self.ui.MyModelCom[ModelNum].hv_Orgin_Column, HTuple(0), HTuple(hv_RowCheck[0].D), HTuple(hv_ColumnCheck[0].D), HTuple(hv_AngleCheck[0].D), hMat2D)HOperatorSet.AffineTransPixel(hMat2D, self.ui.MyModelCom[ModelNum].hv_Target_Row, self.ui.MyModelCom[ModelNum].hv_Target_Column, RowTrans, ColumnTrans)HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("green"))HOperatorSet.DispCross(self.ui.MyCurrentControl.hv_WindowHandle, HTuple(RowTrans[0].D), HTuple(ColumnTrans[0].D), HTuple(self.ui.MyCurrentControl.ho_Width[0].I / 24), HTuple(hv_AngleCheck[0].D))ho_ImageAffinTrans = HOperatorSet.AffineTransRegion(self.ui.MyModelCom[ModelNum].h_roi, ho_ImageAffinTrans, hMat2D, HTuple("constant"))HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("blue"))HOperatorSet.DispObj(ho_ImageAffinTrans, self.ui.MyCurrentControl.hv_WindowHandle)pp.append(str(RowTrans[0].D) + "," + str(ColumnTrans[0].D) + "," + str(hv_AngleCheck[0].D * 57.3) + "," + str(100-hv_Error[0].D))else:HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("green"))HOperatorSet.DispCross(self.ui.MyCurrentControl.hv_WindowHandle, HTuple(hv_RowCheck[0].D), HTuple(hv_ColumnCheck[0].D), HTuple(self.ui.MyCurrentControl.ho_Width[0].I / 24), HTuple(hv_AngleCheck[0].D))hMat2D = HOperatorSet.VectorAngleToRigid(self.ui.MyModelCom[ModelNum].hv_Orgin_Row, self.ui.MyModelCom[ModelNum].hv_Orgin_Column, HTuple(0), HTuple(hv_RowCheck[0].D), HTuple(hv_ColumnCheck[0].D), HTuple(hv_AngleCheck[0].D), hMat2D)ho_ImageAffinTrans = HOperatorSet.AffineTransRegion(self.ui.MyModelCom[ModelNum].h_roi, ho_ImageAffinTrans, hMat2D, HTuple("constant"))HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("blue"))HOperatorSet.DispObj(ho_ImageAffinTrans, self.ui.MyCurrentControl.hv_WindowHandle)pp.append(str(hv_RowCheck[0].D) + "," + str(hv_ColumnCheck[0].D) + "," + str(hv_AngleCheck[0].D * 57.3) + "," + str(100-hv_Error[0].D))if self.ui.MyModelCom[ModelNum].SearchROIFlag == True:HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("orange"))HOperatorSet.DispObj(self.ui.MyModelCom[ModelNum].h_SearchROI,self.ui.MyCurrentControl.hv_WindowHandle)except Exception as e:passreturn pp

7.读取条形码

这里把重要函数读取条形码示例

def ReadBarCode(self):if self.HObjectIsNull(self.ui.MyCurrentControl.ho_Image):return "Code:-1"hv_BarCodeHandle = hv_DecodedDataStrings = hv_BarCodeResults1 = ho_SymbolRegions = hv_DecodedDataTypes = Nonehv_img = self.ui.MyCurrentControl.ho_Imageif self.ui.MyCodeCom.BarCodeROIFlag == True:hv_img = HOperatorSet.ReduceDomain(hv_img, self.ui.MyCodeCom.BarCodeROI, hv_img)try:hv_BarCodeHandle = HOperatorSet.CreateBarCodeModel(HTuple(),HTuple(),hv_BarCodeHandle)HOperatorSet.SetBarCodeParam(hv_BarCodeHandle,HTuple("element_size_min"),HTuple(1))HOperatorSet.FindBarCode(hv_img,ho_SymbolRegions,hv_BarCodeHandle,HTuple(self.ui.BarCodeType[self.ui.MyCurrentControl.CurrentBarCodeType]),hv_DecodedDataStrings)hv_BarCodeResults1 = HOperatorSet.GetBarCodeResult(hv_BarCodeHandle, HTuple("all"), HTuple("orientation"), hv_BarCodeResults1)hv_DecodedDataTypes = HOperatorSet.GetBarCodeResult(hv_BarCodeHandle, HTuple("all"), HTuple("decoded_types"), hv_DecodedDataTypes)HOperatorSet.ClearBarCodeModel(hv_BarCodeHandle)except Exception as e:return "Code:-1"if self.ui.MyCodeCom.BarCodeROIFlag == True:HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("orange"))HOperatorSet.DispObj(self.ui.MyCodeCom.BarCodeROI, self.ui.MyCurrentControl.hv_WindowHandle)length = int(hv_DecodedDataStrings.TupleLength())if length > 0:HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("green"))HOperatorSet.DispObj(ho_SymbolRegions, self.ui.MyCurrentControl.hv_WindowHandle)Angle = hv_BarCodeResults1[0].DCode = hv_DecodedDataTypes[0].S + ":" + hv_DecodedDataStrings[0].S + "," + str(Angle)return Codeelse:return "Code:-1"

8.读取二维码

这里把重要函数读取二维码示例

def ReadQRCode(self):if self.HObjectIsNull(self.ui.MyCurrentControl.ho_Image):return "Code:-1"ho_SymbolXLDs = hv_DataCodeHandle = hv_ResultHandles = hv_DecodedDataStrings = Nonehv_img = self.ui.MyCurrentControl.ho_Imageif self.ui.MyCodeCom.QRCodeROIFlag == True:hv_img = HOperatorSet.ReduceDomain(hv_img, self.ui.MyCodeCom.QRCodeROI, hv_img)if self.ui.MyCodeCom.QRCodeROIFlag == True:HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("orange"))HOperatorSet.DispObj(self.ui.MyCodeCom.QRCodeROI, self.ui.MyCurrentControl.hv_WindowHandle)try:hv_DataCodeHandle = HOperatorSet.CreateDataCode2dModel(HTuple(self.ui.DataCodeType[self.ui.MyCurrentControl.CurrentDataCodeType]),HTuple(),HTuple(),hv_DataCodeHandle)HOperatorSet.FindDataCode2d(hv_img,ho_SymbolXLDs,hv_DataCodeHandle,HTuple(), HTuple(),hv_ResultHandles,hv_DecodedDataStrings)HOperatorSet.ClearDataCode2dModel(hv_DataCodeHandle)HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("green"))HOperatorSet.DispObj(ho_SymbolXLDs, self.ui.MyCurrentControl.hv_WindowHandle)length = int(hv_DecodedDataStrings.TupleLength())if length > 0:Code = self.ui.DataCodeType[self.ui.MyCurrentControl.CurrentDataCodeType] + ":" + hv_DecodedDataStrings[0].Sreturn Codeexcept Exception as e:passreturn "Code:-1"

9.读取OCR

这里以基本的OCR进行实验

def ReadOCRCode(self):if self.HObjectIsNull(self.ui.MyCurrentControl.ho_Image):return "OCR:-1"hv_img = self.ui.MyCurrentControl.ho_Imageif self.ui.MyCodeCom.OCRCodeROIFlag == True:hv_img = HOperatorSet.ReduceDomain(hv_img, self.ui.MyCodeCom.OCRCodeROI, hv_img)try:ho_Region2 = ho_ConnectedRegions1 = ho_SelectedRegions1 = ho_SortedRegions = hv_UsedThreshold2 = hv_OCRHandle = hv_Class = hv_Confidence = NoneHOperatorSet.BinaryThreshold(hv_img,ho_Region2,HTuple("max_separability"),HTuple("dark"),hv_UsedThreshold2)ho_ConnectedRegions1 = HOperatorSet.Connection(ho_Region2,ho_ConnectedRegions1)ho_SelectedRegions1 = HOperatorSet.SelectShape(ho_ConnectedRegions1,ho_SelectedRegions1,HTuple("area"),HTuple("and"),HTuple(150.0),HTuple(99999.0))ho_SortedRegions = HOperatorSet.SortRegion(ho_SelectedRegions1,ho_SortedRegions,HTuple("character"),HTuple("true"),HTuple("row"))hv_OCRHandle = HOperatorSet.ReadOcrClassMlp(HTuple(self.RootPath + "\\genicam\\Industrial.omc"),hv_OCRHandle)HOperatorSet.DoOcrMultiClassMlp(ho_SortedRegions,hv_img,hv_OCRHandle,hv_Class,hv_Confidence)HOperatorSet.ClearOcrClassMlp(hv_OCRHandle)if self.ui.MyCodeCom.OCRCodeROIFlag == True:HOperatorSet.SetColor(self.ui.MyCurrentControl.hv_WindowHandle, HTuple("orange"))HOperatorSet.DispObj(self.ui.MyCodeCom.OCRCodeROI, self.ui.MyCurrentControl.hv_WindowHandle)length = int(hv_Class.TupleLength())if length > 0:Code = "OCR:"for i in range(0,length):Code = Code + hv_Class[i].Sreturn Codeexcept Exception as e:passreturn "OCR:-1"

10.基于python+pyqt的通信:Tcp的服务器及客户端

服务器:

class PyTcpServer(QtCore.QThread):TcpServerRecvEvent = QtCore.pyqtSignal(str)def __init__(self, parent = None):super(PyTcpServer, self).__init__(parent)self.tcpServer = Noneself.tcpServerSocket = Noneself.TcpServerListenFlag = Falsedef SetIp(self,ip):self.IP = ipdef SetPort(self,port):self.PORT = portdef startListen(self):self.tcpServer = QTcpServer()if not self.tcpServer.listen(QHostAddress(self.IP), int(self.PORT)):  # QHostAddress.LocalHostprint(self.tcpServer.errorString())returnself.tcpServer.newConnection.connect(self.TCPServerNewConnect)self.TcpServerListenFlag = Truedef DisListen(self):self.TcpServerListenFlag = Falseif self.tcpServer:self.tcpServer.deleteLater()self.tcpServer.close()self.tcpServer = Noneif self.tcpServerSocket:self.tcpServerSocket.abort()self.tcpServerSocket.close()self.tcpServerSocket = Nonedef TCPServerNewConnect(self):self.blockSize = 0if self.tcpServerSocket:self.tcpServerSocket.abort()self.tcpServerSocket = self.tcpServer.nextPendingConnection()self.tcpServerSocket.readyRead.connect(self.TCPServerReceiveMessage)def TCPServerReceiveMessage(self):buf = self.tcpServerSocket.readAll()mes = str(buf, encoding='utf-8')self.TcpServerRecvEvent.emit(mes)def SendData(self,mes):if self.tcpServerSocket:input_s = mesinput_s = str(input_s).encode('utf-8')self.tcpServerSocket.write(input_s)else:pass

客户端:

class PyTcpClient(QtCore.QThread):TcpClientRecvEvent = QtCore.pyqtSignal(str)def __init__(self, parent = None):super(PyTcpClient, self).__init__(parent)self.TcpClientSocket = NoneTCPClientConnectFlag = Falsedef SetIp(self,ip):self.IP = ipdef SetPort(self,port):self.PORT = portdef ConnectServer(self):self.TcpClientSocket = QTcpSocket()self.TcpClientSocket.connectToHost(self.IP, self.PORT)if self.TcpClientSocket.waitForConnected(3000) == False:return Falseself.TcpClientSocket.readyRead.connect(self.TCPClientReceiveMessage)TCPClientConnectFlag = Truereturn Truedef DisConnectedServer(self):self.TcpClientSocket.abort()self.TcpClientSocket.close()self.TcpClientSocket = NoneTCPClientConnectFlag = Falsedef TCPClientReceiveMessage(self):buf = self.TcpClientSocket.readAll()mes = str(buf, encoding='utf-8')self.TcpClientRecvEvent.emit(mes)def SendData(self,mes):if self.TcpClientSocket:input_s = mesinput_s = str(input_s).encode('utf-8')self.TcpClientSocket.write(input_s)else:pass

总结

该工程篇幅比较多,不过具体的函数在文章中已经表标明,具体的查看源码使用。
python调用halcon只要理解了传参和出参,算子的调用基本无问题

基于python+pyqt+halcon实现视觉定位(halcon12.0)【附部分源码】相关推荐

  1. 【GPS仿真】基于matlab GPS信号捕获跟踪定位仿真【含Matlab源码 1960期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[GPS仿真]基于matlab GPS信号捕获跟踪定位仿真[含Matlab源码 1960期] 点击上面蓝色字体,直接付费下载,即可. 获取 ...

  2. Python编程:实现词云生成(附详细源码)

    Python编程:实现词云生成(附详细源码) 词云是一种数据可视化的方式,它可以用来展示某个主题下的主要关键词汇.在Python中,我们可以使用 wordcloud 库来实现词云的生成.本文将带您一步 ...

  3. 基于ITD实现的轴承故障信号分解并附Matlab源码

    基于ITD实现的轴承故障信号分解并附Matlab源码 轴承是旋转机械中重要的支撑部件,其状态的健康程度对设备运行的性能和寿命有着至关重要的影响.因此,轴承状态监测和故障诊断成为了研究热点.本文基于IT ...

  4. Python实现行业轮动量化选股【附完整源码】

    编者荐语: 所谓山不转水转,行业中的动量也存在一定的轮换效应.今天给大家分享一篇来自<量化小白上分记>的研报复现文章,基于因子动量.波动率.偏度.峰度来刻画行业轮动,对于构建行业轮动量化选 ...

  5. 牛逼,一整套基于Java开发的的区块链系统(附完整源码)

    前言 近几年区块链概念越来越火,特别是区块链技术被纳入国家基础设施建设名单后,各大企业也开始招兵买马,对区块链技术进行研究,从各大招聘网站的区块链职位来看,薪资待遇都很不错,月薪30K到80K的都有, ...

  6. 基于SSM框架实现期刊杂志稿件管理系统【附项目源码】

    基于SSM框架实现期刊杂志稿件管理系统演示 系统后台: 模块一: 系统基本信息(系统管理员) 投稿人信息管理(检索/添加/修改/删除): 编号.登录名.登录密码.姓名.性别.电话.通讯地址 作者信息管 ...

  7. 基于SSM框架实现期刊杂志稿件管理系统【附项目源码】分享

    基于SSM框架实现期刊杂志稿件管理系统演示 系统后台: 模块一: 系统基本信息(系统管理员) 投稿人信息管理(检索/添加/修改/删除): 编号.登录名.登录密码.姓名.性别.电话.通讯地址 作者信息管 ...

  8. 基于Spring+Jsp+MySQL的Java项目-家教系统 附:源码课件

    项目描述 家教信息管理系统主要用于协助工作人员进行系统内部数据管理并为系统用户提供在线沟通.资源共享等服务.本论文分析了当前国内家教公司的核心业务内容和主流家教管理平台的功能,在传统家教公司管理软件单 ...

  9. 基于Python实现的手机基站信息经济分析系统 课程报告+源码及数据

    目录 一.项目背景 1 二.分析的经济逻辑与方法 1 三.分析结果 4 3.1. 基站层面的分析结果 4 3.2. 用户层面的分析结果 12 四.结论 15 一.项目背景 据工信部调查,截止 2020 ...

最新文章

  1. c++中的list用法
  2. 网络传输为什么要序列化_企业为什么要选择网络营销外包
  3. Spring AOP详解(http://sishuok.com/forum/posts/list/281.html)
  4. 深度学习 用户画像_一文告诉你什么是用户画像
  5. java判断是否是路径_java判断是否是目录
  6. Winform窗体中发送HTTP请求 手工发送HTTP请求主要是调用 System.Net的HttpWebResponse方法
  7. Matlab的parfor并行编程
  8. android sh 指令_Android ADB Shell命令解析
  9. mybatis连接oracle
  10. request python菜鸟教程_Python之学习菜鸟教程踩的坑
  11. 徐松亮硬件教学-微波天线设计-基于HFSS软件的天线设计流程
  12. e320/t420/w520等 qm67/hm65/hm67等 6系芯片组更新BIOS以安装三代酷睿cpu提升性能的想法
  13. 图片转化成emf等格式的办法
  14. 会员卡管理系统从哪些方面解决门店会员营销困扰?
  15. 卖出跨式套利与买入蝶式价差
  16. 华为手机备份的通讯录是什么文件_华为通讯录怎么导入新手机(三种方法帮你导通讯录)...
  17. YOLOV2 YOLO9000
  18. 港科夜闻|「广州粤港澳大湾区研究院」成立,香港科技大学校长史维教授获聘担任研究院顾问...
  19. Debian 执行apt-get update失败提示:请使用 apt-cdrom,通过它可以让 APT 识别该盘片。apt-get upgdate 不能被用来加入新的盘片
  20. c语言程序电机,直流电机控制C语言程序

热门文章

  1. K线入门之单根K线图
  2. Navicat工具怎么得到MySQL数据库EXCEL表结构
  3. mysql5.7对应jdbc驱动版本_mysql5.7.11对应的JDBC驱动是哪个版本
  4. FTU馈线终端装置中电流传感器的选择
  5. 【问题解决】Error:(3, 46) java: 程序包org.springframework.context.annotation不存在
  6. 难怪好人有恶报,原来秘密在这里
  7. 输入网络密码来进入共享计算机,win7系统电脑共享文件时提示“输入网络密码”怎么解决...
  8. mysql删除关键字记录,在MySQL删除表语句中,下列选项用于删除表的结构和记录数据全部,并且不能恢复的是( )关键字。...
  9. PyCharm中配置SVN
  10. sp_depends