bushu
137
camera/siyi_caiji.py
Normal file
@ -0,0 +1,137 @@
|
||||
import cv2
|
||||
import time
|
||||
import os
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
from skimage.metrics import structural_similarity as ssim
|
||||
import shutil
|
||||
|
||||
# ================== 配置参数 ==================
|
||||
rtsp_url = "rtsp://192.168.144.25:8554/main.264" # RTSP 流地址
|
||||
capture_interval = 1.0 # 每隔多少秒采集一次(单位:秒)
|
||||
SSIM_THRESHOLD = 0.9 # SSIM 相似度阈值,>0.9 认为太像
|
||||
output_dir = os.path.join("userdata", "image") # 图片保存路径
|
||||
|
||||
# 灰色判断参数
|
||||
GRAY_LOWER = 70
|
||||
GRAY_UPPER = 230
|
||||
GRAY_RATIO_THRESHOLD = 0.7
|
||||
|
||||
# 创建输出目录
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
print(f"已创建目录: {output_dir}")
|
||||
|
||||
def is_large_gray(image, gray_lower=GRAY_LOWER, gray_upper=GRAY_UPPER, ratio_thresh=GRAY_RATIO_THRESHOLD):
|
||||
"""
|
||||
判断图片是否大面积为灰色(R/G/B 都在 [gray_lower, gray_upper] 区间)
|
||||
"""
|
||||
img_array = np.array(image)
|
||||
if len(img_array.shape) != 3 or img_array.shape[2] != 3:
|
||||
return True # 非三通道图视为无效/灰色
|
||||
|
||||
h, w, _ = img_array.shape
|
||||
total = h * w
|
||||
|
||||
gray_mask = (
|
||||
(img_array[:, :, 0] >= gray_lower) & (img_array[:, :, 0] <= gray_upper) &
|
||||
(img_array[:, :, 1] >= gray_lower) & (img_array[:, :, 1] <= gray_upper) &
|
||||
(img_array[:, :, 2] >= gray_lower) & (img_array[:, :, 2] <= gray_upper)
|
||||
)
|
||||
gray_pixels = np.sum(gray_mask)
|
||||
gray_ratio = gray_pixels / total
|
||||
|
||||
return gray_ratio > ratio_thresh
|
||||
|
||||
max_retry_seconds = 10 # 最大重试时间为10秒
|
||||
retry_interval_seconds = 1 # 每隔1秒尝试重新连接一次
|
||||
|
||||
last_gray = None # 用于 SSIM 去重
|
||||
|
||||
while True: # 外层循环用于处理重新连接逻辑
|
||||
cap = cv2.VideoCapture(rtsp_url)
|
||||
start_time = time.time() # 记录开始尝试连接的时间
|
||||
|
||||
while not cap.isOpened():
|
||||
if time.time() - start_time >= max_retry_seconds:
|
||||
print(f"已尝试重新连接 {max_retry_seconds} 秒,但仍无法获取视频流。")
|
||||
exit()
|
||||
|
||||
print("无法打开摄像头,正在尝试重新连接...")
|
||||
time.sleep(retry_interval_seconds)
|
||||
cap = cv2.VideoCapture(rtsp_url)
|
||||
|
||||
print("✅ 开始读取视频流...")
|
||||
|
||||
last_capture_time = time.time()
|
||||
frame_count = 0
|
||||
|
||||
try:
|
||||
while True:
|
||||
ret, frame = cap.read()
|
||||
if not ret:
|
||||
print("读取帧失败,可能是流中断或摄像头断开")
|
||||
cap.release()
|
||||
break
|
||||
|
||||
current_time = time.time()
|
||||
if current_time - last_capture_time < capture_interval:
|
||||
continue
|
||||
|
||||
frame_count += 1
|
||||
last_capture_time = current_time
|
||||
|
||||
print(f"处理帧 {frame_count}")
|
||||
|
||||
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
||||
pil_image = Image.fromarray(rgb_frame)
|
||||
|
||||
if is_large_gray(pil_image):
|
||||
print(f"跳过:大面积灰色图像 (frame_{frame_count})")
|
||||
continue
|
||||
|
||||
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
||||
if last_gray is not None:
|
||||
similarity = ssim(gray, last_gray)
|
||||
if similarity > SSIM_THRESHOLD:
|
||||
print(f"跳过:与上一帧太相似 (SSIM={similarity:.3f})")
|
||||
continue
|
||||
|
||||
last_gray = gray.copy()
|
||||
|
||||
timestamp = time.strftime("%Y%m%d_%H%M%S")
|
||||
ms = int((time.time() % 1) * 1000)
|
||||
filename = f"frame_{timestamp}_{ms:03d}.png"
|
||||
filepath = os.path.join(output_dir, filename)
|
||||
|
||||
total, used, free = shutil.disk_usage(output_dir)
|
||||
if free < 1024 * 1024 * 20: # 小于 20MB 就停止
|
||||
print(f"❌ 磁盘空间严重不足(仅剩 {free / (1024**3):.2f} GB),停止运行。")
|
||||
raise SystemExit(1)
|
||||
|
||||
try:
|
||||
pil_image.save(filepath, format='PNG')
|
||||
print(f"已保存: {filepath}")
|
||||
except (OSError, IOError) as e:
|
||||
error_msg = str(e)
|
||||
if "No space left on device" in error_msg or "disk full" in error_msg.lower() or "quota" in error_msg.lower():
|
||||
print(f"磁盘空间不足,无法保存 {filepath}!错误: {e}")
|
||||
print("停止程序以防止无限错误。")
|
||||
raise SystemExit(1)
|
||||
else:
|
||||
print(f"保存失败 {filename}: {e}(非磁盘空间问题,继续运行)")
|
||||
|
||||
cv2.imshow('Camera Stream (Live)', frame)
|
||||
if cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
raise KeyboardInterrupt
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n用户中断")
|
||||
break
|
||||
|
||||
finally:
|
||||
cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
print(f"视频流已关闭,共处理 {frame_count} 帧。")
|
||||
|
||||
print("程序结束")
|
||||
32
camera/siyi_rtsp.py
Normal file
@ -0,0 +1,32 @@
|
||||
import cv2
|
||||
|
||||
def read_rtsp(rtsp_url):
|
||||
# 创建 VideoCapture 对象
|
||||
cap = cv2.VideoCapture(rtsp_url)
|
||||
# 判断是否成功连接到 RTSP 流
|
||||
if not cap.isOpened():
|
||||
print("无法连接到 RTSP 流")
|
||||
return
|
||||
|
||||
try:
|
||||
while True:
|
||||
# 读取一帧
|
||||
ret, frame = cap.read()
|
||||
if not ret:
|
||||
print("无法读取帧")
|
||||
break
|
||||
|
||||
# 显示帧
|
||||
cv2.imshow('frame', frame)
|
||||
|
||||
# 按下 'q' 键退出
|
||||
if cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
finally:
|
||||
# 释放资源
|
||||
cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
if __name__ == '__main__':
|
||||
rtsp_url = "rtsp://192.168.144.25:8554/main.264" # 替换为实际的 RTSP 地址
|
||||
read_rtsp(rtsp_url)
|
||||
BIN
camera/userdata/image/frame_20251016_102204_124.png
Normal file
|
After Width: | Height: | Size: 781 KiB |
BIN
camera/userdata/image/frame_20251016_102205_189.png
Normal file
|
After Width: | Height: | Size: 780 KiB |
BIN
camera/userdata/image/frame_20251016_102207_222.png
Normal file
|
After Width: | Height: | Size: 778 KiB |
BIN
camera/userdata/image/frame_20251016_102208_221.png
Normal file
|
After Width: | Height: | Size: 784 KiB |
BIN
camera/userdata/image/frame_20251016_102210_302.png
Normal file
|
After Width: | Height: | Size: 770 KiB |
BIN
camera/userdata/image/frame_20251016_102211_347.png
Normal file
|
After Width: | Height: | Size: 769 KiB |
BIN
camera/userdata/image/frame_20251016_102212_386.png
Normal file
|
After Width: | Height: | Size: 764 KiB |
BIN
camera/userdata/image/frame_20251016_102243_374.png
Normal file
|
After Width: | Height: | Size: 761 KiB |
BIN
camera/userdata/image/frame_20251016_102331_476.png
Normal file
|
After Width: | Height: | Size: 774 KiB |
BIN
camera/userdata/image/frame_20251016_102332_545.png
Normal file
|
After Width: | Height: | Size: 766 KiB |
BIN
camera/userdata/image/frame_20251016_102333_543.png
Normal file
|
After Width: | Height: | Size: 757 KiB |
BIN
camera/userdata/image/frame_20251016_102334_581.png
Normal file
|
After Width: | Height: | Size: 758 KiB |
BIN
camera/userdata/image/frame_20251016_102335_583.png
Normal file
|
After Width: | Height: | Size: 774 KiB |
BIN
camera/userdata/image/frame_20251016_102336_582.png
Normal file
|
After Width: | Height: | Size: 764 KiB |
BIN
camera/userdata/image/frame_20251016_102337_658.png
Normal file
|
After Width: | Height: | Size: 824 KiB |
BIN
camera/userdata/image/frame_20251016_102338_695.png
Normal file
|
After Width: | Height: | Size: 797 KiB |
BIN
camera/userdata/image/frame_20251016_102339_703.png
Normal file
|
After Width: | Height: | Size: 790 KiB |
BIN
camera/userdata/image/frame_20251016_102340_700.png
Normal file
|
After Width: | Height: | Size: 811 KiB |
BIN
camera/userdata/image/frame_20251016_102341_742.png
Normal file
|
After Width: | Height: | Size: 790 KiB |
BIN
camera/userdata/image/frame_20251016_102342_740.png
Normal file
|
After Width: | Height: | Size: 791 KiB |
BIN
camera/userdata/image/frame_20251016_102343_738.png
Normal file
|
After Width: | Height: | Size: 785 KiB |
BIN
camera/userdata/image/frame_20251016_102344_785.png
Normal file
|
After Width: | Height: | Size: 739 KiB |
BIN
camera/userdata/image/frame_20251016_102345_786.png
Normal file
|
After Width: | Height: | Size: 790 KiB |
BIN
camera/userdata/image/frame_20251016_102346_824.png
Normal file
|
After Width: | Height: | Size: 788 KiB |
BIN
camera/userdata/image/frame_20251016_102347_821.png
Normal file
|
After Width: | Height: | Size: 804 KiB |
BIN
camera/userdata/image/frame_20251016_102348_857.png
Normal file
|
After Width: | Height: | Size: 798 KiB |
BIN
camera/userdata/image/frame_20251016_102349_902.png
Normal file
|
After Width: | Height: | Size: 786 KiB |
BIN
camera/userdata/image/frame_20251016_102351_983.png
Normal file
|
After Width: | Height: | Size: 692 KiB |
BIN
camera/userdata/image/frame_20251016_102353_024.png
Normal file
|
After Width: | Height: | Size: 801 KiB |
BIN
camera/userdata/image/frame_20251016_102354_059.png
Normal file
|
After Width: | Height: | Size: 758 KiB |
BIN
camera/userdata/image/frame_20251016_102355_101.png
Normal file
|
After Width: | Height: | Size: 735 KiB |
BIN
camera/userdata/image/frame_20251016_102356_138.png
Normal file
|
After Width: | Height: | Size: 736 KiB |
BIN
camera/userdata/image/frame_20251016_102357_184.png
Normal file
|
After Width: | Height: | Size: 723 KiB |
BIN
camera/userdata/image/frame_20251016_102358_224.png
Normal file
|
After Width: | Height: | Size: 780 KiB |
BIN
camera/userdata/image/frame_20251016_102359_259.png
Normal file
|
After Width: | Height: | Size: 857 KiB |
BIN
camera/userdata/image/frame_20251016_102400_300.png
Normal file
|
After Width: | Height: | Size: 882 KiB |
BIN
camera/userdata/image/frame_20251016_102401_345.png
Normal file
|
After Width: | Height: | Size: 750 KiB |
BIN
camera/userdata/image/frame_20251016_102402_388.png
Normal file
|
After Width: | Height: | Size: 885 KiB |
BIN
camera/userdata/image/frame_20251016_102403_419.png
Normal file
|
After Width: | Height: | Size: 841 KiB |
BIN
camera/userdata/image/frame_20251016_102404_460.png
Normal file
|
After Width: | Height: | Size: 858 KiB |
BIN
camera/userdata/image/frame_20251016_102405_498.png
Normal file
|
After Width: | Height: | Size: 661 KiB |
BIN
camera/userdata/image/frame_20251016_102406_543.png
Normal file
|
After Width: | Height: | Size: 819 KiB |
BIN
camera/userdata/image/frame_20251016_102407_577.png
Normal file
|
After Width: | Height: | Size: 746 KiB |
BIN
camera/userdata/image/frame_20251016_102408_585.png
Normal file
|
After Width: | Height: | Size: 613 KiB |
BIN
camera/userdata/image/frame_20251016_102409_658.png
Normal file
|
After Width: | Height: | Size: 820 KiB |
BIN
camera/userdata/image/frame_20251016_102410_697.png
Normal file
|
After Width: | Height: | Size: 789 KiB |
BIN
camera/userdata/image/frame_20251016_102411_743.png
Normal file
|
After Width: | Height: | Size: 806 KiB |
BIN
camera/userdata/image/frame_20251016_102412_777.png
Normal file
|
After Width: | Height: | Size: 781 KiB |
BIN
camera/userdata/image/frame_20251016_102413_814.png
Normal file
|
After Width: | Height: | Size: 783 KiB |
BIN
camera/userdata/image/frame_20251016_102414_916.png
Normal file
|
After Width: | Height: | Size: 762 KiB |
BIN
camera/userdata/image/frame_20251016_102445_808.png
Normal file
|
After Width: | Height: | Size: 712 KiB |
BIN
camera/userdata/image/frame_20251016_102518_932.png
Normal file
|
After Width: | Height: | Size: 777 KiB |
BIN
camera/userdata/image/frame_20251016_102520_009.png
Normal file
|
After Width: | Height: | Size: 760 KiB |
BIN
camera/userdata/image/frame_20251016_102521_044.png
Normal file
|
After Width: | Height: | Size: 756 KiB |
BIN
camera/userdata/image/frame_20251016_102522_086.png
Normal file
|
After Width: | Height: | Size: 751 KiB |
BIN
camera/userdata/image/frame_20251016_102523_081.png
Normal file
|
After Width: | Height: | Size: 754 KiB |
BIN
camera/userdata/image/frame_20251016_102524_162.png
Normal file
|
After Width: | Height: | Size: 752 KiB |
BIN
camera/userdata/image/frame_20251016_102525_161.png
Normal file
|
After Width: | Height: | Size: 780 KiB |
BIN
camera/userdata/image/frame_20251016_102526_160.png
Normal file
|
After Width: | Height: | Size: 775 KiB |
BIN
camera/userdata/image/frame_20251016_102527_200.png
Normal file
|
After Width: | Height: | Size: 765 KiB |
BIN
camera/userdata/image/frame_20251016_102528_200.png
Normal file
|
After Width: | Height: | Size: 757 KiB |
BIN
camera/userdata/image/frame_20251016_102529_205.png
Normal file
|
After Width: | Height: | Size: 773 KiB |
BIN
camera/userdata/image/frame_20251016_102530_240.png
Normal file
|
After Width: | Height: | Size: 820 KiB |
BIN
camera/userdata/image/frame_20251016_102531_238.png
Normal file
|
After Width: | Height: | Size: 833 KiB |
BIN
camera/userdata/image/frame_20251016_102532_277.png
Normal file
|
After Width: | Height: | Size: 835 KiB |
BIN
camera/userdata/image/frame_20251016_102533_278.png
Normal file
|
After Width: | Height: | Size: 829 KiB |
BIN
camera/userdata/image/frame_20251016_102535_317.png
Normal file
|
After Width: | Height: | Size: 780 KiB |
BIN
camera/userdata/image/frame_20251016_102536_363.png
Normal file
|
After Width: | Height: | Size: 788 KiB |
BIN
camera/userdata/image/frame_20251016_102537_365.png
Normal file
|
After Width: | Height: | Size: 781 KiB |
BIN
camera/userdata/image/frame_20251016_102538_399.png
Normal file
|
After Width: | Height: | Size: 780 KiB |
BIN
camera/userdata/image/frame_20251016_102714_874.png
Normal file
|
After Width: | Height: | Size: 707 KiB |
BIN
camera/userdata/image/frame_20251016_102726_211.png
Normal file
|
After Width: | Height: | Size: 708 KiB |
BIN
camera/userdata/image/frame_20251016_102727_213.png
Normal file
|
After Width: | Height: | Size: 666 KiB |
BIN
camera/userdata/image/frame_20251016_102728_214.png
Normal file
|
After Width: | Height: | Size: 647 KiB |
BIN
camera/userdata/image/frame_20251016_102731_294.png
Normal file
|
After Width: | Height: | Size: 742 KiB |
BIN
camera/userdata/image/frame_20251016_102732_293.png
Normal file
|
After Width: | Height: | Size: 730 KiB |
BIN
camera/userdata/image/frame_20251016_102733_334.png
Normal file
|
After Width: | Height: | Size: 733 KiB |
BIN
camera/userdata/image/frame_20251016_102734_370.png
Normal file
|
After Width: | Height: | Size: 694 KiB |
BIN
camera/userdata/image/frame_20251016_102735_381.png
Normal file
|
After Width: | Height: | Size: 716 KiB |
BIN
camera/userdata/image/frame_20251016_102736_414.png
Normal file
|
After Width: | Height: | Size: 672 KiB |
BIN
camera/userdata/image/frame_20251016_102737_452.png
Normal file
|
After Width: | Height: | Size: 681 KiB |
BIN
camera/userdata/image/frame_20251016_102739_496.png
Normal file
|
After Width: | Height: | Size: 705 KiB |
BIN
camera/userdata/image/frame_20251016_102740_533.png
Normal file
|
After Width: | Height: | Size: 706 KiB |
BIN
camera/userdata/image/frame_20251016_102741_535.png
Normal file
|
After Width: | Height: | Size: 711 KiB |
BIN
camera/userdata/image/frame_20251016_103115_945.png
Normal file
|
After Width: | Height: | Size: 685 KiB |
BIN
camera/userdata/image/frame_20251016_103119_046.png
Normal file
|
After Width: | Height: | Size: 657 KiB |
BIN
camera/userdata/image/frame_20251016_103121_126.png
Normal file
|
After Width: | Height: | Size: 723 KiB |
BIN
camera/userdata/image/frame_20251016_103135_366.png
Normal file
|
After Width: | Height: | Size: 699 KiB |
BIN
camera/userdata/image/frame_20251016_103137_407.png
Normal file
|
After Width: | Height: | Size: 614 KiB |
BIN
camera/userdata/image/frame_20251016_103138_448.png
Normal file
|
After Width: | Height: | Size: 664 KiB |
BIN
camera/userdata/image/frame_20251016_103139_482.png
Normal file
|
After Width: | Height: | Size: 681 KiB |
BIN
camera/userdata/image/frame_20251016_103140_488.png
Normal file
|
After Width: | Height: | Size: 688 KiB |
BIN
camera/userdata/image/frame_20251016_103141_491.png
Normal file
|
After Width: | Height: | Size: 717 KiB |
BIN
camera/userdata/image/frame_20251016_103142_527.png
Normal file
|
After Width: | Height: | Size: 736 KiB |
BIN
camera/userdata/image/frame_20251016_103143_566.png
Normal file
|
After Width: | Height: | Size: 737 KiB |
BIN
camera/userdata/image/frame_20251016_103144_605.png
Normal file
|
After Width: | Height: | Size: 733 KiB |
BIN
camera/userdata/image/frame_20251016_103145_653.png
Normal file
|
After Width: | Height: | Size: 758 KiB |
BIN
camera/userdata/image/frame_20251016_103146_687.png
Normal file
|
After Width: | Height: | Size: 780 KiB |