树莓派4B Python3 OpenCV检测鸟类触发pygame播放音频的实现问题
问题解答
1. 需求可行性
该整合需求完全可以实现,你之前整合失败多是触发逻辑不合理、播放重复打断或者音频输出配置的问题。
2. 实现指导
常见失败原因排查
- 直接在帧循环里加播放逻辑会导致每检测到一帧鸟类就重新触发播放,音频被反复打断根本无法正常播放
- 树莓派默认音频输出可能不是蓝牙音箱,需要先在系统设置中将蓝牙音箱设为默认输出设备
- mp3文件用相对路径的话,脚本运行的工作目录不对会导致找不到音频文件,建议写绝对路径
修改后完整可运行代码
import cv2 import pygame as pg from pygame import mixer import time # 初始化音频模块 mixer.init() # 这里改成你mp3文件的绝对路径 AUDIO_PATH = "/home/pi/Desktop/Duck-quack.mp3" mixer.music.load(AUDIO_PATH) mixer.music.set_volume(1.0) # 播放冷却时间,单位秒,避免重复触发 COOLDOWN = 30 last_play_time = 0 # 物体检测初始化部分 classNames = [] classFile = "/home/pi/Desktop/Object_Detection_Files/coco.names" with open(classFile,"rt") as f: classNames = f.read().rstrip("\n").split("\n") configPath = "/home/pi/Desktop/Object_Detection_Files/ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt" weightsPath = "/home/pi/Desktop/Object_Detection_Files/frozen_inference_graph.pb" net = cv2.dnn_DetectionModel(weightsPath,configPath) net.setInputSize(320,320) net.setInputScale(1.0/ 127.5) net.setInputMean((127.5, 127.5, 127.5)) net.setInputSwapRB(True) def getObjects(img, thres, nms, draw=True, objects=[]): classIds, confs, bbox = net.detect(img,confThreshold=thres,nmsThreshold=nms) if len(objects) == 0: objects = classNames objectInfo =[] if len(classIds) != 0: for classId, confidence,box in zip(classIds.flatten(),confs.flatten(),bbox): className = classNames[classId - 1] if className in objects: objectInfo.append([box,className]) if (draw): cv2.rectangle(img,box,color=(0,255,0),thickness=2) cv2.putText(img,classNames[classId-1].upper(),(box[0]+10,box[1]+30), cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2) cv2.putText(img,str(round(confidence*100,2)),(box[0]+200,box[1]+30), cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2) return img,objectInfo if __name__ == "__main__": cap = cv2.VideoCapture(0) cap.set(3,640) cap.set(4,480) while True: success, img = cap.read() result, objectInfo = getObjects(img,0.50,0.2, objects=['bird']) # 鸟类检测触发播放逻辑 current_time = time.time() if len(objectInfo) > 0: # 满足冷却时间且当前没有正在播放的音频才触发 if current_time - last_play_time > COOLDOWN and not mixer.music.get_busy(): mixer.music.play() last_play_time = current_time cv2.imshow("Output",img) # 按q键退出程序 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放资源 cap.release() cv2.destroyAllWindows() mixer.quit()
额外调试建议
如果pygame还是无法正常输出到蓝牙音箱,可以换用命令行调用ffplay实现播放,先安装ffmpeg:sudo apt install ffmpeg,然后把播放逻辑替换成os.system("ffplay -nodisp -autoexit {} &".format(AUDIO_PATH))即可,注意要先导入os模块。
内容的提问来源于stack exchange,提问作者Emma Realtor
相关产品推荐
相关产品推荐

