钓鱼小游戏CV2脚本问题:模板匹配失效与颜色匹配报错求助
钓鱼游戏脚本问题解决方案
咱们先从最紧急的报错问题说起,再依次解决掩码合并和帧率优化的需求。
1. 解决ValueError: max() arg is an empty sequence报错
这个错误的原因很直接:回合开始前或间隙时,屏幕上没有蓝色的鱼指针,导致cnts2是空序列,这时候调用max()自然会报错。只需要在处理蓝色轮廓前加一个非空判断就行:
修改你代码中处理轮廓的部分:
# 只有检测到绿色区域时才继续 if len(cnts) > 0: # 处理绿色区域的逻辑(原代码不变) c = max(cnts, key=cv2.contourArea) (x, y, w, h) = cv2.boundingRect(c) M = cv2.moments(c) center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"])) cv2.rectangle(frame, (int(x), int(y)), (int(x+w), int(y+h)),(0, 255, 255), 2) cv2.circle(frame, center, 5, (0, 0, 255), -1) pts.appendleft(center) # 新增:只有检测到蓝色鱼轮廓时才处理 if len(cnts2) > 0: c2 = max(cnts2, key=cv2.contourArea) (x2, y2, w2, h2) = cv2.boundingRect(c2) M2 = cv2.moments(c2) center2 = (int(M2["m10"] / M2["m00"]), int(M2["m01"] / M2["m00"])) cv2.rectangle(frame, (int(x2), int(y2)), (int(x2+w2), int(y2+h2)),(0, 255, 255), 2) cv2.circle(frame, center2, 5, (0, 0, 255), -1) # 执行点击判断 if y-15 < y2 < y+15: pyautogui.click(4908, 984) time.sleep(2) y2 = 0
这样就能避免在没有鱼指针的时候触发无效的轮廓计算了。
2. 合并掩码后的轮廓识别建议
其实不建议合并绿色和蓝色掩码,因为你需要明确区分“绿色目标区域”和“蓝色鱼指针”两个不同的对象。合并后所有轮廓会混在一起,反而需要额外的步骤去区分哪个是哪个,增加了逻辑复杂度。
如果一定要尝试合并,思路是:
- 合并掩码:
combined_mask = cv2.bitwise_or(mask, mask2) - 提取所有轮廓
- 对每个轮廓,取其中心像素,转换为HSV格式,判断属于绿色还是蓝色区间
- 分别筛选出绿色区域和蓝色鱼的轮廓,再进行后续位置判断
但这个过程远不如分开处理两个掩码来得清晰高效,所以更推荐保持原有的分开掩码逻辑,只修复报错问题即可。
3. 提升屏幕捕获帧率
mss已经是Python中效率很高的屏幕捕获库了,你可以通过以下几点进一步优化:
- 缩小捕获区域:尽量精准定位滑块所在的竖条区域,减少需要处理的像素量(比如如果滑块宽度只有50,就把width设为50,而不是136)
- 关闭预览窗口:如果不需要实时看捕获画面,注释掉
cv2.imshow("frame", frame)和cv2.waitKey()相关代码,这能节省大量资源 - 优化格式转换:mss捕获的是BGRA格式,直接转成BGR避免后续格式混乱:
frame = cv2.cvtColor(np.array(vs), cv2.COLOR_BGRA2BGR) - 减少不必要的计算:比如如果绿色区域的大小固定,可以不用每次都找最大轮廓,直接筛选符合面积范围的轮廓,减少计算量
- 尝试更轻量的轮廓提取:把
cv2.CHAIN_APPROX_SIMPLE换成cv2.CHAIN_APPROX_NONE虽然会得到更多点,但如果你的目标是找矩形框,其实SIMPLE已经足够高效
如果这些优化后帧率还是不够,可以考虑用多线程把屏幕捕获和图像处理分开,避免互相阻塞,但这会增加代码复杂度,适合极致帧率需求的场景。
内容的提问来源于stack exchange,提问作者Exilion
相关产品推荐
相关产品推荐

