我正在使用opencv阅读框架并在浏览器中显示它,但为了避免代码混乱,我将代码写入不同的文件并导入它们。
我写了三个文件:
Flask_sh.py
open_webcam.py
show_gray.py
open_webcam.py有一个类Camera
和一个方法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()
show_gray.py还有一个名为Calulate()
的类和一个方法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
现在Flask_sh.py是我调用我的文件的文件。
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)
现在我不知道问题出在哪里因为获取帧功能运行正常并且我能够将图像从字节解码到数组。但是当我将decoded
传递给cal
方法时,它在第一行中给出了错误:
错误
frame = imutils.resize(frame, width=640)
AttributeError: 'show_gray' object has no attribute 'shape'
但是当我没有创建show_gray.py而是在Flask_sh.py中编写代码时,我得到了输出。我做错了什么。
答案 0 :(得分:4)
您需要通过翻转参数的顺序来修复cal
对象的Calculate
方法; self
应该是第一个。
class Calculate():
def cal(self, frame):
...
回答您的跟进问题:
传递给任何标准类方法的第一个参数是对象本身。它在调用方法时被隐式传递,但它始终是定义的一部分。从您的示例中,当我们实例化对象时,然后调用其中一个方法:
cal = Calculate()
cal.calc(frame)
对cal.calc
的调用实际上是在传递 2 个参数,第一个参数是隐式cal
- 对象本身 - 然后是frame
。
因此,在定义标准方法(即不是类或静态方法)时,第一个参数应始终是对调用对象的引用。您可以随意调用它,但按惯例每个人都应该将其称为self
。
换句话说,这些是等价的:
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()
在这两种情况下,要访问类属性value
,都要传入对象本身,然后引用该属性。但是,定义B
时使用的代码是非标准的。人们会评判你。