Google Colab中cv2_imshow图像堆叠问题及Pong游戏适配咨询
在Google Colab中解决OpenCV Pong游戏图像堆叠问题
问题描述
我在Google Colab中基于现有代码修改实现OpenCV版Pong游戏,将原代码的cv2.imshow替换为Colab专用的cv2_imshow后,发现图像会不断堆叠显示,无法在同一区域形成动态游戏画面。现咨询:
- 是否可在Colab中实现游戏式的同区域动态显示?若可行,请提供代码修改方案;
- 若不可行,是否有方法在显示新图像前清除旧图像以避免堆叠?
附上修改后的代码:
import cv2 import numpy as np import random from google.colab.patches import cv2_imshow # parameters width=1280 height=720 paddlewidth=150 paddleheight=20 paddlecolor=(75, 153, 242) lives=3 deltax=10 deltay=-10 xpos=640 ypos=400 level=1 ball=True ballradius=8 highscore=0 bgcolor=(30,79,24) scorecolor=(149, 129,252) prevval=683 myscore=0 while True: background=np.zeros([720,1366,3],dtype=np.uint8) background[:,:]=bgcolor val = random.randint(0, 1000) if val==0: val=prevval else: prevval=val cv2.rectangle(background,(1366-(val-paddlewidth//2),720-paddleheight),(1366-(val+paddlewidth//2),720),paddlecolor,-1) paddlerightcorner=(1366-(val-paddlewidth//2),720-paddleheight) paddleleftcorner=(1366-(val+paddlewidth//2),720-paddleheight) if ball==True: cv2.circle(background,(xpos,ypos),ballradius,(255,255,255),-1) xpos+=deltax ypos+=deltay if xpos>=1360 or xpos<=5: deltax=-deltax if ypos<=10: deltay=-deltay if xpos<=paddlerightcorner[0] and xpos>=paddleleftcorner[0]: if ypos>=695 and ypos<=710: deltay=-deltay myscore+=1 if myscore%5==0 and myscore>=5: level+=1 if deltax<0: deltax-=2 else: deltax+=2 if deltay<0: deltay-=1 else: deltay+=1 cv2.putText(background,'Lives: '+str(lives),(1200,35),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2) cv2.putText(background,'Level: '+str(level),(1200,68),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2) cv2.putText(background,'Score: '+str(myscore),(1200,101),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2) if ypos>=720: lives-=1 temp=cv2.blur(background,(15,15)) cv2.putText(temp,'You Lost a Life !',(300,360),cv2.FONT_HERSHEY_DUPLEX,3,(185,89,200),3,1) cv2_imshow(temp) cv2.waitKey(2000) xpos=640 ypos=400 if deltay>0: deltay=-deltay if lives==0: ball=False deltax=10 deltay=-10 level=0 background=cv2.blur(background,(20,20)) cv2.waitKey(1000) for i in range(0,720,10): background[i:i+10,:]=(24,34,255) cv2_imshow(background) cv2.waitKey(10) cv2.putText(background,'GAME OVER',(400,360),cv2.FONT_HERSHEY_DUPLEX,3,(0,255,255),2) cv2.putText(background,'Your Score: '+str(myscore),(420,420),cv2.FONT_HERSHEY_PLAIN,2,(0,255,35),2) if myscore>highscore: highscore=myscore cv2.putText(background,'HIGH SCORE: '+str(highscore),(420,480),cv2.FONT_HERSHEY_PLAIN,2,(0,255,56),2) cv2.putText(background,'Press q twice to exit or game restarts in 5 seconds',(300,550),cv2.FONT_HERSHEY_DUPLEX,1,(255,0,0),2) cv2_imshow(background) cv2.waitKey(5000) ball=True myscore=0 lives=3 if cv2.waitKey(1) & 0xff==ord('q'): break cv2_imshow(background)
问题解答
1. 可以在Colab中实现同区域动态显示
Colab支持通过IPython.display.clear_output配合cv2_imshow实现单区域动态刷新,这是适配现有代码最直接的方案。核心逻辑是每次显示新帧前,清除当前输出区域的旧内容,再加载新帧,模拟本地窗口的刷新效果。
修改要点:
- 导入
IPython.display中的clear_output工具 - 在所有调用
cv2_imshow的位置前,添加clear_output(wait=True),wait=True参数确保等待新帧内容加载后再清除旧内容,避免画面闪烁。
2. 清除旧图像的方法
上述方案本质就是清除旧图像的实现,此外也可使用matplotlib的交互式绘图模式,但clear_output方案更简洁,无需大幅改动原有游戏逻辑。
修改后的完整代码:
import cv2 import numpy as np import random from google.colab.patches import cv2_imshow from IPython.display import clear_output # parameters width=1280 height=720 paddlewidth=150 paddleheight=20 paddlecolor=(75, 153, 242) lives=3 deltax=10 deltay=-10 xpos=640 ypos=400 level=1 ball=True ballradius=8 highscore=0 bgcolor=(30,79,24) scorecolor=(149, 129,252) prevval=683 myscore=0 while True: background=np.zeros([720,1366,3],dtype=np.uint8) background[:,:]=bgcolor val = random.randint(0, 1000) if val==0: val=prevval else: prevval=val cv2.rectangle(background,(1366-(val-paddlewidth//2),720-paddleheight),(1366-(val+paddlewidth//2),720),paddlecolor,-1) paddlerightcorner=(1366-(val-paddlewidth//2),720-paddleheight) paddleleftcorner=(1366-(val+paddlewidth//2),720-paddleheight) if ball==True: cv2.circle(background,(xpos,ypos),ballradius,(255,255,255),-1) xpos+=deltax ypos+=deltay if xpos>=1360 or xpos<=5: deltax=-deltax if ypos<=10: deltay=-deltay if xpos<=paddlerightcorner[0] and xpos>=paddleleftcorner[0]: if ypos>=695 and ypos<=710: deltay=-deltay myscore+=1 if myscore%5==0 and myscore>=5: level+=1 if deltax<0: deltax-=2 else: deltax+=2 if deltay<0: deltay-=1 else: deltay+=1 cv2.putText(background,'Lives: '+str(lives),(1200,35),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2) cv2.putText(background,'Level: '+str(level),(1200,68),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2) cv2.putText(background,'Score: '+str(myscore),(1200,101),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2) if ypos>=720: lives-=1 temp=cv2.blur(background,(15,15)) cv2.putText(temp,'You Lost a Life !',(300,360),cv2.FONT_HERSHEY_DUPLEX,3,(185,89,200),3,1) clear_output(wait=True) cv2_imshow(temp) cv2.waitKey(2000) xpos=640 ypos=400 if deltay>0: deltay=-deltay if lives==0: ball=False deltax=10 deltay=-10 level=0 background=cv2.blur(background,(20,20)) cv2.waitKey(1000) for i in range(0,720,10): background[i:i+10,:]=(24,34,255) clear_output(wait=True) cv2_imshow(background) cv2.waitKey(10) cv2.putText(background,'GAME OVER',(400,360),cv2.FONT_HERSHEY_DUPLEX,3,(0,255,255),2) cv2.putText(background,'Your Score: '+str(myscore),(420,420),cv2.FONT_HERSHEY_PLAIN,2,(0,255,35),2) if myscore>highscore: highscore=myscore cv2.putText(background,'HIGH SCORE: '+str(highscore),(420,480),cv2.FONT_HERSHEY_PLAIN,2,(0,255,56),2) cv2.putText(background,'Press q twice to exit or game restarts in 5 seconds',(300,550),cv2.FONT_HERSHEY_DUPLEX,1,(255,0,0),2) clear_output(wait=True) cv2_imshow(background) cv2.waitKey(5000) ball=True myscore=0 lives=3 if cv2.waitKey(1) & 0xff==ord('q'): break clear_output(wait=True) cv2_imshow(background)
内容的提问来源于stack exchange,提问作者Mich
相关产品推荐
相关产品推荐

