1

I am reading frames using opencv and displaying it in browser but in order to avoid messy code I wrote my code in different files and importing them.

I wrote three files:

  • Flask_sh.py

  • open_webcam.py

  • show_gray.py

The open_webcam.py has a class Camera and a method get_frame.

open_webcam.py

class Camera():
    def get_frame(self):
        success, image = self.cap.read()
        ret, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()

The show_gray.py also has a class named Calulate() and a method cal.

show_gray.py

class Calculate():
    def cal(frame,self):
        print(type(frame))
        frame = imutils.resize(frame, width=640)
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        return gray

Now the Flask_sh.py is the file where I am calling both my files.

Flask_sh.py

from open_webcame import Camera
from show_gray import Calculate

while True:
    camera = Camera()
    frame = camera.get_frame()
    decoded = cv2.imdecode(np.frombuffer(frame, np.uint8), -1) #convert from bytes to np array
    cam1 = Calculate()
    frame1 = cam1.cal(decoded)
    cv2.imshow("Output", frame1)

Now I don't know where the issue is because get frame function is running fine and I am able to decode the image from bytes to array. But when I pass the decoded to cal method it gives me error in the first line iself as:

Error

frame = imutils.resize(frame, width=640)    
AttributeError: 'show_gray' object has no attribute 'shape'

But when instead of making show_gray.py I write the code in Flask_sh.py I get the output. What am I doing wrong.

1 Answer 1

4

You need to fix the cal method of the Calculate object by flipping the order of the arguments; self should be first.

class Calculate():
    def cal(self, frame):
        ...

To answer your follow up question:

The first argument passed to any standard class method is the object itself. It is implicitly passed when calling the method, but it is always part of the definition. From your example, when we instantiate the object then call one of its methods:

cal = Calculate()
cal.calc(frame)

the call to cal.calc is actually passing 2 arguments, the first argument is implicitly cal -- the object itself -- and then frame.

So when defining a standard method (i.e. not a class or static method), the first argument should always be a reference to the calling object. You could call it whatever you wanted, but by convention everyone should call it self.

In other words, these would be equivalent:

class A:
    value = 1
    def print_value(self):
        print(self.value)

a = A()
a.print_value()


class B:
    value = 1
    def print_value(me):
        print(me.value)

b = B()
b.print_value()

In both cases, to access the class attribute value, you pass in the object itself which, and then reference the attribute. However, the code used in defining B is non-standard. People will judge you.

Sign up to request clarification or add additional context in comments.

2 Comments

yeah. You are right. Why I didn't see that. Just curious ,is the order matter
@RaghavPatnecha becaulse your class instance is known as frame and your ndarray as self - the way you ordered your variables - when calling class methods they get called by providing the class instance first - whatever name you give as first variable in your function definition will represent the classes instance.

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.