1
Former-commit-id: 1b34dc488f5306fcb5d20746c217255bb9ead3c5
This commit is contained in:
2
ch340.py
2
ch340.py
@ -117,7 +117,7 @@ else:
|
||||
self._speed = 43
|
||||
self._speed = 43/34
|
||||
# x = x*30
|
||||
print(int((x-int(x))*100),int(x),x)
|
||||
# print(int((x-int(x))*100),int(x),x)
|
||||
self.pump_ser.write(f"q1h{int(x)}d".encode('ascii'))
|
||||
time.sleep(0.01)
|
||||
self.pump_ser.write(f"q2h{int((x-int(x))*100)}d".encode('ascii'))
|
||||
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fc7d1088d4f1edb2c939f12a2d5cd136142744c6ddd23835f91710a0383d295f
|
||||
size 21382656
|
1
ch340_gui.exe.REMOVED.git-id
Normal file
1
ch340_gui.exe.REMOVED.git-id
Normal file
@ -0,0 +1 @@
|
||||
f3beccf0b1e66d017cf3a9c35c1f0a50476f25b6
|
132
main.py
132
main.py
@ -6,6 +6,7 @@ import ch340
|
||||
import atexit
|
||||
import utils
|
||||
from utils import State, History
|
||||
from scipy.signal import find_peaks
|
||||
|
||||
|
||||
class MAT:
|
||||
@ -39,8 +40,8 @@ class MAT:
|
||||
self.control_logger.info('完成抽取')
|
||||
|
||||
def ch340_init(self):
|
||||
self.ch340.push(speed=1,t=1)
|
||||
self.ch340.pull(speed=1.2,vol=1)
|
||||
# self.ch340.push(speed=1,t=1)
|
||||
self.ch340.pull(speed=1.2,vol=1.8)
|
||||
self.control_logger.info('电极位置已初始化')
|
||||
|
||||
def ch340_push(self, speed=0.1):
|
||||
@ -93,12 +94,17 @@ class MAT:
|
||||
if self.state.mode == State.Mode.CRAZY:
|
||||
self._display_status(im, ret, rate, val)
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
# === 状态进入逻辑 ===
|
||||
if now - self._start_time<10:
|
||||
self._display_status(im, ret, rate, val)
|
||||
return ret
|
||||
|
||||
if not self.edited and self.history.base is not None and rate>self.history.base * 2:
|
||||
self.edited = True
|
||||
self.speeds[0] /= 2
|
||||
|
||||
# 1. middle: predictor返回middle立即进入slow状态
|
||||
if ret == "middle":
|
||||
if self.state.is_fast_mode():
|
||||
@ -141,8 +147,8 @@ class MAT:
|
||||
|
||||
if self.state.mode == State.Mode.ABOUT and self.state.about_check:
|
||||
h = self.history.get_recent_records(self.about_time/3,now)
|
||||
ratio = self.history.get_state_ratio("about", h)
|
||||
self.history.about_history.append(ratio<0.3)
|
||||
ratio = self.history.get_state_ratio("transport", h)
|
||||
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:
|
||||
@ -150,51 +156,96 @@ class MAT:
|
||||
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)
|
||||
self.state.about_check = False
|
||||
|
||||
|
||||
|
||||
# end检查: 进入end之后的end_bounce_time,如果end比例<80%,则重置;否则终止实验
|
||||
if self.state.should_check_end_result(now):
|
||||
colored_ratio = self.history.get_state_ratio("colored", self.history.get_recent_records(self.state.end_bounce_time, now))
|
||||
# if self.state.should_check_end_result(now):
|
||||
# colored_ratio = self.history.get_state_ratio("colored", self.history.get_recent_records(self.state.end_bounce_time, now))
|
||||
|
||||
if colored_ratio < 0.8:
|
||||
# end比例<80%,从history中找到第二个end并继续check逻辑
|
||||
self.endpoint_logger.warning(f"colored比例{colored_ratio:.2%}<80%,寻找下一个colored点")
|
||||
# if colored_ratio < 0.8:
|
||||
# # end比例<80%,从history中找到第二个end并继续check逻辑
|
||||
# self.endpoint_logger.warning(f"colored比例{colored_ratio:.2%}<80%,寻找下一个colored点")
|
||||
|
||||
# 寻找历史中倒数第二个colored状态
|
||||
colored_times = self.history.get_states_by_type("colored")
|
||||
if len(colored_times) >= 2:
|
||||
# 使用倒数第二个colored时间重新开始检查
|
||||
second_last_colored_time = colored_times[1]
|
||||
self.state.end_detected_time = second_last_colored_time
|
||||
# # 寻找历史中倒数第二个colored状态
|
||||
# colored_times = self.history.get_states_by_type("colored")
|
||||
# if len(colored_times) >= 2:
|
||||
# # 使用倒数第二个colored时间重新开始检查
|
||||
# second_last_colored_time = colored_times[1]
|
||||
# self.state.end_detected_time = second_last_colored_time
|
||||
|
||||
# 更新colored记录为对应的体积
|
||||
record = self.history.find_record_by_timestamp(second_last_colored_time)
|
||||
if record:
|
||||
self.colored_volume = record.volume
|
||||
self.colored_time = record.timestamp
|
||||
self.colored_im = record.image.copy()
|
||||
# # 更新colored记录为对应的体积
|
||||
# record = self.history.find_record_by_timestamp(second_last_colored_time)
|
||||
# if record:
|
||||
# self.colored_volume = record.volume
|
||||
# self.colored_time = record.timestamp
|
||||
# self.colored_im = record.image.copy()
|
||||
|
||||
self.endpoint_logger.info(f"重置到第二个colored点: {self.colored_volume:.2f} ml")
|
||||
else:
|
||||
# 没有足够的colored点,重置end检查
|
||||
self.state.reset_end_check()
|
||||
self.colored_volume = None
|
||||
self.colored_time = None
|
||||
self.endpoint_logger.info("没有足够的colored点,重置end检查")
|
||||
else: # end比例>=80%,确认终点,终止实验
|
||||
self.endpoint_logger.info(f"colored比例{colored_ratio:.2%}>=80%,确认滴定终点")
|
||||
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"
|
||||
# self.endpoint_logger.info(f"重置到第二个colored点: {self.colored_volume:.2f} ml")
|
||||
# else:
|
||||
# # 没有足够的colored点,重置end检查
|
||||
# self.state.reset_end_check()
|
||||
# self.colored_volume = None
|
||||
# self.colored_time = None
|
||||
# self.endpoint_logger.info("没有足够的colored点,重置end检查")
|
||||
# else: # end比例>=80%,确认终点,终止实验
|
||||
# self.endpoint_logger.info(f"colored比例{colored_ratio:.2%}>=80%,确认滴定终点")
|
||||
# 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"
|
||||
|
||||
# 显示状态信息
|
||||
self._display_status(im, ret, rate, val)
|
||||
return ret
|
||||
|
||||
def end_check(self,dep=0):
|
||||
if dep > 5:
|
||||
# self.endpoint_logger.info(f"colored比例{.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"
|
||||
suc,im = self.cap.read()
|
||||
hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
|
||||
s = hsv[:, :, 0]
|
||||
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.2, # 峰值高度至少是最大值的10%
|
||||
distance=10, # 峰值之间的最小距离
|
||||
prominence=np.max(hist) * 0.01) # 峰值的突出度
|
||||
if np.any(peaks>130):
|
||||
self.history.end_history.append(True)
|
||||
time.sleep(2)
|
||||
self.control_logger.info(f"检测到colored状态,end_check at {dep}")
|
||||
self.end_check(dep+1)
|
||||
else:
|
||||
self.history.end_history.append(False)
|
||||
|
||||
def _display_status(self, im, detection_result, rate, volume):
|
||||
"""显示状态信息到图像上"""
|
||||
mode_color = {
|
||||
@ -223,7 +274,7 @@ class MAT:
|
||||
rate = val/tot
|
||||
if self.history.base is not None:
|
||||
base = self.history.base
|
||||
thr = (min(0.05,base*5), min(0.4,base*9), 0.75)
|
||||
thr = (min(0.05,base*5), min(0.4,base*13), 0.5)
|
||||
if rate < thr[0]:
|
||||
return "transport",rate
|
||||
elif rate <thr[1]:
|
||||
@ -246,8 +297,9 @@ class MAT:
|
||||
def run(self, quick_speed=0.2, slow_speed=0.05, end_speed=0.02, mid_time=0.5, about_time=1, cap_dir="Videos"):
|
||||
self.running = True
|
||||
self.start_time = time.time()
|
||||
self.speeds = (quick_speed, slow_speed, end_speed, 1.0)
|
||||
self.speeds = [quick_speed, slow_speed, end_speed, 1.0]
|
||||
self.need_check = False
|
||||
self.edited = False
|
||||
|
||||
if cap_dir is not None:
|
||||
vid_name = f"{cap_dir}/{datetime.now().strftime('%Y%m%d_%H%M%S')}.mkv"
|
||||
@ -363,7 +415,7 @@ if __name__ == "__main__":
|
||||
|
||||
mat.run(
|
||||
slow_speed = 0.05,
|
||||
quick_speed = 0.15,
|
||||
quick_speed = 0.45,
|
||||
about_time=3,
|
||||
# cap_dir=None
|
||||
)
|
||||
|
11
test.py
11
test.py
@ -3,7 +3,7 @@ import numpy as np
|
||||
from matplotlib import pyplot as plt
|
||||
from scipy.signal import find_peaks
|
||||
|
||||
cap = cv2.VideoCapture(1) # 使用摄像头0,通常更稳定
|
||||
cap = cv2.VideoCapture(2) # 使用摄像头0,通常更稳定
|
||||
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) # 降低分辨率提高处理速度
|
||||
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
|
||||
|
||||
@ -25,7 +25,7 @@ while True:
|
||||
|
||||
# 直接提取饱和度通道,避免完整HSV转换
|
||||
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
|
||||
s = hsv[:, :, 1]
|
||||
s = hsv[:, :, 0]
|
||||
s = s[s > 0] # 只保留非零饱和度值,减少噪声
|
||||
# 使用更高效的直方图计算
|
||||
hist = cv2.calcHist([s], [0], None, [256], [0, 256])
|
||||
@ -33,9 +33,9 @@ while True:
|
||||
|
||||
# 峰值检测 - 找到直方图中的峰值
|
||||
peaks, properties = find_peaks(hist,
|
||||
# height=np.max(hist) * 0.1, # 峰值高度至少是最大值的10%
|
||||
distance=5, # 峰值之间的最小距离
|
||||
prominence=np.max(hist) * 0.05) # 峰值的突出度
|
||||
height=np.max(hist) * 0.5, # 峰值高度至少是最大值的10%
|
||||
distance=10, # 峰值之间的最小距离
|
||||
prominence=np.max(hist) * 0.2) # 峰值的突出度
|
||||
|
||||
# 清除旧数据并绘制新直方图
|
||||
ax.clear()
|
||||
@ -43,6 +43,7 @@ while True:
|
||||
|
||||
# 标注峰值
|
||||
if len(peaks) > 0:
|
||||
print(peaks)
|
||||
ax.text(0.5, 1.05, f'Found {len(peaks)} peaks')
|
||||
ax.plot(peaks, hist[peaks], 'ro', markersize=8, label=f'Peaks ({len(peaks)})')
|
||||
# 在峰值处添加文字标注
|
||||
|
11
test2.py
Normal file
11
test2.py
Normal file
@ -0,0 +1,11 @@
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
cap = cv2.VideoCapture(2) # 使用摄像头0,通常更稳定
|
||||
im = cap.read()[1]
|
||||
hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
|
||||
h, s, v = cv2.split(hsv)
|
||||
pink_mask = (((h >= 300/360) | (h <= 20/360)) & (s >= 0.15) & (v >= 0.2))
|
||||
cv2.imshow("Pink Mask", im * pink_mask[:,:,np.newaxis]) # 显示掩码
|
||||
cv2.waitKey(0) # 等待按键
|
||||
cap.release()
|
Reference in New Issue
Block a user