#基于yolov3和深度相机的目标检测框架定位系统总结

Gelsey ·
更新时间:2024-09-20
· 634 次阅读

基于pyqt和yolov3搭建界面

1.首先要了解信号与槽是关键
在这里插入图片描述
2,参考网上的pyqt安装。将界面文件转换为.py文件

# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'realsense.ui' # # Created by: PyQt5 UI code generator 5.13.0 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(1315, 895) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.btnopen = QtWidgets.QPushButton(self.centralwidget) self.btnopen.setGeometry(QtCore.QRect(240, 730, 181, 51)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btnopen.sizePolicy().hasHeightForWidth()) self.btnopen.setSizePolicy(sizePolicy) self.btnopen.setStyleSheet("background-color: rgb(0, 170, 255);\n" "font: 18pt \"楷体\";") self.btnopen.setObjectName("btnopen") self.layoutWidget = QtWidgets.QWidget(self.centralwidget) self.layoutWidget.setGeometry(QtCore.QRect(20, 50, 1271, 541)) self.layoutWidget.setObjectName("layoutWidget") self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setObjectName("gridLayout") self.rightlabel = QtWidgets.QLabel(self.layoutWidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.rightlabel.sizePolicy().hasHeightForWidth()) self.rightlabel.setSizePolicy(sizePolicy) font = QtGui.QFont() font.setPointSize(18) font.setBold(True) font.setWeight(75) self.rightlabel.setFont(font) self.rightlabel.setAlignment(QtCore.Qt.AlignCenter) self.rightlabel.setObjectName("rightlabel") self.gridLayout.addWidget(self.rightlabel, 1, 1, 1, 1) self.label2 = QtWidgets.QLabel(self.layoutWidget) font = QtGui.QFont() font.setPointSize(18) font.setBold(True) font.setWeight(75) self.label2.setFont(font) self.label2.setAlignment(QtCore.Qt.AlignCenter) self.label2.setObjectName("label2") self.gridLayout.addWidget(self.label2, 0, 1, 1, 1) self.leftlabel = QtWidgets.QLabel(self.layoutWidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.leftlabel.sizePolicy().hasHeightForWidth()) self.leftlabel.setSizePolicy(sizePolicy) font = QtGui.QFont() font.setPointSize(19) font.setBold(True) font.setWeight(75) self.leftlabel.setFont(font) self.leftlabel.setAlignment(QtCore.Qt.AlignCenter) self.leftlabel.setObjectName("leftlabel") self.gridLayout.addWidget(self.leftlabel, 1, 0, 1, 1) self.label1 = QtWidgets.QLabel(self.layoutWidget) font = QtGui.QFont() font.setPointSize(18) font.setBold(True) font.setWeight(75) self.label1.setFont(font) self.label1.setAlignment(QtCore.Qt.AlignCenter) self.label1.setObjectName("label1") self.gridLayout.addWidget(self.label1, 0, 0, 1, 1) self.textEdit1 = QtWidgets.QTextEdit(self.centralwidget) self.textEdit1.setGeometry(QtCore.QRect(290, 600, 481, 101)) self.textEdit1.setStyleSheet("font: 24pt \"3ds\";") self.textEdit1.setObjectName("textEdit1") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(40, 620, 241, 61)) self.label.setStyleSheet("font: 30pt \"3ds\";") self.label.setObjectName("label") self.btncamera = QtWidgets.QPushButton(self.centralwidget) self.btncamera.setGeometry(QtCore.QRect(10, 730, 201, 51)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btncamera.sizePolicy().hasHeightForWidth()) self.btncamera.setSizePolicy(sizePolicy) self.btncamera.setStyleSheet("background-color: rgb(85, 255, 255);\n" "font: 18pt \"楷体\";") self.btncamera.setObjectName("btncamera") self.label_2 = QtWidgets.QLabel(self.centralwidget) self.label_2.setGeometry(QtCore.QRect(800, 600, 101, 61)) self.label_2.setStyleSheet("font: 30pt \"3ds\";") self.label_2.setObjectName("label_2") self.textEdit2 = QtWidgets.QTextEdit(self.centralwidget) self.textEdit2.setGeometry(QtCore.QRect(890, 600, 231, 101)) self.textEdit2.setStyleSheet("font: 24pt \"3ds\";") self.textEdit2.setObjectName("textEdit2") self.label_3 = QtWidgets.QLabel(self.centralwidget) self.label_3.setGeometry(QtCore.QRect(380, 0, 551, 41)) self.label_3.setStyleSheet("font: 30pt \"3ds\";") self.label_3.setObjectName("label_3") self.splitter = QtWidgets.QSplitter(self.centralwidget) self.splitter.setGeometry(QtCore.QRect(280, 790, 751, 52)) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setObjectName("splitter") self.label_time = QtWidgets.QLabel(self.splitter) self.label_time.setStyleSheet("font: 30pt \"3ds\";\n" "color: rgb(0, 0, 0);") self.label_time.setText("") self.label_time.setObjectName("label_time") self.btnread = QtWidgets.QPushButton(self.centralwidget) self.btnread.setGeometry(QtCore.QRect(450, 730, 171, 51)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btnread.sizePolicy().hasHeightForWidth()) self.btnread.setSizePolicy(sizePolicy) self.btnread.setStyleSheet("background-color: rgb(170, 255, 127);\n" "font: 18pt \"楷体\";") self.btnread.setObjectName("btnread") self.btnvideo = QtWidgets.QPushButton(self.centralwidget) self.btnvideo.setGeometry(QtCore.QRect(650, 730, 251, 51)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btnvideo.sizePolicy().hasHeightForWidth()) self.btnvideo.setSizePolicy(sizePolicy) self.btnvideo.setStyleSheet("background-color: rgb(255, 255, 127);\n" "font: 18pt \"楷体\";") self.btnvideo.setObjectName("btnvideo") self.btndepthvideo = QtWidgets.QPushButton(self.centralwidget) self.btndepthvideo.setGeometry(QtCore.QRect(930, 730, 251, 51)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btndepthvideo.sizePolicy().hasHeightForWidth()) self.btndepthvideo.setSizePolicy(sizePolicy) self.btndepthvideo.setStyleSheet("background-color: rgb(170, 170, 255);\n" "font: 18pt \"楷体\";") self.btndepthvideo.setObjectName("btndepthvideo") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 1315, 23)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) self.btnopen.clicked.connect(MainWindow.btnopen_clicked) self.btnread.clicked.connect(MainWindow.btnread_clicked) self.btncamera.clicked.connect(MainWindow.btncamera_clicked) self.btnvideo.clicked.connect(MainWindow.btnvideo_clicked) self.btndepthvideo.clicked.connect(MainWindow.btndepthvideo_clicked) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.btnopen.setText(_translate("MainWindow", "连接深度相机")) self.rightlabel.setText(_translate("MainWindow", "右相机图像")) self.label2.setText(_translate("MainWindow", "深度图")) self.leftlabel.setText(_translate("MainWindow", "左相机图像")) self.label1.setText(_translate("MainWindow", "原始图")) self.label.setText(_translate("MainWindow", "目标实际坐标")) self.btncamera.setText(_translate("MainWindow", "连接普通相机")) self.label_2.setText(_translate("MainWindow", "深度")) self.label_3.setText(_translate("MainWindow", "目标检测三维空间定位系统V1")) self.btnread.setText(_translate("MainWindow", "单张图片检测")) self.btnvideo.setText(_translate("MainWindow", "离线普通相机视频检测")) self.btndepthvideo.setText(_translate("MainWindow", "离线深度相机视频检测"))

3.基于yolov3的代码我就不贴,主要是基于我们检测目标,要主要返回值

```cpp import os import numpy as np import copy import colorsys from timeit import default_timer as timer from keras import backend as K from keras.models import load_model from keras.layers import Input from PIL import Image, ImageFont, ImageDraw from nets.yolo3 import yolo_body,yolo_eval from utils.utils import letterbox_image class YOLO(object): _defaults = { "model_path": 'model_data/yolo.h5', "anchors_path": 'model_data/yolo_anchors.txt', "classes_path": 'model_data/coco_classes.txt', "score" : 0.5, "iou" : 0.3, "model_image_size" : (416, 416) } @classmethod def get_defaults(cls, n): if n in cls._defaults: return cls._defaults[n] else: return "Unrecognized attribute name '" + n + "'" #---------------------------------------------------# # 初始化yolo #---------------------------------------------------# def __init__(self, **kwargs): self.__dict__.update(self._defaults) self.class_names = self._get_class() self.anchors = self._get_anchors() self.sess = K.get_session() self.boxes, self.scores, self.classes = self.generate() #---------------------------------------------------# # 获得所有的分类 #---------------------------------------------------# def _get_class(self): classes_path = os.path.expanduser(self.classes_path) with open(classes_path) as f: class_names = f.readlines() class_names = [c.strip() for c in class_names] return class_names #---------------------------------------------------# # 获得所有的先验框 #---------------------------------------------------# def _get_anchors(self): anchors_path = os.path.expanduser(self.anchors_path) with open(anchors_path) as f: anchors = f.readline() anchors = [float(x) for x in anchors.split(',')] return np.array(anchors).reshape(-1, 2) #---------------------------------------------------# # 获得所有的分类 #---------------------------------------------------# def generate(self): model_path = os.path.expanduser(self.model_path) assert model_path.endswith('.h5'), 'Keras model or weights must be a .h5 file.' # 计算anchor数量 num_anchors = len(self.anchors) num_classes = len(self.class_names) # 载入模型,如果原来的模型里已经包括了模型结构则直接载入。 # 否则先构建模型再载入 try: self.yolo_model = load_model(model_path, compile=False) except: self.yolo_model = yolo_body(Input(shape=(None,None,3)), num_anchors//3, num_classes) self.yolo_model.load_weights(self.model_path) else: assert self.yolo_model.layers[-1].output_shape[-1] == \ num_anchors/len(self.yolo_model.output) * (num_classes + 5), \ 'Mismatch between model and given anchor and class sizes' print('{} model, anchors, and classes loaded.'.format(model_path)) # 画框设置不同的颜色 hsv_tuples = [(x / len(self.class_names), 1., 1.) for x in range(len(self.class_names))] self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) self.colors = list( map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors)) # 打乱颜色 np.random.seed(10101) np.random.shuffle(self.colors) np.random.seed(None) self.input_image_shape = K.placeholder(shape=(2, )) boxes, scores, classes = yolo_eval(self.yolo_model.output, self.anchors, num_classes, self.input_image_shape, score_threshold=self.score, iou_threshold=self.iou) return boxes, scores, classes #---------------------------------------------------# # 检测图片 #---------------------------------------------------# def detect_image(self, image): start = timer() # 调整图片使其符合输入要求 new_image_size = (self.model_image_size[0],self.model_image_size[1]) boxed_image = letterbox_image(image, new_image_size) image_data = np.array(boxed_image, dtype='float32') image_data /= 255. image_data = np.expand_dims(image_data, 0) # Add batch dimension. # 预测结果 out_boxes, out_scores, out_classes = self.sess.run( [self.boxes, self.scores, self.classes], feed_dict={ self.yolo_model.input: image_data, self.input_image_shape: [image.size[1], image.size[0]], K.learning_phase(): 0 }) print('Found {} boxes for {}'.format(len(out_boxes), 'img')) # 设置字体 font = ImageFont.truetype(font='font/simhei.ttf', size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32')) thickness = (image.size[0] + image.size[1]) // 300 small_pic=[] for i, c in list(enumerate(out_classes)): predicted_class = self.class_names[c] box = out_boxes[i] score = out_scores[i] top, left, bottom, right = box top = top - 5 left = left - 5 bottom = bottom + 5 right = right + 5 top = max(0, np.floor(top + 0.5).astype('int32')) left = max(0, np.floor(left + 0.5).astype('int32')) bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32')) right = min(image.size[0], np.floor(right + 0.5).astype('int32')) # 画框框 label = '{} {:.2f}'.format(predicted_class, score) draw = ImageDraw.Draw(image) label_size = draw.textsize(label, font) label = label.encode('utf-8') print(label) if top - label_size[1] >= 0: text_origin = np.array([left, top - label_size[1]]) else: text_origin = np.array([left, top + 1]) for i in range(thickness): draw.rectangle( [left + i, top + i, right - i, bottom - i], outline=self.colors[c]) draw.rectangle( [tuple(text_origin), tuple(text_origin + label_size)], fill=self.colors[c]) draw.text(text_origin, str(label,'UTF-8'), fill=(0, 0, 0), font=font) del draw fruitx = (left + right) / 2 fruity = (top + bottom) / 2 end = timer() print(end - start) # print(i) return image,fruitx,fruity########这个·是·重点,返回主要数组迭代 def close_session(self): self.sess.close()

4.我这里就只贴深度相机打开的界面,要主要相机内参,其他的文件我就不贴了,应该可以复现

import sys import cv2 from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import QFileDialog, QMainWindow from realsense import Ui_MainWindow import pyrealsense2 as rs import numpy as np from keras.layers import Input from yolo import YOLO from PIL import Image from nets.yolo3 import yolo_body from keras.layers import Input yolo = YOLO() class fruit(QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) self.setWindowTitle('目标检测三维空间定位系统V1') self.setWindowIcon(QIcon('fruit.jpg')) # 设置窗体标题图标 self.Timer = QTimer() # 自定义QTimer self.Timer.start(500) # 每0.5秒运行一次 self.Timer.timeout.connect(self.updateTime) # 连接updateTime # 设置窗口背景图片 # self.setStyleSheet("#MainWindow{border-image:url(fruit.jpg);}") def updateTime(self): self.label_time.setText(QDateTime.currentDateTime().toString('yyyy-MM-dd hh:mm:ss dddd')) # 显示时间的格式 self.label_time.setWordWrap(True) # 让图片自适应label大小 ##打开深度相机 def btnopen_clicked(self): pipeline = rs.pipeline() cfg = rs.config() cfg.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30) cfg.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30) # 设定需要对齐的方式(这里是深度对齐彩色,彩色图不变,深度图变换) profile = pipeline.start(cfg) depth_sensor = profile.get_device().first_depth_sensor() depth_scale = depth_sensor.get_depth_scale() align_to = rs.stream.color # 设定需要对齐的方式(这里是彩色对齐深度,深度图不变,彩色图变换) # align_to = rs.stream.depth alignedFs = rs.align(align_to) # profile = pipeline.start(cfg) try: while True: fs = pipeline.wait_for_frames() self.aligned_frames = alignedFs.process(fs) self.color_frame = self.aligned_frames.get_color_frame() self.depth_frame = self.aligned_frames.get_depth_frame() if not self.depth_frame or not self.color_frame: continue self.color_image = np.asanyarray(self.color_frame.get_data()) print(type(self.color_image)) self.depth_image = np.asanyarray(self.depth_frame.get_data()) self.depth_image = cv2.applyColorMap(cv2.convertScaleAbs(self.depth_image, alpha=0.03), cv2.COLORMAP_JET) self.images = np.hstack((self.color_image, self.depth_image)) # 获取颜色帧内参 color_profile = self.color_frame.get_profile() cvsprofile = rs.video_stream_profile(color_profile) color_intrin = cvsprofile.get_intrinsics() color_intrin_part = [color_intrin.ppx, color_intrin.ppy, color_intrin.fx, color_intrin.fy] # print(color_intrin_part) # 转变成Image self.color_image = Image.fromarray(np.uint8(self.color_image)) # 进行检测 self.color_image1 = np.array(yolo.detect_image(self.color_image)[0]) fruit_x=np.array(yolo.detect_image(self.color_image)[1]) fruit_y = np.array(yolo.detect_image(self.color_image)[2]) # 显示深度 fruit_depth = self.depth_frame.get_distance(int(fruit_x), int(fruit_y)) # 坐标系变换 fruit_x_true=round((fruit_x-color_intrin_part[0])*fruit_depth /color_intrin_part[2],4) fruit_y_true =round((fruit_y - color_intrin_part[1]) * fruit_depth / color_intrin_part[3],4) target=[fruit_x_true,fruit_y_true] # cv2.imshow('window', self.color_image1) height, width, channel = self.color_image1.shape bytesPerline = 3 * width self.left = QImage(self.color_image1.data, width, height, bytesPerline, QImage.Format_RGB888).rgbSwapped() # 将QImage显示出来 self.label.setText("目标实际坐标") self.label2.setText("深度图") self.leftlabel.setPixmap(QPixmap.fromImage(self.left)) self.leftlabel.setScaledContents(True) # 让图片自适应label大小 self.right = QImage(self.depth_image.data, width, height, bytesPerline, QImage.Format_RGB888).rgbSwapped() self.rightlabel.setPixmap(QPixmap.fromImage(self.right)) self.rightlabel.setScaledContents(True) # 让图片自适应label大小 self.textEdit1.setPlainText(str(target)) self.textEdit2.setPlainText(str(round(fruit_depth, 4))) cv2.waitKey(1) finally: pipeline.stop()

5.效果图(这里打码,疫情在家,只能用别人训练的数据模型测试了,回实验室可以训练自己模型测试)
在这里插入图片描述

查看专栏详情 立即解锁全部专栏
作者:zx96xz



系统 相机 定位 框架

需要 登录 后方可回复, 如果你还没有账号请 注册新账号