Files
ai-titration/test.py
flt6 8184179a17 alter
Former-commit-id: 0d9b33e7625efe7bee422d1514d8453ff689553d
2025-06-05 22:23:28 +08:00

67 lines
2.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import cv2
import numpy as np
from matplotlib import pyplot as plt
from scipy.signal import find_peaks
cap = cv2.VideoCapture(1) # 使用摄像头0通常更稳定
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) # 降低分辨率提高处理速度
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
# 预先创建图形窗口,避免重复创建
fig, ax = plt.subplots(figsize=(10, 4))
plt.ion()
ax.set_title('Saturation Channel Histogram')
ax.set_xlabel('Saturation Value')
ax.set_ylabel('Pixel Count')
ax.set_xlim(0, 255)
while True:
ret, frame = cap.read()
if not ret:
print("Failed to grab frame")
break
cv2.imshow("Camera Feed", frame)
# 直接提取饱和度通道避免完整HSV转换
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
s = hsv[:, :, 1]
s = s[s > 0] # 只保留非零饱和度值,减少噪声
# 使用更高效的直方图计算
hist = cv2.calcHist([s], [0], None, [256], [0, 256])
hist = hist.flatten() # 转换为一维数组
# 峰值检测 - 找到直方图中的峰值
peaks, properties = find_peaks(hist,
# height=np.max(hist) * 0.1, # 峰值高度至少是最大值的10%
distance=5, # 峰值之间的最小距离
prominence=np.max(hist) * 0.05) # 峰值的突出度
# 清除旧数据并绘制新直方图
ax.clear()
ax.plot(hist, 'b-', linewidth=1)
# 标注峰值
if len(peaks) > 0:
ax.text(0.5, 1.05, f'Found {len(peaks)} peaks')
ax.plot(peaks, hist[peaks], 'ro', markersize=8, label=f'Peaks ({len(peaks)})')
# 在峰值处添加文字标注
for i, peak in enumerate(peaks):
ax.annotate(f'Peak {i+1}\n({peak}, {int(hist[peak])})',
xy=(peak, hist[peak]),
xytext=(peak, hist[peak] + np.max(hist) * 0.1),
ha='center', va='bottom',
bbox=dict(boxstyle='round,pad=0.3', facecolor='yellow', alpha=0.7),
arrowprops=dict(arrowstyle='->', color='red'))
plt.draw()
plt.pause(0.1) # 确保图形更新
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
plt.close('all')