final 1
Former-commit-id: dc04af028eb2ecbda74eef38f377be0989e21756
This commit is contained in:
51
main.py
51
main.py
@ -10,7 +10,7 @@ from scipy.signal import find_peaks
|
|||||||
|
|
||||||
|
|
||||||
class MAT:
|
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
|
# 初始化logging
|
||||||
utils.setup_logging()
|
utils.setup_logging()
|
||||||
self.system_logger = utils.get_system_logger()
|
self.system_logger = utils.get_system_logger()
|
||||||
@ -23,6 +23,7 @@ class MAT:
|
|||||||
self.cap = cv2.VideoCapture(videoSourceIndex, cv2.CAP_DSHOW)
|
self.cap = cv2.VideoCapture(videoSourceIndex, cv2.CAP_DSHOW)
|
||||||
self.ch340 = ch340.CH340()
|
self.ch340 = ch340.CH340()
|
||||||
self.total_volume = 0
|
self.total_volume = 0
|
||||||
|
self.k = k
|
||||||
|
|
||||||
self.state = State(bounce_time, end_bounce_time)
|
self.state = State(bounce_time, end_bounce_time)
|
||||||
|
|
||||||
@ -131,7 +132,7 @@ class MAT:
|
|||||||
# === 状态检查逻辑 ===
|
# === 状态检查逻辑 ===
|
||||||
|
|
||||||
# middle检查: 进入middle的bounce_time后,在最近bounce_time内middle比例<70%返回fast状态
|
# 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比例
|
# 计算最近bounce_time内的middle比例
|
||||||
recent_records = self.history.get_recent_records(self.state.bounce_time, now)
|
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)
|
self.history.about_history.append(ratio == 1)
|
||||||
while len(self.history.about_history) > 5:
|
while len(self.history.about_history) > 5:
|
||||||
self.history.about_history.pop(0)
|
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)
|
rate = sum(self.history.about_history) / len(self.history.about_history)
|
||||||
if rate > 0.8:
|
if rate > 0.8:
|
||||||
self.state.exit_about()
|
self.state.exit_about()
|
||||||
self.control_logger.info(f"about比例{ratio:.2%}<80%,退出about检查,返回middle模式")
|
self.control_logger.info(f"about比例{ratio:.2%}<80%,退出about检查,返回middle模式")
|
||||||
|
|
||||||
self.end_check()
|
ret = self.end_check()
|
||||||
# print(f"end_history: {self.history.end_history}",peaks)
|
if ret == "colored":
|
||||||
# if len(self.history.end_history) >= 10:
|
return ret
|
||||||
# colored_ratio=sum(self.history.end_history)/len(self.history.end_history)
|
if not self.history.last_end:
|
||||||
# if colored_ratio > 0.7:
|
self.history.last_end = max(self.history.last_end,ret)
|
||||||
# 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)
|
|
||||||
self.state.about_check = False
|
self.state.about_check = False
|
||||||
|
|
||||||
|
|
||||||
@ -182,6 +174,7 @@ class MAT:
|
|||||||
def end_check(self,dep=0):
|
def end_check(self,dep=0):
|
||||||
if dep > 5:
|
if dep > 5:
|
||||||
# self.endpoint_logger.info(f"colored比例{.2%}>=70%,确认滴定终点")
|
# 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.endpoint_logger.info(f"最终体积: {self.colored_volume:.2f} ml")
|
||||||
self.running = False
|
self.running = False
|
||||||
self.ch340.stop()
|
self.ch340.stop()
|
||||||
@ -201,12 +194,22 @@ class MAT:
|
|||||||
distance=10, # 峰值之间的最小距离
|
distance=10, # 峰值之间的最小距离
|
||||||
prominence=np.max(hist) * 0.01) # 峰值的突出度
|
prominence=np.max(hist) * 0.01) # 峰值的突出度
|
||||||
if np.any(peaks>130):
|
if np.any(peaks>130):
|
||||||
|
if dep == 0:
|
||||||
|
self.process_left(time.time())
|
||||||
self.history.end_history.append(True)
|
self.history.end_history.append(True)
|
||||||
time.sleep(2)
|
|
||||||
self.control_logger.info(f"检测到colored状态,end_check at {dep}")
|
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:
|
else:
|
||||||
self.history.end_history.append(False)
|
return dep
|
||||||
|
|
||||||
def _display_status(self, im, detection_result, rate, volume):
|
def _display_status(self, im, detection_result, rate, volume):
|
||||||
"""显示状态信息到图像上"""
|
"""显示状态信息到图像上"""
|
||||||
@ -229,7 +232,7 @@ class MAT:
|
|||||||
def predictor(self,im):
|
def predictor(self,im):
|
||||||
hsv = cv2.cvtColor(im,cv2.COLOR_BGR2HSV)
|
hsv = cv2.cvtColor(im,cv2.COLOR_BGR2HSV)
|
||||||
s = hsv[:,:,1]
|
s = hsv[:,:,1]
|
||||||
mask = s>30
|
mask = s>self.k
|
||||||
cv2.imshow('mask',im*mask[:,:,np.newaxis])
|
cv2.imshow('mask',im*mask[:,:,np.newaxis])
|
||||||
tot = mask.shape[0]*mask.shape[1]
|
tot = mask.shape[0]*mask.shape[1]
|
||||||
val = np.sum(mask)
|
val = np.sum(mask)
|
||||||
@ -237,6 +240,7 @@ class MAT:
|
|||||||
if self.history.base is not None:
|
if self.history.base is not None:
|
||||||
base = self.history.base
|
base = self.history.base
|
||||||
thr = (min(0.05,base*5), min(0.4,base*13), 0.5)
|
thr = (min(0.05,base*5), min(0.4,base*13), 0.5)
|
||||||
|
# thr = (base*5, base*13, 0.5)
|
||||||
if rate < thr[0]:
|
if rate < thr[0]:
|
||||||
return "transport",rate
|
return "transport",rate
|
||||||
elif rate <thr[1]:
|
elif rate <thr[1]:
|
||||||
@ -370,14 +374,15 @@ if __name__ == "__main__":
|
|||||||
mat = MAT(
|
mat = MAT(
|
||||||
videoSourceIndex = 1,
|
videoSourceIndex = 1,
|
||||||
bounce_time=4,
|
bounce_time=4,
|
||||||
end_bounce_time=0.01
|
end_bounce_time=0.01,
|
||||||
|
k = 34
|
||||||
)
|
)
|
||||||
|
|
||||||
mat.state.mode = State.Mode.FAST
|
mat.state.mode = State.Mode.FAST
|
||||||
|
|
||||||
mat.run(
|
mat.run(
|
||||||
slow_speed = 0.05,
|
slow_speed = 0.05,
|
||||||
quick_speed = 0.45,
|
quick_speed = 0.8,
|
||||||
about_time=3,
|
about_time=3,
|
||||||
# cap_dir=None
|
# cap_dir=None
|
||||||
)
|
)
|
||||||
|
1
utils.py
1
utils.py
@ -44,6 +44,7 @@ class History:
|
|||||||
self._base_time = base_time
|
self._base_time = base_time
|
||||||
self._base_cnt = 0
|
self._base_cnt = 0
|
||||||
self.end_history:list[bool] = []
|
self.end_history:list[bool] = []
|
||||||
|
self.last_end = 0
|
||||||
self.display = display
|
self.display = display
|
||||||
self.fig: Any = None
|
self.fig: Any = None
|
||||||
self.ax: Any = None
|
self.ax: Any = None
|
||||||
|
43
vid_chk.py
43
vid_chk.py
@ -1,4 +1,5 @@
|
|||||||
import cv2
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
flag = False
|
flag = False
|
||||||
vidId = 1
|
vidId = 1
|
||||||
@ -8,11 +9,49 @@ while not flag:
|
|||||||
cv2.imshow("image",im)
|
cv2.imshow("image",im)
|
||||||
k = cv2.waitKey(0)
|
k = cv2.waitKey(0)
|
||||||
if k & 0xff == ord('q'):
|
if k & 0xff == ord('q'):
|
||||||
cap.release()
|
# cap.release()
|
||||||
cv2.destroyAllWindows()
|
# cv2.destroyAllWindows()
|
||||||
flag=True
|
flag=True
|
||||||
else:
|
else:
|
||||||
vidId+=1
|
vidId+=1
|
||||||
cap.release()
|
cap.release()
|
||||||
cap.open(vidId, cv2.CAP_DSHOW)
|
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
|
Reference in New Issue
Block a user