diff --git a/output/detection_20250113_112407_136399.jpg b/output/detection_20250113_112407_136399.jpg new file mode 100644 index 0000000..4cb6ae2 Binary files /dev/null and b/output/detection_20250113_112407_136399.jpg differ diff --git a/src/__pycache__/api_server.cpython-39.pyc b/src/__pycache__/api_server.cpython-39.pyc new file mode 100644 index 0000000..04898e4 Binary files /dev/null and b/src/__pycache__/api_server.cpython-39.pyc differ diff --git a/src/__pycache__/camera_handler.cpython-39.pyc b/src/__pycache__/camera_handler.cpython-39.pyc new file mode 100644 index 0000000..7b9355e Binary files /dev/null and b/src/__pycache__/camera_handler.cpython-39.pyc differ diff --git a/src/__pycache__/person_detector.cpython-39.pyc b/src/__pycache__/person_detector.cpython-39.pyc index 51c8340..badbfe8 100644 Binary files a/src/__pycache__/person_detector.cpython-39.pyc and b/src/__pycache__/person_detector.cpython-39.pyc differ diff --git a/src/person_detector.py b/src/person_detector.py index 8987617..b5f73fb 100644 --- a/src/person_detector.py +++ b/src/person_detector.py @@ -1,6 +1,6 @@ from ultralytics import YOLO import numpy as np -from ..utils.utils import VisualizationUtils +from utils.utils import VisualizationUtils class PersonDetector: def __init__(self, model_path, conf_threshold=0.5): diff --git a/test.py b/test.py new file mode 100644 index 0000000..64bd988 --- /dev/null +++ b/test.py @@ -0,0 +1,6 @@ +import asyncio +from tests.run_tests import run_all_tests + + +if __name__ == "__main__": + asyncio.run(run_all_tests()) \ No newline at end of file diff --git a/tests/__pycache__/run_tests.cpython-39.pyc b/tests/__pycache__/run_tests.cpython-39.pyc new file mode 100644 index 0000000..a589eb8 Binary files /dev/null and b/tests/__pycache__/run_tests.cpython-39.pyc differ diff --git a/tests/__pycache__/test_api.cpython-39.pyc b/tests/__pycache__/test_api.cpython-39.pyc new file mode 100644 index 0000000..c8ae875 Binary files /dev/null and b/tests/__pycache__/test_api.cpython-39.pyc differ diff --git a/tests/__pycache__/test_camera.cpython-39.pyc b/tests/__pycache__/test_camera.cpython-39.pyc new file mode 100644 index 0000000..fd0b661 Binary files /dev/null and b/tests/__pycache__/test_camera.cpython-39.pyc differ diff --git a/tests/__pycache__/test_distance_estimator.cpython-39.pyc b/tests/__pycache__/test_distance_estimator.cpython-39.pyc new file mode 100644 index 0000000..241cdeb Binary files /dev/null and b/tests/__pycache__/test_distance_estimator.cpython-39.pyc differ diff --git a/tests/__pycache__/test_person_detector.cpython-39.pyc b/tests/__pycache__/test_person_detector.cpython-39.pyc new file mode 100644 index 0000000..aed3acc Binary files /dev/null and b/tests/__pycache__/test_person_detector.cpython-39.pyc differ diff --git a/tests/run_tests.py b/tests/run_tests.py new file mode 100644 index 0000000..4e71850 --- /dev/null +++ b/tests/run_tests.py @@ -0,0 +1,24 @@ +import asyncio +from .test_camera import test_rtsp_camera +from .test_person_detector import test_person_detector +from .test_distance_estimator import test_distance_estimator +from .test_api import test_distance_api + +async def run_all_tests(): + print("开始运行所有测试...") + # print("\n1. 测试摄像头模块") + # test_rtsp_camera() + + print("\n2. 测试人物检测模块") + test_person_detector() + + print("\n3. 测试距离估算模块") + test_distance_estimator() + + # print("\n4. 测试API模块") + # await test_distance_api() + + print("\n所有测试完成!") + +if __name__ == "__main__": + asyncio.run(run_all_tests()) \ No newline at end of file diff --git a/tests/test_api.py b/tests/test_api.py new file mode 100644 index 0000000..2ce3a88 --- /dev/null +++ b/tests/test_api.py @@ -0,0 +1,40 @@ +import asyncio +import numpy as np +from src.api_server import DistanceAPI, Distance +from src.camera_handler import RTSPCamera +from src.person_detector import PersonDetector +from src.distance_estimator import DistanceEstimator + +async def test_distance_api(): + # 初始化所有组件 + camera = RTSPCamera(0) # 使用本地摄像头测试 + detector = PersonDetector("yolov8n.pt") + estimator = DistanceEstimator( + focal_length=35, + sensor_height=24, + avg_person_height=1700 + ) + + # 初始化API + api = DistanceAPI(camera, detector, estimator) + + print("测试API...") + camera.start() + await asyncio.sleep(2) # 等待摄像头初始化 + + try: + distances = await api.get_distances() + assert isinstance(distances, list), "返回结果应该是列表" + for distance in distances: + assert isinstance(distance, Distance), "返回结果应该是Distance对象" + assert distance.distance_mm > 0, "距离应该大于0" + assert 0 <= distance.confidence <= 1, "置信度应该在0-1之间" + + print(f"检测到 {len(distances)} 个人物的距离") + for i, d in enumerate(distances): + print(f"人物 {i+1}: 距离 = {d.distance_mm:.2f}mm, 置信度 = {d.confidence:.2f}") + + finally: + camera.stop() + + print("API测试完成!") \ No newline at end of file diff --git a/tests/test_camera.py b/tests/test_camera.py new file mode 100644 index 0000000..ac8791d --- /dev/null +++ b/tests/test_camera.py @@ -0,0 +1,22 @@ +import cv2 +import numpy as np +import time +from src.camera_handler import RTSPCamera + +def test_rtsp_camera(): + # 使用本地测试视频或摄像头 + camera = RTSPCamera(0) # 使用本地摄像头进行测试 + + print("测试摄像头启动...") + camera.start() + time.sleep(2) # 等待摄像头初始化 + + print("测试获取帧...") + frame = camera.get_frame() + assert frame is not None, "无法获取视频帧" + assert isinstance(frame, np.ndarray), "帧格式不正确" + assert len(frame.shape) == 3, "帧维度不正确" + + print("测试摄像头停止...") + camera.stop() + print("摄像头测试完成!") \ No newline at end of file diff --git a/tests/test_data/Meeting-2nd-Floor-8-19-2024-13_05_00-GMT-7-8-19-2024-13_35_30-GMT-7_mp4-1803_jpg.rf.3e48dd21b87dfe87dd5c32df99b3c468.jpg b/tests/test_data/test_image.jpg similarity index 100% rename from tests/test_data/Meeting-2nd-Floor-8-19-2024-13_05_00-GMT-7-8-19-2024-13_35_30-GMT-7_mp4-1803_jpg.rf.3e48dd21b87dfe87dd5c32df99b3c468.jpg rename to tests/test_data/test_image.jpg diff --git a/tests/test_distance_estimator.py b/tests/test_distance_estimator.py index e0d91ca..5aa6788 100644 --- a/tests/test_distance_estimator.py +++ b/tests/test_distance_estimator.py @@ -1,54 +1,31 @@ -import pytest import numpy as np -from ..src.distance_estimator import DistanceEstimator +from src.distance_estimator import DistanceEstimator -@pytest.fixture -def estimator(): - return DistanceEstimator( - focal_length=1000, # mm - sensor_height=5.6, # mm - avg_person_height=1700 # mm +def test_distance_estimator(): + # 初始化距离估算器 + focal_length = 35 # mm + sensor_height = 24 # mm + avg_person_height = 1700 # mm + + estimator = DistanceEstimator( + focal_length=focal_length, + sensor_height=sensor_height, + avg_person_height=avg_person_height ) - -def test_distance_estimator_initialization(estimator): - assert estimator.focal_length == 1000 - assert estimator.sensor_height == 5.6 - assert estimator.avg_person_height == 1700 - -def test_distance_estimation(estimator): - # 测试不同像素高度的情况 - test_cases = [ - # (person_height_pixels, frame_height, expected_distance_range) - (400, 720, (2000, 5000)), # 近距离 - (200, 720, (4000, 10000)), # 中等距离 - (100, 720, (8000, 20000)) # 远距离 - ] - for height_px, frame_height, (min_dist, max_dist) in test_cases: - distance = estimator.estimate_distance(height_px, frame_height) - assert min_dist <= distance <= max_dist, \ - f"Distance {distance}mm not in expected range [{min_dist}, {max_dist}]" - -def test_distance_estimation_edge_cases(estimator): - # 测试边界情况 - with pytest.raises(ZeroDivisionError): - estimator.estimate_distance(0, 720) + print("测试距离估算...") - # 测试极小值 - distance = estimator.estimate_distance(1, 720) - assert distance > 0 + # 测试场景1:人物占据画面一半高度 + frame_height = 1080 + person_height_pixels = frame_height / 2 + distance = estimator.estimate_distance(person_height_pixels, frame_height) + print(f"场景1 - 人物占据画面一半高度时的估算距离: {distance:.2f}mm") + assert distance > 0, "距离估算结果应该大于0" - # 测试当人物高度等于图像高度的情况 - distance = estimator.estimate_distance(720, 720) - assert distance > 0 - -def test_distance_estimation_linearity(estimator): - # 测试距离估算的线性关系 - height1, height2 = 200, 100 - frame_height = 720 + # 测试场景2:人物占据画面四分之一高度 + person_height_pixels = frame_height / 4 + distance = estimator.estimate_distance(person_height_pixels, frame_height) + print(f"场景2 - 人物占据画面四分之一高度时的估算距离: {distance:.2f}mm") + assert distance > 0, "距离估算结果应该大于0" - distance1 = estimator.estimate_distance(height1, frame_height) - distance2 = estimator.estimate_distance(height2, frame_height) - - # 当像素高度减半时,距离应该翻倍 - assert abs(distance2 / distance1 - 2.0) < 0.1 \ No newline at end of file + print("距离估算测试完成!") \ No newline at end of file diff --git a/tests/test_person_detector.py b/tests/test_person_detector.py index 0899df5..1bbb89e 100644 --- a/tests/test_person_detector.py +++ b/tests/test_person_detector.py @@ -1,51 +1,25 @@ -import pytest -import numpy as np import cv2 -# import os -# import sys +import numpy as np +from src.person_detector import PersonDetector -from ..src.person_detector import PersonDetector -# from src.person_detector import PersonDetector - -@pytest.fixture -def detector(): - # 使用YOLOv8n模型进行测试 - return PersonDetector("yolov8n.pt", conf_threshold=0.5) - -@pytest.fixture -def sample_image(): - # 创建一个测试用的图像,包含一个人的图像 - img_path = "tests/test_data/person.jpg" # 请准备一张包含人物的测试图片 - return cv2.imread(img_path) - -def test_person_detector_initialization(detector): - assert detector.model is not None - assert detector.conf_threshold == 0.5 - -def test_person_detection(detector, sample_image): - persons = detector.detect(sample_image, True) +def test_person_detector(): + # 初始化检测器 + detector = PersonDetector("yolov8n.pt", conf_threshold=0.5) + + # 读取测试图像 + test_image = cv2.imread("tests/test_data/test_image.jpg") + assert test_image is not None, "无法加载测试图像" + + print("测试人物检测...") + persons, vis_path = detector.detect(test_image, save_visualization=True) # 验证检测结果 - assert isinstance(persons, list) - if len(persons) > 0: - person = persons[0] - assert 'bbox' in person - assert 'confidence' in person - - # 验证边界框格式 - bbox = person['bbox'] - assert len(bbox) == 4 - assert all(isinstance(x, int) for x in bbox) - assert bbox[0] < bbox[2] # x1 < x2 - assert bbox[1] < bbox[3] # y1 < y2 - - # 验证置信度 - print("人物置信度", person['confidence']) - assert 0 <= person['confidence'] <= 1 - -def test_person_detector_empty_image(detector): - # 测试空图像 - empty_image = np.zeros((100, 100, 3), dtype=np.uint8) - persons = detector.detect(empty_image) - assert isinstance(persons, list) - assert len(persons) == 0 \ No newline at end of file + assert isinstance(persons, list), "检测结果应该是列表" + for person in persons: + assert 'bbox' in person, "检测结果缺少bbox" + assert 'confidence' in person, "检测结果缺少confidence" + assert len(person['bbox']) == 4, "bbox格式不正确" + assert 0 <= person['confidence'] <= 1, "confidence值范围不正确" + + print(f"检测到 {len(persons)} 个人物") + print("人物检测测试完成!") \ No newline at end of file