Ask Your Question
0

re-order my code into a function

asked 2015-05-11 06:02:12 -0600

reggie gravatar image

updated 2015-05-12 05:26:16 -0600

I'm trying to re order my code and move the commented out lines to the function accu_w(frame). When I do this I get the error:

if avg1 is None: avg1 = np.float32(frame)
UnboundLocalError: local variable 'avg1' referenced before assignment

I'm struggling to understand:

1) What this means?

2) How I can fix it?

The code:

import cv2
import numpy as np

def accu_w(frame):

    if avg1 is None: avg1 = np.float32(frame)
    if avg2 is None: avg2 = np.float32(frame)

    cv2.accumulateWeighted(frame, avg1, 0.05)
    cv2.accumulateWeighted(frame, avg2, 0.0006)

    res1 = cv2.convertScaleAbs(avg1)
    res2 = cv2.convertScaleAbs(avg2)

    cv2.imshow('img',frame)
    cv2.imshow('avg1',res1)
    cv2.imshow('avg2',res2)




def main():

    c = cv2.VideoCapture(0)

    global avg1
    avg1 = None
    global avg2
    avg2 = None

    while(True):


        got_frame,frame = c.read()

        if got_frame:


            accu_w(frame)

            '''
            if avg1 is None: avg1 = np.float32(frame)
            if avg2 is None: avg2 = np.float32(frame)

            cv2.accumulateWeighted(frame, avg1, 0.05)
            cv2.accumulateWeighted(frame, avg2, 0.0006)

            res1 = cv2.convertScaleAbs(avg1)
            res2 = cv2.convertScaleAbs(avg2)

            cv2.imshow('img',frame)
            cv2.imshow('avg1',res1)
            cv2.imshow('avg2',res2)

            '''

            k = cv2.waitKey(20)

            if k == 27:
                break

    cv2.destroyAllWindows()
    c.release()


main()

Iv'e managed to fix it by moving:

if avg1 is None: avg1 = np.float32(frame)
if avg2 is None: avg2 = np.float32(frame)

outside the function, but I still don't understand what the original error meant.

import cv2
import numpy as np



def accu_w(frame):

    cv2.accumulateWeighted(frame, avg1, 0.05)
    cv2.accumulateWeighted(frame, avg2, 0.0006)

    res1 = cv2.convertScaleAbs(avg1)
    res2 = cv2.convertScaleAbs(avg2)

    cv2.imshow('img',frame)
    cv2.imshow('avg1',res1)
    cv2.imshow('avg2',res2)



def main():

    c = cv2.VideoCapture(0)

    global avg1
    avg1 = None
    global avg2
    avg2 = None

    while(True):

        got_frame,frame = c.read()

        if got_frame:


            if avg1 is None: avg1 = np.float32(frame)
            if avg2 is None: avg2 = np.float32(frame)

            accu_w(frame)

            '''        
            cv2.accumulateWeighted(frame, avg1, 0.05)
            cv2.accumulateWeighted(frame, avg2, 0.0006)

            res1 = cv2.convertScaleAbs(avg1)
            res2 = cv2.convertScaleAbs(avg2)


            cv2.imshow('img',frame)
            cv2.imshow('avg1',res1)
            cv2.imshow('avg2',res2)

            '''

            k = cv2.waitKey(20)

            if k == 27:
                break

    cv2.destroyAllWindows()
    c.release()


main()

This appeared to work too, I think its because I have 2 functions and I need to declare the global variables inside each function. I thought if I declare something as global anywhere it could be seen by everything; but one has to declare global variables from within a function for that function to see it from outside.

import cv2
import numpy as np

def accu_w(frame):

    global avg1
    global avg2


    if avg1 is None: avg1 = np.float32(frame)
    if avg2 is None: avg2 = np.float32(frame)

    cv2.accumulateWeighted(frame, avg1, 0.1)
    cv2.accumulateWeighted(frame, avg2, 0.0006)

    res1 = cv2.convertScaleAbs(avg1)
    res2 = cv2.convertScaleAbs(avg2)


    cv2.imshow('img',frame)
    cv2.imshow('avg1',res1)
    cv2.imshow('avg2',res2)




def main():

    c = cv2.VideoCapture(0)


    global avg1
    avg1 = None
    global avg2
    avg2 = None

    while(True ...
(more)
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
1

answered 2015-05-11 17:11:10 -0600

berak gravatar image

updated 2015-05-11 17:12:21 -0600

global vars are evil. avoid them, whenever possible (in your case, just pass them as additional parameters):

import cv2
import numpy as np



def accu_w(frame, avg1, avg2):

    if avg1 is None: avg1 = np.float32(frame)
    if avg2 is None: avg2 = np.float32(frame)

    cv2.accumulateWeighted(frame, avg1, 0.05)
    cv2.accumulateWeighted(frame, avg2, 0.0006)

    res1 = cv2.convertScaleAbs(avg1)
    res2 = cv2.convertScaleAbs(avg2)

    cv2.imshow('img',frame)
    cv2.imshow('avg1',res1)
    cv2.imshow('avg2',res2)



def main():

    c = cv2.VideoCapture(0)

    avg1 = None
    avg2 = None

    while(True):

        got_frame,frame = c.read()

        if got_frame:

            accu_w(frame, avg1, avg2)

            k = cv2.waitKey(20)
            if k == 27:
                break

    cv2.destroyAllWindows()
    c.release()
edit flag offensive delete link more

Comments

Hi Berak,That's what I thought, but this results in 3 windows of live feed, i.e. 3 windows exactly the same as img. I' puzzled as to why. I think its because I don't exactly understand what if avg1 is None: avg1 = np.float32(frame) does.

reggie gravatar imagereggie ( 2015-05-12 04:56:53 -0600 )edit

Would having it inside main() make a difference? If a global is declared inside main() it cannot be seen inside accu_w(). I take your point about keeping away from globals!

reggie gravatar imagereggie ( 2015-05-12 05:09:39 -0600 )edit

again, i'm only cleaning up the syntax error.

the semantics (what is it good for ?, what was ever intended to do ?) are beyond me.

if avg1 is None: avg1 = np.float32(frame) <-- this only assigns avg1 once (in the 1st iteration)

berak gravatar imageberak ( 2015-05-12 05:10:01 -0600 )edit
1

"global is declared inside main() it cannot be seen inside accu_w()" - that's correct. that's why you should pass it as a function argument instead.

berak gravatar imageberak ( 2015-05-12 05:11:52 -0600 )edit

I aggree, thanks for that :)

reggie gravatar imagereggie ( 2015-05-12 05:44:11 -0600 )edit
1

answered 2015-05-11 13:34:23 -0600

SR gravatar image

Before you refer to a variable with global it must exist. Therefore, assign a value to it right after the imports.

edit flag offensive delete link more

Comments

I tried that but it didn't work. Could it be because there are two functions, main() and accu_w()

reggie gravatar imagereggie ( 2015-05-12 05:12:06 -0600 )edit

I may have misunderstood you, I tried specifying global right after the imports, but that didn't work. Global only seems to make a variable visible from inside to outside a function. I thought specifying a global outside a function made it visible inside all functions, which it clearly doesn't, which I realise now. Thanks :)

reggie gravatar imagereggie ( 2015-05-12 06:18:01 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-05-11 06:02:12 -0600

Seen: 363 times

Last updated: May 12 '15