毕业设计 双目立体视觉图像匹配与测距

2024-01-02 17:20

本文主要是介绍毕业设计 双目立体视觉图像匹配与测距,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 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 最后

这篇关于毕业设计 双目立体视觉图像匹配与测距的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/563142

相关文章

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

计算机视觉工程师所需的基本技能

一、编程技能 熟练掌握编程语言 Python:在计算机视觉领域广泛应用,有丰富的库如 OpenCV、TensorFlow、PyTorch 等,方便进行算法实现和模型开发。 C++:运行效率高,适用于对性能要求严格的计算机视觉应用。 数据结构与算法 掌握常见的数据结构(如数组、链表、栈、队列、树、图等)和算法(如排序、搜索、动态规划等),能够优化代码性能,提高算法效率。 二、数学基础

《计算机视觉工程师养成计划》 ·数字图像处理·数字图像处理特征·概述~

1 定义         从哲学角度看:特征是从事物当中抽象出来用于区别其他类别事物的属性集合,图像特征则是从图像中抽取出来用于区别其他类别图像的属性集合。         从获取方式看:图像特征是通过对图像进行测量或借助算法计算得到的一组表达特性集合的向量。 2 认识         有些特征是视觉直观感受到的自然特征,例如亮度、边缘轮廓、纹理、色彩等。         有些特征需要通

【python计算机视觉编程——7.图像搜索】

python计算机视觉编程——7.图像搜索 7.图像搜索7.1 基于内容的图像检索(CBIR)从文本挖掘中获取灵感——矢量空间模型(BOW表示模型)7.2 视觉单词**思想****特征提取**: 创建词汇7.3 图像索引7.3.1 建立数据库7.3.2 添加图像 7.4 在数据库中搜索图像7.4.1 利用索引获取获选图像7.4.2 用一幅图像进行查询7.4.3 确定对比基准并绘制结果 7.

参会邀请 | 第二届机器视觉、图像处理与影像技术国际会议(MVIPIT 2024)

第二届机器视觉、图像处理与影像技术国际会议(MVIPIT 2024)将于2024年9月13日-15日在中国张家口召开。 MVIPIT 2024聚焦机器视觉、图像处理与影像技术,旨在为专家、学者和研究人员提供一个国际平台,分享研究成果,讨论问题和挑战,探索前沿技术。诚邀高校、科研院所、企业等有关方面的专家学者参加会议。 9月13日(周五):签到日 9月14日(周六):会议日 9月15日(周日

【python计算机视觉编程——8.图像内容分类】

python计算机视觉编程——8.图像内容分类 8.图像内容分类8.1 K邻近分类法(KNN)8.1.1 一个简单的二维示例8.1.2 用稠密SIFT作为图像特征8.1.3 图像分类:手势识别 8.2贝叶斯分类器用PCA降维 8.3 支持向量机8.3.2 再论手势识别 8.4 光学字符识别8.4.2 选取特征8.4.3 多类支持向量机8.4.4 提取单元格并识别字符8.4.5 图像校正

基于stm32的河流检测系统-单片机毕业设计

文章目录 前言资料获取设计介绍功能介绍具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机设计精品

Python计算机视觉编程 第十章

目录 一、OpenCv基础知识 1.读取和写入图像 2.颜色空间 3.显示图像和结果 二、处理视频 1.输入视频 2.将视频读取到NumPy数组中 三、跟踪 1.光流 2.Lucas-Kanade算法 一、OpenCv基础知识 OpenCV 自带读取、写入图像函数以及矩阵操作和数学库。 1.读取和写入图像 import cv2# 读取图像im = c

2025届计算机毕业设计:如何构建Java SpringBoot+Vue个人健康档案管理系统?

✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 | SpringBoot/SSM Python实战项目 | Django 微信小程序/安卓实战项目 大数据实战项目 ⚡⚡文末获取源码 文章目录