拉流功能测试完毕
This commit is contained in:
parent
7f5e223d8c
commit
6d26b8be82
@ -1,26 +1,31 @@
|
||||
camera:
|
||||
rtsp_url: "rtsp://username:password@ip:port/stream"
|
||||
fps: 30
|
||||
width: 1280
|
||||
height: 720
|
||||
|
||||
model:
|
||||
person_detection:
|
||||
model_name: "yolov8n.pt" # 使用YOLOv8进行人物检测
|
||||
confidence_threshold: 0.5
|
||||
|
||||
distance_estimation:
|
||||
# focal_length: 1000 # 摄像头焦距
|
||||
# sensor_height: 3000 # 摄像头传感器高度(mm)
|
||||
# average_person_height: 1700 # 平均人身高(mm)
|
||||
focal_length_mm : 35 # 焦距(mm)
|
||||
sensor_width_mm : 23.6 # 传感器宽度(mm)
|
||||
sensor_height_mm : 15.6 # 传感器高度(mm)
|
||||
image_width_pixels : 640 # 图像宽度(像素)
|
||||
image_height_pixels : 640 # 图像高度(像素)
|
||||
camera_height_mm: 1700 # 摄像头安装高度(mm)
|
||||
camera_tilt_angle: 15 # 摄像头俯仰角(度)
|
||||
|
||||
api:
|
||||
# 服务器配置
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
port: 8000
|
||||
port: 5000
|
||||
debug: false
|
||||
|
||||
# 相机配置
|
||||
camera:
|
||||
rtsp_url: "rtsp://10.0.0.17:8554/camera_test/2"
|
||||
fps: 30
|
||||
|
||||
# 检测器配置
|
||||
detector:
|
||||
model_path: "yolov8n.pt"
|
||||
conf_threshold: 0.5
|
||||
|
||||
# 距离估计器配置
|
||||
estimator:
|
||||
focal_length_mm: 35
|
||||
sensor_width_mm: 23.5
|
||||
sensor_height_mm: 15.6
|
||||
image_width_pixels: 1920
|
||||
image_height_pixels: 1080
|
||||
camera_height_mm: 1700
|
||||
camera_tilt_angle: 15
|
||||
|
||||
# 输出配置
|
||||
output:
|
||||
save_detections: true
|
||||
output_dir: "output"
|
||||
visualization: true
|
||||
19
logs/app_20250114_165540.log
Normal file
19
logs/app_20250114_165540.log
Normal file
@ -0,0 +1,19 @@
|
||||
2025-01-14 16:55:40,070 - __main__ - INFO - 启动服务...
|
||||
2025-01-14 16:55:40,073 - __main__ - INFO - 配置加载成功
|
||||
2025-01-14 16:55:40,073 - __main__ - INFO - 正在初始化相机...
|
||||
2025-01-14 16:55:40,073 - __main__ - INFO - 正在初始化人物检测器...
|
||||
2025-01-14 16:55:40,117 - __main__ - INFO - 正在初始化距离估计器...
|
||||
2025-01-14 16:55:50,180 - __main__ - INFO - 服务启动在 http://0.0.0.0:5000
|
||||
2025-01-14 16:55:50,188 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://10.0.0.202:5000
|
||||
2025-01-14 16:55:50,188 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-01-14 16:56:05,409 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:56:05] "[35m[1mGET /camera/frame HTTP/1.1[0m" 500 -
|
||||
2025-01-14 16:56:15,458 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:56:15] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 16:56:55,298 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:56:55] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 16:56:59,786 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:56:59] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 16:57:20,843 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:57:20] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 16:57:32,595 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:57:32] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 16:57:34,837 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:57:34] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 16:58:06,508 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:58:06] "GET /health HTTP/1.1" 200 -
|
||||
19
logs/app_20250114_165842.log
Normal file
19
logs/app_20250114_165842.log
Normal file
@ -0,0 +1,19 @@
|
||||
2025-01-14 16:58:42,373 - __main__ - INFO - 启动服务...
|
||||
2025-01-14 16:58:42,375 - __main__ - INFO - 配置加载成功
|
||||
2025-01-14 16:58:42,375 - __main__ - INFO - 正在初始化相机...
|
||||
2025-01-14 16:58:42,375 - __main__ - INFO - 正在初始化人物检测器...
|
||||
2025-01-14 16:58:42,419 - __main__ - INFO - 正在初始化距离估计器...
|
||||
2025-01-14 16:58:52,476 - __main__ - INFO - 服务启动在 http://0.0.0.0:5000
|
||||
2025-01-14 16:58:52,480 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://10.0.0.202:5000
|
||||
2025-01-14 16:58:52,480 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-01-14 16:59:00,367 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:59:00] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 16:59:02,726 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:59:02] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 16:59:29,231 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:59:29] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 16:59:30,247 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:59:30] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 16:59:32,079 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 16:59:32] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:00:16,520 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:00:16] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:00:19,144 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:00:19] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:00:37,169 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:00:37] "GET /health HTTP/1.1" 200 -
|
||||
18
logs/app_20250114_170133.log
Normal file
18
logs/app_20250114_170133.log
Normal file
@ -0,0 +1,18 @@
|
||||
2025-01-14 17:01:33,247 - __main__ - INFO - 启动服务...
|
||||
2025-01-14 17:01:33,250 - __main__ - INFO - 配置加载成功
|
||||
2025-01-14 17:01:33,250 - __main__ - INFO - 正在初始化相机...
|
||||
2025-01-14 17:01:33,250 - __main__ - INFO - 正在初始化人物检测器...
|
||||
2025-01-14 17:01:33,294 - __main__ - INFO - 正在初始化距离估计器...
|
||||
2025-01-14 17:01:43,346 - __main__ - INFO - 服务启动在 http://0.0.0.0:5000
|
||||
2025-01-14 17:01:43,354 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://10.0.0.202:5000
|
||||
2025-01-14 17:01:43,354 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-01-14 17:01:51,262 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:01:51] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:02:09,413 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:02:09] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:02:19,605 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:02:19] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:02:21,029 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:02:21] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:02:49,669 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:02:49] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:03:12,519 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:03:12] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:03:13,886 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:03:13] "GET /health HTTP/1.1" 200 -
|
||||
13
logs/app_20250114_170445.log
Normal file
13
logs/app_20250114_170445.log
Normal file
@ -0,0 +1,13 @@
|
||||
2025-01-14 17:04:45,083 - __main__ - INFO - 启动服务...
|
||||
2025-01-14 17:04:45,086 - __main__ - INFO - 配置加载成功
|
||||
2025-01-14 17:04:45,086 - __main__ - INFO - 正在初始化相机...
|
||||
2025-01-14 17:04:45,086 - __main__ - INFO - 正在初始化人物检测器...
|
||||
2025-01-14 17:04:45,130 - __main__ - INFO - 正在初始化距离估计器...
|
||||
2025-01-14 17:04:55,193 - __main__ - INFO - 服务启动在 http://0.0.0.0:5000
|
||||
2025-01-14 17:04:55,201 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://10.0.0.202:5000
|
||||
2025-01-14 17:04:55,201 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-01-14 17:05:49,979 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:05:49] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:07:19,390 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:07:19] "GET /health HTTP/1.1" 200 -
|
||||
12
logs/app_20250114_171631.log
Normal file
12
logs/app_20250114_171631.log
Normal file
@ -0,0 +1,12 @@
|
||||
2025-01-14 17:16:31,184 - __main__ - INFO - 启动服务...
|
||||
2025-01-14 17:16:31,187 - __main__ - INFO - 配置加载成功
|
||||
2025-01-14 17:16:31,187 - __main__ - INFO - 正在初始化相机...
|
||||
2025-01-14 17:16:31,187 - __main__ - INFO - 正在初始化人物检测器...
|
||||
2025-01-14 17:16:31,231 - __main__ - INFO - 正在初始化距离估计器...
|
||||
2025-01-14 17:16:31,279 - __main__ - INFO - 服务启动在 http://0.0.0.0:5000
|
||||
2025-01-14 17:16:31,283 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://10.0.0.202:5000
|
||||
2025-01-14 17:16:31,284 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-01-14 17:16:51,802 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:16:51] "GET /health HTTP/1.1" 200 -
|
||||
14
logs/app_20250114_171846.log
Normal file
14
logs/app_20250114_171846.log
Normal file
@ -0,0 +1,14 @@
|
||||
2025-01-14 17:18:46,293 - __main__ - INFO - 启动服务...
|
||||
2025-01-14 17:18:46,296 - __main__ - INFO - 配置加载成功
|
||||
2025-01-14 17:18:46,296 - __main__ - INFO - 正在初始化相机...
|
||||
2025-01-14 17:18:46,296 - __main__ - INFO - 正在初始化人物检测器...
|
||||
2025-01-14 17:18:46,340 - __main__ - INFO - 正在初始化距离估计器...
|
||||
2025-01-14 17:18:56,397 - __main__ - INFO - 服务启动在 http://0.0.0.0:5000
|
||||
2025-01-14 17:18:56,402 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://10.0.0.202:5000
|
||||
2025-01-14 17:18:56,402 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-01-14 17:19:12,783 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:19:12] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:19:14,894 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:19:14] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:21:45,779 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:21:45] "GET /health HTTP/1.1" 200 -
|
||||
18
logs/app_20250114_172426.log
Normal file
18
logs/app_20250114_172426.log
Normal file
@ -0,0 +1,18 @@
|
||||
2025-01-14 17:24:26,534 - __main__ - INFO - 启动服务...
|
||||
2025-01-14 17:24:26,537 - __main__ - INFO - 配置加载成功
|
||||
2025-01-14 17:24:26,537 - __main__ - INFO - 正在初始化相机...
|
||||
2025-01-14 17:24:26,537 - __main__ - INFO - 正在初始化人物检测器...
|
||||
2025-01-14 17:24:26,581 - __main__ - INFO - 正在初始化距离估计器...
|
||||
2025-01-14 17:24:36,639 - __main__ - INFO - 服务启动在 http://0.0.0.0:5000
|
||||
2025-01-14 17:24:36,647 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://10.0.0.202:5000
|
||||
2025-01-14 17:24:36,647 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-01-14 17:25:25,900 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:25:25] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:25:54,229 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:25:54] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:25:59,198 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:25:59] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:26:01,141 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:26:01] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:26:09,452 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:26:09] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:26:24,462 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:26:24] "GET /health HTTP/1.1" 200 -
|
||||
2025-01-14 17:26:30,262 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:26:30] "GET /health HTTP/1.1" 200 -
|
||||
31
logs/app_20250114_173524.log
Normal file
31
logs/app_20250114_173524.log
Normal file
@ -0,0 +1,31 @@
|
||||
2025-01-14 17:35:24,654 - __main__ - INFO - 启动服务...
|
||||
2025-01-14 17:35:24,657 - __main__ - INFO - 配置加载成功
|
||||
2025-01-14 17:35:24,657 - __main__ - INFO - 正在初始化相机...
|
||||
2025-01-14 17:35:24,657 - __main__ - INFO - 正在初始化人物检测器...
|
||||
2025-01-14 17:35:24,701 - __main__ - INFO - 正在初始化距离估计器...
|
||||
2025-01-14 17:35:34,750 - __main__ - INFO - 服务启动在 http://0.0.0.0:5000
|
||||
2025-01-14 17:35:34,754 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://10.0.0.202:5000
|
||||
2025-01-14 17:35:34,754 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-01-14 17:36:31,071 - src.api_server - ERROR - Exception on /health [GET]
|
||||
Traceback (most recent call last):
|
||||
File "/home/admin-root/miniconda3/envs/trt/lib/python3.9/site-packages/flask/app.py", line 1473, in wsgi_app
|
||||
response = self.full_dispatch_request()
|
||||
File "/home/admin-root/miniconda3/envs/trt/lib/python3.9/site-packages/flask/app.py", line 882, in full_dispatch_request
|
||||
rv = self.handle_user_exception(e)
|
||||
File "/home/admin-root/miniconda3/envs/trt/lib/python3.9/site-packages/flask/app.py", line 880, in full_dispatch_request
|
||||
rv = self.dispatch_request()
|
||||
File "/home/admin-root/miniconda3/envs/trt/lib/python3.9/site-packages/flask/app.py", line 865, in dispatch_request
|
||||
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
|
||||
File "/home/admin-root/haotian/东厂_深度估计/src/api_server.py", line 188, in health_check
|
||||
return jsonify(api.check_health())
|
||||
File "/home/admin-root/haotian/东厂_深度估计/src/api_server.py", line 145, in check_health
|
||||
self.save_visualization(self.camera.get_frame())
|
||||
File "/home/admin-root/haotian/东厂_深度估计/src/api_server.py", line 86, in save_visualization
|
||||
cv2.imwrite(output_path, frame)
|
||||
cv2.error: OpenCV(4.10.0) /io/opencv/modules/imgcodecs/src/loadsave.cpp:798: error: (-215:Assertion failed) !_img.empty() in function 'imwrite'
|
||||
|
||||
2025-01-14 17:36:31,072 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:36:31] "[35m[1mGET /health HTTP/1.1[0m" 500 -
|
||||
2025-01-14 17:37:03,547 - werkzeug - INFO - 127.0.0.1 - - [14/Jan/2025 17:37:03] "GET /health HTTP/1.1" 200 -
|
||||
153
main.py
153
main.py
@ -1,60 +1,113 @@
|
||||
import os
|
||||
import sys
|
||||
import yaml
|
||||
import uvicorn
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from src.camera_handler import RTSPCamera
|
||||
from src.person_detector import PersonDetector
|
||||
from src.distance_estimator import DistanceEstimator
|
||||
from src.api_server import DistanceAPI, app
|
||||
from src.api_server import create_app
|
||||
|
||||
def load_config():
|
||||
with open('config/config.yaml', 'r') as f:
|
||||
return yaml.safe_load(f)
|
||||
# 配置日志
|
||||
def setup_logging():
|
||||
"""设置日志配置"""
|
||||
# 创建logs目录
|
||||
if not os.path.exists('logs'):
|
||||
os.makedirs('logs')
|
||||
|
||||
# 设置日志格式
|
||||
log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format=log_format,
|
||||
handlers=[
|
||||
logging.FileHandler(
|
||||
f'logs/app_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log'
|
||||
),
|
||||
logging.StreamHandler(sys.stdout)
|
||||
]
|
||||
)
|
||||
return logging.getLogger(__name__)
|
||||
|
||||
def load_config(config_path='config/config.yaml'):
|
||||
"""加载配置文件"""
|
||||
try:
|
||||
with open(config_path, 'r', encoding='utf-8') as f:
|
||||
return yaml.safe_load(f)
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"无法加载配置文件: {str(e)}")
|
||||
|
||||
def init_camera(config, logger):
|
||||
"""初始化相机"""
|
||||
logger.info("正在初始化相机...")
|
||||
camera_config = config['camera']
|
||||
camera = RTSPCamera(
|
||||
rtsp_url=camera_config['rtsp_url'],
|
||||
fps=camera_config.get('fps', 30)
|
||||
)
|
||||
return camera
|
||||
|
||||
def init_detector(config, logger):
|
||||
"""初始化人物检测器"""
|
||||
logger.info("正在初始化人物检测器...")
|
||||
detector_config = config['detector']
|
||||
detector = PersonDetector(
|
||||
model_path=detector_config['model_path'],
|
||||
conf_threshold=detector_config.get('conf_threshold', 0.5)
|
||||
)
|
||||
return detector
|
||||
|
||||
def init_estimator(config, logger):
|
||||
"""初始化距离估计器"""
|
||||
logger.info("正在初始化距离估计器...")
|
||||
estimator_config = config['estimator']
|
||||
estimator = DistanceEstimator(
|
||||
focal_length_mm=estimator_config['focal_length_mm'],
|
||||
sensor_width_mm=estimator_config['sensor_width_mm'],
|
||||
sensor_height_mm=estimator_config['sensor_height_mm'],
|
||||
image_width_pixels=estimator_config['image_width_pixels'],
|
||||
image_height_pixels=estimator_config['image_height_pixels'],
|
||||
camera_height_mm=estimator_config.get('camera_height_mm', 1700),
|
||||
camera_tilt_angle=estimator_config.get('camera_tilt_angle', 0)
|
||||
)
|
||||
return estimator
|
||||
|
||||
def main():
|
||||
config = load_config()
|
||||
|
||||
# 初始化摄像头
|
||||
camera = RTSPCamera(
|
||||
config['camera']['rtsp_url'],
|
||||
config['camera']['fps']
|
||||
)
|
||||
camera.start()
|
||||
|
||||
# 初始化检测器
|
||||
detector = PersonDetector(
|
||||
config['model']['person_detection']['model_name'],
|
||||
config['model']['person_detection']['confidence_threshold']
|
||||
)
|
||||
|
||||
# 初始化距离估算器
|
||||
'''
|
||||
focal_length_mm : 35 # 焦距(mm)
|
||||
sensor_width_mm : 23.6 # 传感器宽度(mm)
|
||||
sensor_height_mm : 15.6 # 传感器高度(mm)
|
||||
image_width_pixels : 640 # 图像宽度(像素)
|
||||
image_height_pixels : 640 # 图像高度(像素)
|
||||
camera_height_mm: 1700 # 摄像头安装高度(mm)
|
||||
camera_tilt_angle : 15 # 摄像头俯仰角(度)
|
||||
'''
|
||||
estimator = DistanceEstimator(
|
||||
config['model']['distance_estimation']['focal_length_mm'],
|
||||
config['model']['distance_estimation']['sensor_width_mm'],
|
||||
config['model']['distance_estimation']['sensor_height_mm'],
|
||||
config['model']['distance_estimation']['image_width_pixels'],
|
||||
config['model']['distance_estimation']['image_height_pixels'],
|
||||
config['model']['distance_estimation']['camera_height_mm'],
|
||||
config['model']['distance_estimation']['camera_tilt_angle']
|
||||
)
|
||||
|
||||
# 初始化API
|
||||
distance_api = DistanceAPI(camera, detector, estimator)
|
||||
app.distance_api = distance_api
|
||||
|
||||
# 启动API服务器
|
||||
uvicorn.run(
|
||||
app,
|
||||
host=config['api']['host'],
|
||||
port=config['api']['port']
|
||||
)
|
||||
"""主函数"""
|
||||
# 设置日志
|
||||
logger = setup_logging()
|
||||
logger.info("启动服务...")
|
||||
|
||||
try:
|
||||
# 加载配置
|
||||
config = load_config()
|
||||
logger.info("配置加载成功")
|
||||
|
||||
# 初始化组件
|
||||
camera = init_camera(config, logger)
|
||||
detector = init_detector(config, logger)
|
||||
estimator = init_estimator(config, logger)
|
||||
|
||||
# 创建Flask应用
|
||||
app = create_app(camera, detector, estimator)
|
||||
|
||||
# 获取服务配置
|
||||
server_config = config['server']
|
||||
host = server_config.get('host', '0.0.0.0')
|
||||
port = server_config.get('port', 5000)
|
||||
debug = server_config.get('debug', False)
|
||||
|
||||
# 启动服务
|
||||
logger.info(f"服务启动在 http://{host}:{port}")
|
||||
app.run(
|
||||
host=host,
|
||||
port=port,
|
||||
debug=debug
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"服务启动失败: {str(e)}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
BIN
output/detection_20250114_172624_460839.jpg
Normal file
BIN
output/detection_20250114_172624_460839.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
BIN
output/detection_20250114_172630_260122.jpg
Normal file
BIN
output/detection_20250114_172630_260122.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
BIN
output/detection_20250114_173703_545500.jpg
Normal file
BIN
output/detection_20250114_173703_545500.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 72 KiB |
Binary file not shown.
Binary file not shown.
@ -63,9 +63,7 @@ class CameraConfig:
|
||||
class DistanceAPI:
|
||||
def __init__(self, camera, detector, estimator):
|
||||
self.camera = camera
|
||||
self.camera.start()
|
||||
time.sleep(10)
|
||||
print('相机启动')
|
||||
|
||||
|
||||
self.detector = detector
|
||||
self.estimator = estimator
|
||||
@ -81,7 +79,7 @@ class DistanceAPI:
|
||||
"""获取当前时间戳"""
|
||||
return datetime.now().strftime("%Y%m%d_%H%M%S_%f")
|
||||
|
||||
def save_visualization(self, frame, distances):
|
||||
def save_visualization(self, frame, distances=None):
|
||||
"""保存可视化结果"""
|
||||
timestamp = self.get_timestamp()
|
||||
output_path = os.path.join(self.output_dir, f"detection_{timestamp}.jpg")
|
||||
@ -141,7 +139,12 @@ class DistanceAPI:
|
||||
|
||||
def check_health(self) -> Dict:
|
||||
"""检查服务健康状态"""
|
||||
|
||||
# 只要连上后 get_frame()就有帧, 计算突然断开RTSP流, 还是会返回最后一帧的结果.
|
||||
camera_ok = self.camera.get_frame() is not None
|
||||
self.save_visualization(self.camera.get_frame())
|
||||
|
||||
# print(self.camera.get_frame())
|
||||
|
||||
health = HealthCheck(
|
||||
status="healthy" if camera_ok else "degraded",
|
||||
@ -173,6 +176,10 @@ class DistanceAPI:
|
||||
return True
|
||||
except Exception as e:
|
||||
return False
|
||||
def start_camera(self):
|
||||
self.camera.start()
|
||||
time.sleep(10)
|
||||
print('相机启动')
|
||||
|
||||
def create_routes(app: Flask, api: DistanceAPI):
|
||||
@app.route('/health', methods=['GET'])
|
||||
@ -222,6 +229,7 @@ def create_routes(app: Flask, api: DistanceAPI):
|
||||
def create_app(camera, detector, estimator):
|
||||
"""创建Flask应用实例"""
|
||||
api = DistanceAPI(camera, detector, estimator)
|
||||
api.start_camera()
|
||||
create_routes(app, api)
|
||||
return app
|
||||
|
||||
|
||||
@ -16,17 +16,39 @@ class RTSPCamera:
|
||||
self.running = True
|
||||
self._thread = Thread(target=self._update_frame, daemon=True)
|
||||
self._thread.start()
|
||||
|
||||
|
||||
def connect_to_rtsp_stream(self, url):
|
||||
""" 尝试连接到 RTSP 流 """
|
||||
cap = cv2.VideoCapture(url)
|
||||
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'HEVC'))
|
||||
if not cap.isOpened():
|
||||
print(f"Failed to connect to {url}")
|
||||
return None
|
||||
return cap
|
||||
|
||||
def _update_frame(self):
|
||||
cap = cv2.VideoCapture(self.rtsp_url)
|
||||
cap = self.connect_to_rtsp_stream(self.rtsp_url)
|
||||
while self.running:
|
||||
if cap is None:
|
||||
time.sleep(5)
|
||||
cap = cv2.VideoCapture(self.rtsp_url)
|
||||
self.frame = None
|
||||
print("RTSP流断开连接, 重连中")
|
||||
time.sleep(2)
|
||||
cap = self.connect_to_rtsp_stream(self.rtsp_url)
|
||||
else:
|
||||
print("RTSP流连接成功", end='')
|
||||
ret, frame = cap.read()
|
||||
if ret:
|
||||
self.frame = frame
|
||||
else:
|
||||
print("无法读取帧, 尝试重新连接")
|
||||
cap.release()
|
||||
while True:
|
||||
self.frame = None
|
||||
time.sleep(2)
|
||||
cap = self.connect_to_rtsp_stream(self.rtsp_url)
|
||||
if cap is not None:
|
||||
break
|
||||
|
||||
# 若视频流是实时的 cv2捕获的视频帧是当前时刻的帧.
|
||||
time.sleep(1/self.fps)
|
||||
|
||||
|
||||
@ -1,3 +1,15 @@
|
||||
from src.api_server import main
|
||||
|
||||
main()
|
||||
# 测试整个流程
|
||||
main()
|
||||
|
||||
# 健康检查
|
||||
# curl http://localhost:5000/health
|
||||
|
||||
# 获取距离估计
|
||||
# curl "http://localhost:5000/distances?save_visualization=true"
|
||||
|
||||
# 更新相机配置
|
||||
# curl -X POST http://localhost:5000/camera/config \
|
||||
# -H "Content-Type: application/json" \
|
||||
# -d '{"rtsp_url": "rtsp://new_camera_url", "fps": 30}'
|
||||
Loading…
Reference in New Issue
Block a user