0

I'm using Python 3.x and Cascades OpenCV to detect my hand and sending coordinate (in pixel) of it to Arduino.
Everything is going fine when I'm using 1 hand gesture. BUT, when I'm trying to using 2 like this:
1. Opened hand -> Change X and Z (keep Y) by moving left-right and up-down
2. Closed hand -> Change Y (keep X and Z) by moving up-down
It ran in to some problem like "global variable" and "local variable".


import cv2                  # OpenCV
import numpy as np
from serial import Serial   # serial communication
import struct               # pack int to byte => for sending in serial

arduinoData = Serial('com6', 115200)
cap = cv2.VideoCapture(0)   # 0 = laptom camera
Closed_cascade = cv2.CascadeClassifier('Closed.xml')
Opened_cascade = cv2.CascadeClassifier('Opened.xml')

while(True):
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    Closed_detect = Closed_cascade.detectMultiScale(gray, 1.2, 5)
    Opened_detect = Opened_cascade.detectMultiScale(gray, 1.2, 5)

    for (x1, y1, w1, h1) in Opened_detect:
        cv2.rectangle(frame, (x1, y1), (x1 + w1, y1 + h1), (0, 150, 0), 2)

        servoPosition = 35
        zcenter1 = int(x1 + w1/2)
        ycenter1 = ycenter2
        xcenter1 = int(y1 + h1/2 + 30)

        arduinoData.write(struct.pack('>IIII',xcenter1,ycenter1,zcenter1,servoPosition))

    for (x2, y2, w2, h2) in Closed_detect:
        cv2.rectangle(frame, (x2, y2), (x2 + w2, y2 + h2), (0, 0, 200), 2)

        servoPosition = 5
        zcenter2 = zcenter1
        ycenter2 = int(y2 + h2/2 + 30)
        xcenter2 = xcenter1

        arduinoData.write(struct.pack('>IIII',xcenter2,ycenter2,zcenter2,servoPosition))

    cv2.imshow('Webcam', frame)
    k = cv2.waitKey(40) & 0xff
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()

When i'm trying to run the code, some false happen like:

name 'ycenter2' is not defined
name 'zcenter1' is not defined
name 'xcenter1' is not defined


How to swap their variables when they are in 2 different for-loop function like below?

ycenter1 = ycenter2

zcenter2 = zcenter1  
xcenter2 = xcenter1  

I newbie in Python so I'm appreciate all of your help! Thanks a lot!

6
  • 1
    I think putting this line: ycenter2 = int(y2 + h2/2 + 30) before the first for will do the trick. Commented Sep 18, 2019 at 11:31
  • Hello @SayandipDutta, it doesn't work because they are not global variables, debug say they are not define yet! Commented Sep 18, 2019 at 11:43
  • Please provide the actual error message/stack trace you get when you run the code. Commented Sep 18, 2019 at 11:44
  • Hello @FiddleStix, i'm added error message, thanks for reminding me! Commented Sep 18, 2019 at 11:51
  • You are trying to do ycenter1 = ycenter2 in the first for loop. As the other commenter has mentioned, this is because you have not declared ycenter2 yet. If you declare it before it, the first error will be fixed. I imagine it will fix the other errors too. Commented Sep 18, 2019 at 12:30

1 Answer 1

1

You can iterate two lists simultaneous, smth like that. So you can declare ycenter2 before ycenter1

while(True):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
Closed_detect = Closed_cascade.detectMultiScale(gray, 1.2, 5)
Opened_detect = Opened_cascade.detectMultiScale(gray, 1.2, 5)

for (x1, y1, w1, h1), (x2, y2, w2, h2) in zip(Opened_detect, Closed_detect):
    cv2.rectangle(frame, (x1, y1), (x1 + w1, y1 + h1), (0, 150, 0), 2)

    servoPosition = 35
    zcenter1 = int(x1 + w1/2)
    ycenter2 = int(y2 + h2/2 + 30)
    ycenter1 = ycenter2
    xcenter1 = int(y1 + h1/2 + 30)

    arduinoData.write(struct.pack('>IIII',xcenter1,ycenter1,zcenter1,servoPosition))
    cv2.rectangle(frame, (x2, y2), (x2 + w2, y2 + h2), (0, 0, 200), 2)

    servoPosition = 5
    zcenter2 = zcenter1
    xcenter2 = xcenter1

    arduinoData.write(struct.pack('>IIII',xcenter2,ycenter2,zcenter2,servoPosition))

cv2.imshow('Webcam', frame)
k = cv2.waitKey(40) & 0xff
if k == 27:
    break
Sign up to request clarification or add additional context in comments.

3 Comments

doesn't this assume Opened_detect and Closed_detect are the same lengths? (I believe if you zip two lists, it will iterate through until the end of the smaller lists based on a quick check with zip([],[1,2])) ... I'm not seeing a reason why they would be the same length, I would expect one to normally be empty and the other have one result
Thanks for you comment, but when I using your code, my hand is not detected anymore!
@le-phong, as Foon said, your problem(with my script) can be in different length in Opened_detect, Closed_detect lists. Can you provide minimum sample data?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.