1. 完成了对相机和模型调用的封装

This commit is contained in:
KYOSG 2024-02-27 14:32:31 +08:00
parent 454381eb1c
commit 4fa517fa1f
12 changed files with 249 additions and 128 deletions

63
.idea/workspace.xml generated
View File

@ -4,30 +4,19 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="5de6e434-16d8-46ca-a50f-5cce2ce0877f" name="更改" comment="">
<change afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/graduation_design.iml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/profiles_settings.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/saveactions_settings.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/camera/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/camera/image_processing.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/camera/orbbec_camera/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/camera/orbbec_camera/color_viewer.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/camera/utils.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/camera/yolo.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/camera/yolov8n.pt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/distance_measurement/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/distance_measurement/stereo_vision.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/integration_testing/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/integration_testing/integration_tests.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/robot_control/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/robot_control/control.py" afterDir="false" />
<list default="true" id="5de6e434-16d8-46ca-a50f-5cce2ce0877f" name="更改" comment="1. 成功允运行了Yolo的分类模型大体了解了使用方式&#10;2. 成功运行了Gemini2摄像头&#10;3. 成功将摄像头与Yolo模型整合运行">
<change afterPath="$PROJECT_DIR$/img_process/ObjectClassify.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/img_process/orbbec_camera/ColorViewer.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/img_process/test.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/camera/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/img_process/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/camera/image_processing.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/camera/orbbec_camera/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/img_process/orbbec_camera/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/camera/orbbec_camera/color_viewer.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/camera/utils.py" beforeDir="false" afterPath="$PROJECT_DIR$/img_process/orbbec_camera/utils.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/camera/yolo.py" beforeDir="false" afterPath="$PROJECT_DIR$/img_process/yolo.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/camera/yolov8n.pt" beforeDir="false" afterPath="$PROJECT_DIR$/img_process/yolov8n.pt" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -58,6 +47,8 @@
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"Python.ColorViewer.executor": "Run",
"Python.ObjectClassify.executor": "Run",
"Python.color_viewer.executor": "Run",
"Python.image_processing.executor": "Run",
"Python.yolo.executor": "Run",
@ -72,7 +63,7 @@
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable",
"settings.editor.selected.configurable": "preferences.pluginManager",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
@ -85,9 +76,9 @@
<recent name="F:\Projects\PyCharmProjects\graduation_design\integration_testing" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="F:\Projects\PyCharmProjects\graduation_design\camera\orbbec_camera" />
<recent name="F:\Projects\PyCharmProjects\graduation_design\camera" />
<recent name="F:\Projects\PyCharmProjects\graduation_design\lib" />
<recent name="F:\Projects\PyCharmProjects\graduation_design\camera\orbbec_camera" />
<recent name="F:\Projects\PyCharmProjects\graduation_design\camera\orbbec_camera\lib" />
<recent name="F:\Projects\PyCharmProjects\graduation_design\yolo" />
</key>
@ -124,16 +115,32 @@
<workItem from="1708918220728" duration="85000" />
<workItem from="1708918314610" duration="999000" />
<workItem from="1708925007136" duration="10070000" />
<workItem from="1708953749808" duration="5840000" />
<workItem from="1708953749808" duration="6400000" />
<workItem from="1708996202967" duration="9852000" />
</task>
<task id="LOCAL-00001" summary="1. 成功允运行了Yolo的分类模型大体了解了使用方式&#10;2. 成功运行了Gemini2摄像头&#10;3. 成功将摄像头与Yolo模型整合运行">
<option name="closed" value="true" />
<created>1708960272915</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1708960272915</updated>
</task>
<option name="localTasksCounter" value="2" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="1. 成功允运行了Yolo的分类模型大体了解了使用方式&#10;2. 成功运行了Gemini2摄像头&#10;3. 成功将摄像头与Yolo模型整合运行" />
<option name="LAST_COMMIT_MESSAGE" value="1. 成功允运行了Yolo的分类模型大体了解了使用方式&#10;2. 成功运行了Gemini2摄像头&#10;3. 成功将摄像头与Yolo模型整合运行" />
</component>
<component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/graduation_design$yolo.coverage" NAME="yolo 覆盖结果" MODIFIED="1708959490347" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/camera" />
<SUITE FILE_PATH="coverage/graduation_design$yolo.coverage" NAME="yolo 覆盖结果" MODIFIED="1709010274059" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/camera" />
<SUITE FILE_PATH="coverage/graduation_design$ColorViewer.coverage" NAME="ColorViewer 覆盖结果" MODIFIED="1709015445565" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/img_process/orbbec_camera" />
<SUITE FILE_PATH="coverage/graduation_design$image_processing.coverage" NAME="image_processing 覆盖结果" MODIFIED="1708957639566" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/camera" />
<SUITE FILE_PATH="coverage/graduation_design$ObjectClassify.coverage" NAME="ObjectClassify 覆盖结果" MODIFIED="1709015448681" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/img_process" />
<SUITE FILE_PATH="coverage/graduation_design$color_viewer.coverage" NAME="color_viewer 覆盖结果" MODIFIED="1708957257852" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/camera/orbbec_camera" />
</component>
</project>

View File

@ -32,21 +32,7 @@
## 3. 项目文件结构
```
plaintext
robotic_arm_project/
|-- camera/
| |-- __init__.py
| |-- image_processing.py
|-- distance_measurement/
| |-- __init__.py
| |-- stereo_vision.py
|-- arm_control/
| |-- __init__.py
| |-- control.py
|-- integration_testing/
| |-- __init__.py
| |-- integration_tests.py
|-- main.py
```
### ColorViewer
使用多线程控制摄像头的启停,对摄像头的操作进行二次封装,提高了代码的可读性和可维护性。
具体做法为:将摄像头的操作封装成一个类,然后在主函数中创建一个线程,将摄像头的数据流开在这个线程中。通过标识符控制流的启停和线程的开关。

View File

@ -1,4 +0,0 @@
from yolo import process_img
if __name__ == '__main__':
process_img()

View File

@ -1,77 +0,0 @@
# 导入所需模块
from pyorbbecsdk import Pipeline, FrameSet
from pyorbbecsdk import Config
from pyorbbecsdk import OBSensorType, OBFormat
from pyorbbecsdk import OBError
from pyorbbecsdk import VideoStreamProfile
import cv2
from camera.utils import frame_to_bgr_image
# ESC键的键值
ESC_KEY = 27
def main():
# 创建配置对象
config = Config()
# 创建Pipeline对象
pipeline = Pipeline()
try:
# 获取颜色传感器的流配置列表
profile_list = pipeline.get_stream_profile_list(OBSensorType.COLOR_SENSOR)
try:
# 尝试获取指定分辨率、格式和帧率的颜色配置
color_profile: VideoStreamProfile = profile_list.get_video_stream_profile(640, 0, OBFormat.RGB, 30)
except OBError as e:
# 如果出错,打印错误信息并使用默认的颜色配置
print(e)
color_profile = profile_list.get_default_video_stream_profile()
# 启用颜色流
config.enable_stream(color_profile)
except Exception as e:
# 如果出现异常,打印错误信息并返回
print(e)
return
# 启动Pipeline
pipeline.start(config)
while True:
try:
# 等待获取帧集最多等待100毫秒
frames: FrameSet = pipeline.wait_for_frames(100)
if frames is None:
continue
# 获取颜色帧
color_frame = frames.get_color_frame()
if color_frame is None:
continue
# 将帧转换为BGR格式的图像
color_image = frame_to_bgr_image(color_frame)
if color_image is None:
print("failed to convert frame to image")
continue
# 在窗口中显示颜色图像
cv2.imshow("Color Viewer", color_image)
# 等待用户按键每次等待1毫秒
key = cv2.waitKey(1)
# 如果用户按下 'q' 键或 ESC 键,则退出循环
if key == ord('q') or key == ESC_KEY:
break
except KeyboardInterrupt:
# 如果捕获到键盘中断信号,则退出循环
break
# 停止Pipeline
pipeline.stop()
if __name__ == "__main__":
# 当脚本作为主程序运行时调用main函数
main()

View File

@ -0,0 +1,39 @@
from ultralytics import YOLO
import cv2
from orbbec_camera.ColorViewer import ColorViewer
class ObjectClassify:
def __init__(self):
self.model = YOLO('yolov8n.pt')
def image_classify(self, path=None):
res = self.model(path)
predicted_img = res[0].plot()
cv2.imshow("分类结果", predicted_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
def video_classify(self):
cw = ColorViewer()
frame = cw.get_current_frame()
self.model(source=frame, show=True)
if __name__ == '__main__':
oc = ObjectClassify()
# 实例化相机操作类
cw = ColorViewer()
# 启动相机
cw.start()
# 处理循环
while True:
frame = cw.get_current_frame()
if frame is not None:
oc.model.predict(source=frame, show=True)
key = cv2.waitKey(1)
if key == ord('q'):
cw.stop()
break

View File

@ -0,0 +1,66 @@
import threading
from pyorbbecsdk import Pipeline, FrameSet
from pyorbbecsdk import Config
from pyorbbecsdk import OBSensorType, OBFormat
import cv2
from .utils import frame_to_bgr_image
# 这个类用于初始化摄像头并调用颜色传感器获取图像
class ColorViewer:
def __init__(self):
try:
self.pipeline = Pipeline() # 创建Pipeline对象用于管理数据流
self.config = Config() # 创建配置对象
self.color_frame = None # 前颜色帧
self.active = False # 控制捕获循环的标志
self.thread = None # 线程对象,用于并行执行捕获循环
self.ESC_KEY = 27 # ESC键的ASCII码用于退出循环
self.profile_list = None # 颜色传感器的流配置列表
self.color_profile = None # 颜色传感器的流配置
self.width = 1920 # 图像宽度
self.fps = 30 # 帧率
except Exception as e:
print('初始化失败:', e)
return
# 开始捕获颜色流
def start(self):
if not self.active:
self.active = True
# 传感器选择颜色传感器
self.profile_list = self.pipeline.get_stream_profile_list(OBSensorType.COLOR_SENSOR)
self.color_profile = self.profile_list.get_video_stream_profile(self.width, 0, OBFormat.RGB, self.fps)
self.config.enable_stream(self.color_profile) # 启用配置
# 创建并启动线程目标函数是_capture_loop
self.thread = threading.Thread(target=self._capture_loop)
self.thread.start()
# 停止捕获
def stop(self):
self.active = False
if self.thread is not None:
self.thread.join() # 等待线程结束
# 捕获循环
def _capture_loop(self):
try:
self.pipeline.start(self.config)
while self.active:
try:
# 等待新帧超时时间为100ms
frames: FrameSet = self.pipeline.wait_for_frames(100)
if frames is None:
continue
# 获取颜色帧并转换为RGB格式
self.color_frame = frame_to_bgr_image(frames.get_color_frame())
except Exception as e:
print('创建流失败{}', e)
continue
finally:
self.pipeline.stop() # 确保最终停止数据流
# 获取当前帧
def get_current_frame(self):
# 返回当前颜色的RGB格式帧
return self.color_frame

105
img_process/test.py Normal file
View File

@ -0,0 +1,105 @@
# 用于测试的临时文件
import cv2
from ultralytics import YOLO
from pyorbbecsdk import Pipeline, FrameSet
from pyorbbecsdk import Config
from pyorbbecsdk import OBSensorType, OBFormat
from pyorbbecsdk import OBError
from pyorbbecsdk import VideoStreamProfile
from img_process.orbbec_camera.utils import frame_to_bgr_image
def load_model():
# 载入 YOLOv8 模型
model = YOLO('yolov8n.pt')
return model
# 参数说明
# --img: 输入图片的路径
# --is_save_video: 是否保存识别后的视频
def process_img(img=None):
# 暂时性配置
video_path = "output_video.mp4"
# 加载模型
model = load_model()
if img is not None:
# 对图像运行 YOLOv8 推理
results = model(img)
# 在图像上可视化结果
annotated_img = results[0].plot()
# 显示带有标注的图像
cv2.imshow("YOLOv8 推理", annotated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
# 获取本机摄像头内容
cap = cv2.VideoCapture(0)
# 奥比中光摄像头
# ESC键的键值
ESC_KEY = 27
# 创建配置对象
config = Config()
# 创建Pipeline对象
pipeline = Pipeline()
try:
# 获取颜色传感器的流配置列表
profile_list = pipeline.get_stream_profile_list(OBSensorType.COLOR_SENSOR)
try:
# 尝试获取指定分辨率、格式和帧率的颜色配置
color_profile: VideoStreamProfile = profile_list.get_video_stream_profile(700, 0, OBFormat.RGB, 30)
except OBError as e:
# 如果出错,打印错误信息并使用默认的颜色配置
print(e)
color_profile = profile_list.get_default_video_stream_profile()
# 启用颜色流
config.enable_stream(color_profile)
except Exception as e:
# 如果出现异常,打印错误信息并返回
print(e)
return
# 启动Pipeline
pipeline.start(config)
while True:
try:
# 等待获取帧集最多等待100毫秒
frames: FrameSet = pipeline.wait_for_frames(100)
if frames is None:
continue
# 获取颜色帧
color_frame = frames.get_color_frame()
if color_frame is None:
continue
# 将帧转换为BGR格式的图像
color_image = frame_to_bgr_image(color_frame)
model.predict(source=color_image, show=True)
if color_image is None:
print("failed to convert frame to image")
continue
key = cv2.waitKey(1)
if key == ord('q') or key == ESC_KEY:
break
except KeyboardInterrupt:
# 如果捕获到键盘中断信号,则退出循环
break
# 释放视频捕获对象并关闭显示窗口
cap.release()
cv2.destroyAllWindows()
# 停止Pipeline
pipeline.stop()
if __name__ == '__main__':
process_img()

View File

@ -5,8 +5,7 @@ from pyorbbecsdk import Config
from pyorbbecsdk import OBSensorType, OBFormat
from pyorbbecsdk import OBError
from pyorbbecsdk import VideoStreamProfile
import numpy as np
from utils import frame_to_bgr_image
from img_process.orbbec_camera.utils import frame_to_bgr_image
def load_model():