python使用yolov5结合pyqt5实时处理摄像头水稻种子图像标记并计数,根据相近的几个计数画出一个框,计算两个框之间的距离并将处理后的图片放在一个专门文件夹、信息汇总成表格,并写出代码
时间: 2024-03-08 20:45:30 浏览: 26
很高兴能为您解答问题!这个问题比较复杂,需要涉及到摄像头、深度学习、GUI界面、文件操作和数据处理等多方面的知识。以下是一个基本的实现思路和代码示例,供您参考:
1. 搭建GUI界面,使用PyQt5实现一个简单的窗口,包含一个显示摄像头画面的控件和一个按钮用于开始处理图像。
```python
import sys
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('Rice Seed Detection')
self.setGeometry(100, 100, 800, 600)
self.label = QLabel(self)
self.label.setGeometry(10, 10, 640, 480)
self.button = QPushButton('Start', self)
self.button.setGeometry(660, 10, 120, 50)
self.button.clicked.connect(self.start_detection)
def start_detection(self):
# TODO: 开始处理图像
pass
```
2. 获取摄像头画面,使用OpenCV读取摄像头画面,并将其显示在GUI界面上。
```python
import cv2
class MainWindow(QMainWindow):
def __init__(self):
# ...
self.cap = cv2.VideoCapture(0)
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_frame)
self.timer.start(50)
def update_frame(self):
ret, frame = self.cap.read()
if ret:
# 将OpenCV格式的图像转换为PyQt5格式的图像
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
h, w, c = frame.shape
qimage = QImage(frame.data, w, h, w * c, QImage.Format_RGB888)
pixmap = QPixmap.fromImage(qimage)
self.label.setPixmap(pixmap)
```
3. 使用YOLOv5进行目标检测,使用YOLOv5模型对摄像头画面中的水稻种子进行目标检测,并将检测结果显示在GUI界面上。
```python
import torch
import numpy as np
from models.experimental import attempt_load
from utils.general import non_max_suppression, scale_coords, xyxy2xywh
class MainWindow(QMainWindow):
def __init__(self):
# ...
self.model = attempt_load('yolov5s.pt', map_location=torch.device('cpu'))
self.model.eval()
self.names = self.model.module.names if hasattr(self.model, 'module') else self.model.names
def start_detection(self):
self.button.setEnabled(False)
while True:
ret, frame = self.cap.read()
if ret:
# 目标检测
img = frame.copy()
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = torch.from_numpy(img.transpose(2, 0, 1)).float() / 255.0
img = img.unsqueeze(0)
pred = self.model(img)[0]
pred = non_max_suppression(pred, conf_thres=0.5, iou_thres=0.5, agnostic=False)
for i, det in enumerate(pred):
if len(det):
det[:, :4] = scale_coords(img.shape[2:], det[:, :4], frame.shape).round()
for *xyxy, conf, cls in reversed(det):
label = f'{self.names[int(cls)]} {conf:.2f}'
plot_one_box(xyxy, frame, label=label, color=colors[int(cls)], line_thickness=3)
# 显示图像
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
h, w, c = frame.shape
qimage = QImage(frame.data, w, h, w * c, QImage.Format_RGB888)
pixmap = QPixmap.fromImage(qimage)
self.label.setPixmap(pixmap)
```
4. 标记并计数水稻种子,对检测到的水稻种子进行标记,并计算种子数量。
```python
def plot_one_box(xyxy, img, color=None, label=None, line_thickness=None):
# 在图像上画一个矩形框
tl = line_thickness or round(0.002 * max(img.shape[0:2])) + 1 # line thickness
color = color or [random.randint(0, 255) for _ in range(3)]
c1, c2 = (int(xyxy[0]), int(xyxy[1])), (int(xyxy[2]), int(xyxy[3]))
cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
if label:
# 在矩形框上显示标签
tf = max(tl - 1, 1) # font thickness
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled
cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
# 计数
seed_count = len(xyxy)
print(f'Seed count: {seed_count}')
```
5. 基于种子数量画框,并计算两个框之间的距离,使用种子数量计算出相邻两个框的位置,并在GUI界面上将其画出。
```python
class MainWindow(QMainWindow):
def __init__(self):
# ...
self.prev_xyxy = None
def plot_boxes(self, xyxy):
# 在图像上画出所有的矩形框
for *xyxy, _, _ in xyxy:
plot_one_box(xyxy, self.frame, line_thickness=2)
# 基于种子数量画出框
seed_count = len(xyxy)
if seed_count > 0:
if self.prev_xyxy is None:
self.prev_xyxy = xyxy
else:
prev_seed_count = len(self.prev_xyxy)
if prev_seed_count > 0:
x1, y1, _, _ = self.prev_xyxy[0]
x2, y2, _, _ = xyxy[0]
x, y = (x1 + x2) // 2, (y1 + y2) // 2
w, h = abs(x2 - x1), abs(y2 - y1)
cv2.rectangle(self.frame, (x - w, y - h), (x + w, y + h), (0, 255, 0), thickness=2)
distance = np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
print(f'Distance: {distance:.2f}')
self.prev_xyxy = xyxy
```
6. 将处理后的图片放在一个专门文件夹,并将信息汇总成表格,使用Python的os和csv模块将处理后的图片保存到一个指定的文件夹中,并将检测结果保存到一个csv文件中。
```python
import os
import csv
class MainWindow(QMainWindow):
def __init__(self):
# ...
self.output_dir = 'output'
if not os.path.exists(self.output_dir):
os.makedirs(self.output_dir)
self.csv_file = open(os.path.join(self.output_dir, 'result.csv'), 'w', newline='')
self.csv_writer = csv.writer(self.csv_file)
self.csv_writer.writerow(['Frame', 'Seed count', 'Distance'])
def start_detection(self):
# ...
frame_count = 0
while True:
# ...
if seed_count > 0:
frame_count += 1
cv2.imwrite(os.path.join(self.output_dir, f'frame{frame_count:04d}.jpg'), self.frame)
self.csv_writer.writerow([f'frame{frame_count:04d}.jpg', seed_count, distance])
self.csv_file.flush()
```
完整代码如下:
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)