Former-commit-id: dc04af028eb2ecbda74eef38f377be0989e21756
This commit is contained in:
2025-06-12 18:50:25 +08:00
parent 6ad826c17f
commit 492b37c912
3 changed files with 71 additions and 26 deletions

51
main.py
View File

@ -10,7 +10,7 @@ from scipy.signal import find_peaks
class MAT:
def __init__(self, videoSourceIndex=0, bounce_time=2, end_bounce_time=5):
def __init__(self, videoSourceIndex=0, bounce_time=2, end_bounce_time=5,k=30):
# 初始化logging
utils.setup_logging()
self.system_logger = utils.get_system_logger()
@ -23,6 +23,7 @@ class MAT:
self.cap = cv2.VideoCapture(videoSourceIndex, cv2.CAP_DSHOW)
self.ch340 = ch340.CH340()
self.total_volume = 0
self.k = k
self.state = State(bounce_time, end_bounce_time)
@ -131,7 +132,7 @@ class MAT:
# === 状态检查逻辑 ===
# middle检查: 进入middle的bounce_time后在最近bounce_time内middle比例<70%返回fast状态
if self.state.should_check_middle_exit(now):
if self.state.should_check_middle_exit(now) and not self.history.last_end:
# 计算最近bounce_time内的middle比例
recent_records = self.history.get_recent_records(self.state.bounce_time, now)
@ -151,26 +152,17 @@ class MAT:
self.history.about_history.append(ratio == 1)
while len(self.history.about_history) > 5:
self.history.about_history.pop(0)
if len(self.history.about_history) == 5:
if len(self.history.about_history) == 5 and self.history.last_end < 2:
rate = sum(self.history.about_history) / len(self.history.about_history)
if rate > 0.8:
self.state.exit_about()
self.control_logger.info(f"about比例{ratio:.2%}<80%退出about检查返回middle模式")
self.end_check()
# print(f"end_history: {self.history.end_history}",peaks)
# if len(self.history.end_history) >= 10:
# colored_ratio=sum(self.history.end_history)/len(self.history.end_history)
# if colored_ratio > 0.7:
# self.endpoint_logger.info(f"colored比例{colored_ratio:.2%}>=70%,确认滴定终点")
# self.endpoint_logger.info(f"最终体积: {self.colored_volume:.2f} ml")
# self.running = False
# self.ch340.stop()
# if self.colored_im is not None:
# cv2.imwrite(f"colored_{datetime.now().strftime('%Y%m%d_%H%M%S')}.jpg", self.colored_im)
# return "colored"
# while len(self.history.end_history) > 10:
# self.history.end_history.pop(0)
ret = self.end_check()
if ret == "colored":
return ret
if not self.history.last_end:
self.history.last_end = max(self.history.last_end,ret)
self.state.about_check = False
@ -182,6 +174,7 @@ class MAT:
def end_check(self,dep=0):
if dep > 5:
# self.endpoint_logger.info(f"colored比例{.2%}>=70%,确认滴定终点")
self.colored_volume = self.total_volume
self.endpoint_logger.info(f"最终体积: {self.colored_volume:.2f} ml")
self.running = False
self.ch340.stop()
@ -201,12 +194,22 @@ class MAT:
distance=10, # 峰值之间的最小距离
prominence=np.max(hist) * 0.01) # 峰值的突出度
if np.any(peaks>130):
if dep == 0:
self.process_left(time.time())
self.history.end_history.append(True)
time.sleep(2)
self.control_logger.info(f"检测到colored状态end_check at {dep}")
self.end_check(dep+1)
bgn = time.time()
while time.time()-bgn < 2:
suc,im = self.cap.read()
if hasattr(self, 'capFile') and self.capFile.isOpened():
self.capFile.write(im)
cv2.putText(im, "ENDCHK", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
cv2.imshow("Frame", im)
return self.end_check(dep+1)
# time.sleep(2)
else:
self.history.end_history.append(False)
return dep
def _display_status(self, im, detection_result, rate, volume):
"""显示状态信息到图像上"""
@ -229,7 +232,7 @@ class MAT:
def predictor(self,im):
hsv = cv2.cvtColor(im,cv2.COLOR_BGR2HSV)
s = hsv[:,:,1]
mask = s>30
mask = s>self.k
cv2.imshow('mask',im*mask[:,:,np.newaxis])
tot = mask.shape[0]*mask.shape[1]
val = np.sum(mask)
@ -237,6 +240,7 @@ class MAT:
if self.history.base is not None:
base = self.history.base
thr = (min(0.05,base*5), min(0.4,base*13), 0.5)
# thr = (base*5, base*13, 0.5)
if rate < thr[0]:
return "transport",rate
elif rate <thr[1]:
@ -370,14 +374,15 @@ if __name__ == "__main__":
mat = MAT(
videoSourceIndex = 1,
bounce_time=4,
end_bounce_time=0.01
end_bounce_time=0.01,
k = 34
)
mat.state.mode = State.Mode.FAST
mat.run(
slow_speed = 0.05,
quick_speed = 0.45,
quick_speed = 0.8,
about_time=3,
# cap_dir=None
)

View File

@ -44,6 +44,7 @@ class History:
self._base_time = base_time
self._base_cnt = 0
self.end_history:list[bool] = []
self.last_end = 0
self.display = display
self.fig: Any = None
self.ax: Any = None

View File

@ -1,4 +1,5 @@
import cv2
import numpy as np
flag = False
vidId = 1
@ -8,11 +9,49 @@ while not flag:
cv2.imshow("image",im)
k = cv2.waitKey(0)
if k & 0xff == ord('q'):
cap.release()
cv2.destroyAllWindows()
# cap.release()
# cv2.destroyAllWindows()
flag=True
else:
vidId+=1
cap.release()
cap.open(vidId, cv2.CAP_DSHOW)
print(f"使用摄像头索引: {vidId}")
print(f"使用摄像头索引: {vidId}")
import ch340
base = 30
pump = ch340.CH340()
while True:
suc,im = cap.read()
hsv = cv2.cvtColor(im,cv2.COLOR_BGR2HSV)
s = hsv[:,:,1]
mask = s>base
cv2.imshow('mask',im*mask[:,:,np.newaxis])
tot = mask.shape[0]*mask.shape[1]
val = np.sum(mask)
rate = val/tot
thr = (0.05,0.3, 0.5)
ret = ""
if rate < thr[0]:
ret = "transport"
elif rate <thr[1]:
ret = "middle"
elif rate < thr[2]:
ret = "about"
else:
ret = "colored"
im = cv2.putText(im, f"Rate: {rate:.2},base={base},{ret}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
cv2.imshow('image',im)
k = cv2.waitKey(1)
if k & 0xff == ord('w'):
base+=1
elif k & 0xff == ord('s'):
base-=1
elif k & 0xff == ord('a'):
pump.push_async(speed=0.1,vol=0.1)
elif k & 0xff == ord('q'):
print("Camera index = ", vidId)
print("k =",base)
cap.release()
cv2.destroyAllWindows()
break