本文主要是介绍毕业设计 双目立体视觉图像匹配与测距,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 0 项目说明
- 1 研究目的
- 2 研究方法
- 3 研究结论
- 4 项目源码
- 5 最后
0 项目说明
基于双目立体视觉的图像匹配与测距
提示:适合用于课程设计或毕业设计,工作量达标,源码开放
1 研究目的
双目立体视觉是计算机视觉范畴的核心之一,它利用双目相机来获得目标物体的图像,经过物体图像处理之后得到目标物体所在场景环境的三维信息,最终实现非接触条件下测距,简单便捷。
本次毕业设计主要内容为研究基于双目立体视觉平台上的图像匹配以及目标物体的距离测量技术,图像特征提取部分研究了 SIFT 算法和 SURF 算法,特征匹配部分研究了 BF 法和 FLANN 法,距离测量研究主要通过视差深度的计算,结合视觉坐标系的转换实现三维位置的定位与测量。
2 研究方法
(1)在对相机成像和坐标系原理研究的基础上,依托维视双目立体视觉测量平台 MV-VS220 实现了双目相机标定,以及目标物体图像数据采集。
(2)在灰度化、二值化以及加噪等必要图像预处理的基础上,研究 SIFT、SURF 特征点提取与匹配算法,进行实验并显示提取和匹配效果;研究测距模型和视差深度计算目标物体的深度信息,进行实验并获取测量结果,对测量误差进行分析与讨论。
(3)基于维视双目立体视觉测量平台 MV-VS220,采用 Python+OpenCV 开发工具,设计实现了一个双目立体视觉图像匹配与测距原型系统,可实现对关键环节的过程与结果的演示,以及不同算法的性能比较
3 研究结论
系统可实现对关键环节的过程与结果的演示,以及不同算法的性能比较。系统测试表明,所开发的原型演示系统从界面、功能与性能方面均达到了设计的要求。
4 项目源码
# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'mainimagewidget.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
from MVGigE import *
import os
import shutil
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QMessageBox, QLabel, QFileDialog, QScrollArea, QComboBox, QLineEdit, QSlider, QGridLayout, QGroupBox, QCheckBox
from PyQt5.QtGui import QPixmap, QPalette, QImage, QIcon
from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form_Image(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(800, 600)self.btnStartGrab = QtWidgets.QPushButton(Form)self.btnStartGrab.setGeometry(QtCore.QRect(210, 70, 100, 35))self.btnStartGrab.setStyleSheet("font: bold 14pt \"汉仪喵魂体W\";\n"
"color: rgb(255, 255, 255);\n"
"border:2px solid;\n"
"border-color: rgb(255, 255, 255);\n"
"background-color: rgb(242, 216, 121);")self.btnStartGrab.setObjectName("btnStartGrab")self.btnStopGrab = QtWidgets.QPushButton(Form)self.btnStopGrab.setGeometry(QtCore.QRect(350, 70, 100, 35))self.btnStopGrab.setStyleSheet("font: bold 14pt \"汉仪喵魂体W\";\n"
"color: rgb(255, 255, 255);\n"
"border:2px solid;\n"
"border-color: rgb(255, 255, 255);\n"
"background-color: rgb(242, 216, 121);")self.btnStopGrab.setObjectName("btnStopGrab")self.ResultLabel = QtWidgets.QLabel(Form)self.ResultLabel.setGeometry(QtCore.QRect(70, 485, 660, 70))self.ResultLabel.setStyleSheet("font: 12pt \"汉仪喵魂体W\";\n"
"color: rgb(0, 0, 0);\n"
"border:2px solid;\n"
"border-color: rgb(255, 255, 255);\n"
"background-color: rgb(242, 216, 121);")self.ResultLabel.setObjectName("ResultLabel")self.frame = QtWidgets.QFrame(Form)self.frame.setGeometry(QtCore.QRect(0, 0, 800, 600))self.frame.setStyleSheet("border-image: url(:/newPrefix/img/background.jpg);")self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)self.frame.setFrameShadow(QtWidgets.QFrame.Raised)self.frame.setObjectName("frame")self.btnSaveImage = QtWidgets.QPushButton(Form)self.btnSaveImage.setGeometry(QtCore.QRect(490, 70, 100, 35))self.btnSaveImage.setStyleSheet("font: bold 14pt \"汉仪喵魂体W\";\n"
"color: rgb(255, 255, 255);\n"
"border:2px solid;\n"
"border-color: rgb(255, 255, 255);\n"
"background-color: rgb(242, 216, 121);")self.btnSaveImage.setObjectName("btnSaveImage")self.btnCloseCam = QtWidgets.QPushButton(Form)self.btnCloseCam.setGeometry(QtCore.QRect(630, 70, 100, 35))self.btnCloseCam.setStyleSheet("font: bold 14pt \"汉仪喵魂体W\";\n"
"color: rgb(255, 255, 255);\n"
"border:2px solid;\n"
"border-color: rgb(255, 255, 255);\n"
"background-color: rgb(242, 216, 121);")self.btnCloseCam.setObjectName("btnCloseCam")self.RLabel = QtWidgets.QLabel(Form)self.RLabel.setGeometry(QtCore.QRect(405, 135, 325, 331))self.RLabel.setStyleSheet("font: 14pt \"汉仪喵魂体W\";\n"
"color: rgb(255, 255, 255);\n"
"border:2px;\n"
"border-style:dotted;\n"
"border-color: rgb(242, 216, 121);")self.RLabel.setObjectName("RLabel")self.LLabel = QtWidgets.QLabel(Form)self.LLabel.setGeometry(QtCore.QRect(70, 135, 325, 331))self.LLabel.setStyleSheet("font: 14pt \"汉仪喵魂体W\";\n"
"color: rgb(255, 255, 255);\n"
"border:2px;\n"
"border-style:dotted;\n"
"border-color: rgb(242, 216, 121);")self.LLabel.setObjectName("LLabel")self.btnOpenCam = QtWidgets.QPushButton(Form)self.btnOpenCam.setGeometry(QtCore.QRect(70, 70, 100, 35))self.btnOpenCam.setStyleSheet("font: bold 14pt \"汉仪喵魂体W\";\n"
"color: rgb(255, 255, 255);\n"
"border:2px solid;\n"
"border-color: rgb(255, 255, 255);\n"
"background-color: rgb(242, 216, 121);")self.btnOpenCam.setObjectName("btnOpenCam")self.frame.raise_()self.btnStartGrab.raise_()self.btnStopGrab.raise_()self.ResultLabel.raise_()self.btnSaveImage.raise_()self.btnCloseCam.raise_()self.RLabel.raise_()self.LLabel.raise_()self.btnOpenCam.raise_()self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Form"))self.btnStartGrab.setText(_translate("Form", "采集图像"))self.btnStopGrab.setText(_translate("Form", "停止采集"))self.ResultLabel.setText(_translate("Form", "结果显示区域"))self.btnSaveImage.setText(_translate("Form", "保存图像"))self.btnCloseCam.setText(_translate("Form", "关闭相机"))self.RLabel.setText(_translate("Form", "右图像区域"))self.LLabel.setText(_translate("Form", "左图像区域"))self.btnOpenCam.setText(_translate("Form", "启动相机"))# -------------------------设置按钮点击事件-------------------------------------self.btnOpenCam.clicked.connect(self.openCam)self.btnStartGrab.clicked.connect(self.startGrab)self.btnStopGrab.clicked.connect(self.stopGrab)self.btnCloseCam.clicked.connect(self.closeCam)self.btnSaveImage.clicked.connect(self.saveImage)# 点击启动相机按钮,开始打开左右相机def openCam(self):r = MVInitLib() # 初始化函数库if (r != MVSTATUS_CODES.MVST_SUCCESS):msgBox = QMessageBox(QMessageBox.Warning, '提示', '函数库初始化失败!')msgBox.exec()returnr = MVUpdateCameraList() # 查找连接到计算机上的相机if (r != MVSTATUS_CODES.MVST_SUCCESS):msgBox = QMessageBox(QMessageBox.Warning, '提示', '查找连接计算机失败!')msgBox.exec()returnnCams = MVGetNumOfCameras() # 获取相机数量if (nCams.status != MVSTATUS_CODES.MVST_SUCCESS):msgBox = QMessageBox(QMessageBox.Warning, '提示', nCams.status)msgBox.exec()returnif (nCams.num == 0):msgBox = QMessageBox(QMessageBox.Warning, '提示', '没有找到相机,请确认连接和相机IP设置!')msgBox.exec()return# 左相机hCam = MVOpenCamByIndex(0) # 根据相机的索引返回相机句柄if (hCam.hCam == 0):if (hCam.status == MVSTATUS_CODES.MVST_ACCESS_DENIED):msgBox = QMessageBox(QMessageBox.Warning, '提示', '无法打开相机,可能正被别的软件控制!')msgBox.exec()returnelse:msgBox = QMessageBox(QMessageBox.Warning, '提示', '无法打开相机!')msgBox.exec()returnw = MVGetWidth(hCam.hCam) # 获取图像宽度h = MVGetHeight(hCam.hCam) # 获取图像高度pf = MVGetPixelFormat(hCam.hCam) # 获取图像格式self.hCam = hCam.hCamself.width = w.widthself.height = h.heightself.pixelFormat = pf.pixelFormatif (self.pixelFormat == MV_PixelFormatEnums.PixelFormat_Mono8):self.himage = MVImageCreate(self.width, self.height, 8).himage # 创建图像句柄else:self.himage = MVImageCreate(self.width, self.height, 24).himage # 创建图像句柄# self.LLImage.resize(self.width * 0.25, self.height * 0.25)self.LLabel.resize(self.width * 0.25, self.height * 0.35)self.LLabel.setText("左相机检测正常!")# self.ResultLlabel.setText("左相机检测正常!")# 右相机hCam2 = MVOpenCamByIndex(1) # 根据相机的索引返回相机句柄if (hCam2.hCam == 0):if (hCam2.status == MVSTATUS_CODES.MVST_ACCESS_DENIED):msgBox = QMessageBox(QMessageBox.Warning, '提示', '无法打开相机,可能正被别的软件控制!')msgBox.exec()returnelse:msgBox = QMessageBox(QMessageBox.Warning, '提示', '无法打开相机!')msgBox.exec()returnw2 = MVGetWidth(hCam2.hCam) # 获取图像宽度h2 = MVGetHeight(hCam2.hCam) # 获取图像高度pf2 = MVGetPixelFormat(hCam2.hCam) # 获取图像格式self.hCam2 = hCam2.hCamself.width2 = w2.widthself.height2 = h2.heightself.pixelFormat2 = pf2.pixelFormatif (self.pixelFormat2 == MV_PixelFormatEnums.PixelFormat_Mono8):self.himage2 = MVImageCreate(self.width2, self.height2, 8).himage # 创建图像句柄else:self.himage2 = MVImageCreate(self.width2, self.height2, 24).himage # 创建图像句柄# self.LRImage.resize(self.width2 * 0.25, self.height2 * 0.25)self.RLabel.resize(self.width * 0.25, self.height * 0.35)self.RLabel.setText("右相机检测正常!")# self.ResultLlabel.setText("右相机检测正常!")self.ResultLabel.setText("相机启动正常!")# 点击采集图像按钮,相机开始采集执行本函数def startGrab(self):self.winid = self.LLabel.winId() # 获取label对象的句柄mode = MVGetTriggerMode(self.hCam) # 获取当前相机采集模式source = MVGetTriggerSource(self.hCam) # 获取当前相机信号源self.winid2 = self.RLabel.winId() # 获取label对象的句柄mode2 = MVGetTriggerMode(self.hCam2) # 获取当前相机采集模式source2 = MVGetTriggerSource(self.hCam2) # 获取当前相机信号源if (self.btnStartGrab.text() == '采集图像'):if ((mode.pMode == TriggerModeEnums.TriggerMode_Off) & (mode2.pMode == TriggerModeEnums.TriggerMode_Off)): # 当触发模式关闭的时候,界面的行为# self.btnStartGrab.setText('停止采集')MVStartGrabWindow(self.hCam, self.winid) # 将采集的图像传输到指定窗口MVStartGrabWindow(self.hCam2, self.winid2) # 将采集的图像传输到指定窗口else:if ((source.source == TriggerSourceEnums.TriggerSource_Software) & (source2.source == TriggerSourceEnums.TriggerSource_Software)): # 当触发模式打开且为软触发的时候,界面的行为MVStartGrabWindow(self.hCam, self.winid) # 将采集的图像传输到指定窗口MVStartGrabWindow(self.hCam2, self.winid2) # 将采集的图像传输到指定窗口MVTriggerSoftware(self.hCam)MVTriggerSoftware(self.hCam2)else: # 当触发模式打开且为外触发的时候,界面的行为MVStartGrabWindow(self.hCam, self.winid) # 将采集的图像传输到指定窗口MVStartGrabWindow(self.hCam2, self.winid2) # 将采集的图像传输到指定窗口self.ResultLabel.setText("图像采集开始!")# else:# self.btnStartGrab.setText('开始采集')# MVStopGrabWindow(self.hCam) # 停止采集# MVStopGrabWindow(self.hCam2) # 停止采集# self.btnStopGrab.setEnabled(False)# self.ResultLabel.setText("图像采集停止!")# 暂停或者继续执行本函数def stopGrab(self):if (self.btnStopGrab.text() == '继续采集'):self.btnStopGrab.setText('暂停采集')MVFreezeGrabWindow(self.hCam, False) # 恢复图像传输到左窗口MVFreezeGrabWindow(self.hCam2, False) # 恢复将图像传输到右窗口self.ResultLabel.setText("图像采集继续!")else:self.btnStopGrab.setText('继续采集')MVFreezeGrabWindow(self.hCam, True) # 暂停将图像传输到左窗口MVFreezeGrabWindow(self.hCam2, True) # 暂停将图像传输到右窗口self.ResultLabel.setText("图像采集暂停!")# 保存图片执行本函数,在非触发模式时,只有采集暂停是才可以保存def saveImage(self):idn = MVGetSampleGrab(self.hCam, self.himage)print("01")fname = QFileDialog.getSaveFileName(self, '打开文件', './Images' + str(idn.idn) + '.bmp', ("Images (*.bmp *.jpg *.tif *.raw)"))print("02")filename = os.path.basename(fname[0]) # 获取到需要存储的文件名pathname = os.path.join(os.getcwd(), filename) # 获取带有文件名的文件路径newfile = '\\'.join(fname[0].split('/')[:-1]) # 需要存储到的新文件夹print("03")MVImageSave(self.himage, filename.encode('utf-8')) # 将图片保存下来print("04")if (newfile != os.getcwd()): # 将图片移动到指定文件夹下try:shutil.move(pathname, newfile)except:os.unlink(os.path.join(newfile, filename))shutil.move(pathname, newfile)image = QImage(newfile + '\\' + filename)self.label.setPixmap(QPixmap.fromImage(image)) # 加载图片mode = MVGetTriggerMode(self.hCam) # 获取当前相机采集模式#保存左图像# idn = MVGetSampleGrab(self.hCam, self.himage)# fname = QFileDialog.getSaveFileName(# self, '打开文件', './Images' + str(idn.idn) + '.bmp', ("Images (*.bmp *.jpg *.tif *.raw)"))# filename = os.path.basename(fname[0]) # 获取到需要存储的文件名# pathname = os.path.join(os.getcwd(), filename) # 获取带有文件名的文件路径# newfile = '\\'.join(fname[0].split('/')[:-1]) # 需要存储到的新文件夹# MVImageSave(self.himage, filename.encode('utf-8')) # 将图片保存下来# if (newfile != os.getcwd()): # 将图片移动到指定文件夹下# try:# shutil.move(pathname, newfile)# except:# os.unlink(os.path.join(newfile, filename))# shutil.move(pathname, newfile)# image = QImage(newfile + '\\' + filename)# self.LLabel.setPixmap(QPixmap.fromImage(image)) # 加载图片#保存右图像# idn = MVGetSampleGrab(self.hCam2, self.himage2)# fname = QFileDialog.getSaveFileName(# self, '打开文件', './Images' + str(idn.idn) + '.bmp', ("Images (*.bmp *.jpg *.tif *.raw)"))# filename = os.path.basename(fname[0]) # 获取到需要存储的文件名# pathname = os.path.join(os.getcwd(), filename) # 获取带有文件名的文件路径# newfile = '\\'.join(fname[0].split('/')[:-1]) # 需要存储到的新文件夹# MVImageSave(self.himage2, filename.encode('utf-8')) # 将图片保存下来# if (newfile != os.getcwd()): # 将图片移动到指定文件夹下# try:# shutil.move(pathname, newfile)# except:# os.unlink(os.path.join(newfile, filename))# shutil.move(pathname, newfile)# image2 = QImage(newfile + '\\' + filename)# self.RLabel.setPixmap(QPixmap.fromImage(image2)) # 加载图片self.ResultLabel.setText("图像保存正常!")# 点击关闭相机按钮,开始关闭相机def closeCam(self):result = MVCloseCam(self.hCam)# 关闭左相机result2 = MVCloseCam(self.hCam2)# 关闭右相机if (result.status != MVSTATUS_CODES.MVST_SUCCESS):msgBox = QMessageBox(QMessageBox.Warning, '提示', result.status)msgBox.exec()if (result2.status != MVSTATUS_CODES.MVST_SUCCESS):msgBox = QMessageBox(QMessageBox.Warning, '提示', result.status)msgBox.exec()self.ResultLabel.setText("相机关闭成功!")
import imgimport sys
if __name__ == '__main__':app = QApplication(sys.argv)window = Ui_Form_Image()# 显示window.show()sys.exit(app.exec_())
5 最后
这篇关于毕业设计 双目立体视觉图像匹配与测距的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!