0

Hey python friends.

Sorry for the long code. Am doing a pong hand tracking for a project and need a full screen, the full screen works but i have an error with

img = cv2.addWeighted(img, 0.2, imgBackground, 0.8, 0)

Regarding the background overlay the error is:

File "D:\Stage\Hand gesture\Pong - HT - TekAngel\pong.py", line 91, in start_pong
    img = cv2.addWeighted(img, 0.2, imgBackground, 0.8, 0)
cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\core\src\arithm.cpp:650: error: (-209:Sizes of input arguments do not match) The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' in function 'cv::arithm_op

The Scripts:

import cv2
import cvzone
from cvzone.HandTrackingModule import HandDetector
import numpy as np
import pygame
from tkinter import * 
import time


# variable
##############################
detCon = 0.7 # detection confident ratio 0.1 to 0.9
hands = 2
width = 1280
height = 720
ball_pos = [640, 235]
speedX = 15
speedY = 15
gameOver = False
player_Left_Name = ""
player_Right_Name = ""
player_Right_Score = 0
player_Left_Score = 0
##############################

# cam setting
##############################
cap = cv2.VideoCapture(0)
cv2.namedWindow("Pong New GEN", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("Pong New GEN", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
##############################

# pygame object
##############################
pygame.init()
##############################

# tknint object
##############################
root = Tk()
root.title("Pong Land Tracking")
root.geometry('450x330')
root.resizable(width=False, height=False)
##############################

# image import
##############################
imgBackground = cv2.imread("Resources/Background-EMD.png") # in full screen original size(720, 1280, 3)
imgGameOver = cv2.imread("Resources/gameOver.png")
imgBall = cv2.imread("Resources/Ball.png",cv2.IMREAD_UNCHANGED)
player_Left_paddle = cv2.imread("Resources/bat1.png",cv2.IMREAD_UNCHANGED)
player_Right_paddle = cv2.imread("Resources/bat2.png",cv2.IMREAD_UNCHANGED)
##############################

# sound music
##############################
point_effect = pygame.mixer.Sound('Sound/block.wav')
gameover_effect = pygame.mixer.Sound('Sound/hit_skill00.wav')
pygame.mixer.music.load('Sound/gameMusic.wav')
pygame.mixer.music.play(-1)
#############################

# handtracking object
#############################
detector = HandDetector(detectionCon = detCon, maxHands=hands)
#############################
print(imgBackground.shape)
def start_pong():
    
    global ball_pos
    global speedX
    global speedY
    global gameOver
    global player_Left_Name
    global player_Right_Name
    global player_Right_Score
    global player_Left_Score 
    global imgGameOver 
    player_Right_Name = player_Right_Name_entry.get()
    player_Left_Name = player_Left_Name_entry.get()
    root.destroy()


    while True:
        _, img = cap.read()
        img = cv2.flip(img, 1) # flip image

        hands, img = detector.findHands(img, flipType=False) # display image

        # overlay background image
        img = cv2.addWeighted(img, 0.2, imgBackground, 0.8, 0)



        # check for hands
        if hands:
            for hand in hands:
                x, y, w, h = hand['bbox']
                h1, w1, _ = player_Right_paddle.shape
                y1 = y - h1 // 2
                y1 = np.clip(y1, 25, 370)
                
                
                if hand['type'] == "Left":
                    img = cvzone.overlayPNG(img, player_Right_paddle, (29,y1))
                    if 29+speedX < ball_pos[0] < 29 + w1 and y1 < ball_pos[1]< y1 + h1:
                        speedX = - speedX
                        ball_pos[0] += 20
                        player_Left_Score += 1
                        point_effect.play(0)

                        if speedX <= 95:
                            speedX += int(3)
                        else:
                            continue

                        # speedX 100 bug
                        
                        
                        


                if hand['type'] == "Right":
                    img = cvzone.overlayPNG(img, player_Left_paddle, (1190,y1))
                    if 1190 - 50+speedX < ball_pos[0] < 1190  and y1 < ball_pos[1] < y1 + h1:
                        speedX = - speedX
                        ball_pos[0] -= 20
                        player_Right_Score += 1
                        point_effect.play(0)

                        if speedX <= 95:
                            speedX -= int(3)
                        else:
                            continue
                        
                        
                        
                    
                        


        # game over
        if ball_pos[0] < 18 or ball_pos[0] > 1200:
            gameOver = True
            gameover_effect.play(0)

        if gameOver:
            img = imgGameOver
            cv2.putText(img, str(f'{player_Left_Score} | {player_Right_Score}').zfill(2), (562,360),cv2.FONT_HERSHEY_COMPLEX, 2, (200,0,200), 5)
        else:
            # move the ball
            if ball_pos[1] >= 490 or ball_pos[1] <= 10:
                speedY = - speedY
            ball_pos[0] += speedX
            ball_pos[1] += speedY
            print(f"X={speedX} : Y={speedY}")


            
            # draw ball
            img = cvzone.overlayPNG(img, imgBall, ball_pos)

            # display score
            cv2.putText(img, str(f'{player_Left_Name} : {player_Left_Score}').zfill(2), (10, 650), cv2.FONT_HERSHEY_COMPLEX, 3, (255,255,255), 5)
            cv2.putText(img, str(f'{player_Right_Score} : {player_Right_Name}').zfill(2), (800, 650), cv2.FONT_HERSHEY_COMPLEX, 3, (255,255,255), 5)



        if cv2.waitKey(1) & 0x7F == ord('q'):
         print("Exit requested.")
         break
         cap.release()
         cv2.destroyAllWindows()


        elif key == ord('r'):
            speedX = 15
            speedY = 15
            ball_pos = [640, 235]
            gameOver = False
            player_Left_Name = ""
            player_Right_Name = ""
            player_Right_Score = 0
            player_Left_Score = 0
            imgGameOver = cv2.imread("Resources/gameOver.png")





# tkinter display x=width, y=height
#############################)
initialize_bg = PhotoImage(file='Resources/title.png')
bg_label = Label(root, image=initialize_bg)
bg_label.place(x=50,y=20)

name_r = Label(root, text="Enter Right Hand Name : ", font=('impact', 10), fg='#585859')
name_r.place(x=50, y=130)
name_l = Label(root, text="Enter Left Hand Name : ", font=('impact', 10), fg='#585859')
name_l.place(x=50, y= 170)
player_Right_Name_entry = Entry(root, width=25, font=('impact', 10), fg='#585859')
player_Right_Name_entry.place(x=250, y=130)
player_Left_Name_entry = Entry(root, width=25, font=('impact', 10), fg='#585859')
player_Left_Name_entry.place(x=250, y=170)


start_game_bte = Button(root, width=15, text="Start Game", command=start_pong)
start_game_bte.place(x=300, y=280)



#############################
# if __name__ == '__main__':
#   main()

root.mainloop()
Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
Yoan Tufel
  • 45
  • 9
  • error shows you in which line is problem so first you could use `print()` to see what you have in variables in this line. And you should check `shape` for both elements - probably they have different shapes but they have to be the same `shape` – furas May 04 '22 at 12:37
  • I get this: imgbackground = (480, 640, 3) Img = (720, 1280, 3) Even so i try to bu all in fullscreen. – Yoan Tufel May 04 '22 at 13:18
  • `addWeighted` needs two elements with the same shape. But you have two different shapes. You have to resize background to `720, 1280` – furas May 04 '22 at 13:46
  • if you want to put background only in some region then you should use `img[y:y+480, x:x+640]` to get region with size `480,640`, next use `addWeighted` with this region, and finally put it back to `img` - ie. `img[y:y+480, x:x+640] = cv.addWeighted(img[y:y+480, x:x+640], 0.2, background, 0.8, 0)` – furas May 04 '22 at 13:50
  • 1
    if you use `f'...'` then you don't need `str()` – furas May 04 '22 at 13:54
  • Hey, thanks all of you for your help, i tried `(img[y:y+480, x:x+640] = cv.addWeighted(img[y:y+480, x:x+640], 0.2, background, 0.8, 0))` still have the some issue, but the y and x variable are int()? – Yoan Tufel May 05 '22 at 08:33
  • do you have exactly the same issue in the same place? Maybe you have different problem in different place and this would need to ask new question on new page. And if you have the same mistake in the sme place then maybe `background.shape` in this place is different then `480, 640` – furas May 05 '22 at 10:50

0 Answers0