1. 单继承
代码编写过程中,重复的地方肯定越少越好,继承就是一个能够有效减少重复的一个方法,这里主要讲述三点:
- 继承的基本语法
- 方法的重写
父类的方法实现不能满足子类的需求。 - 对父类方法扩展
子类的方法实现中包含父类的方法实现。
最后我用实现二帧差法和三帧差法来最为实例。
1.1. 继承的基本语法
class 类名(父类名):
pass
1.2. 方法的重写
重写的英文名字为override,可以理解为把父类的方法整个覆盖掉。其具体实现方式:在子类中定义了一个和父类同名的方法并且实现。
1.3. 对父类方法扩展
如果在子类中需要部分父类的方法,那么就可以使用扩展功能。
就可以使用扩展的方式:
- 在子类中 重写 父类的方法
- 在需要的位置使用 super().父类方法 来调用父类方法的执行
- 代码其他的位置针对子类的需求,编写子类特有的代码实现
关于 super:
在 Python 中 super 是一个 特殊的类
super() 就是使用 super 类创建出来的对象,最常使用的场景就是在 重写父类方法时,调用 在父类中封装的方法实现。
python 子类继承父类的__init__方法
以上内容参考python 黑马程序员。按我自己的理解,在子类中一旦出现与父类同名的方法,就发生重写,此时子类中相当于开辟了一个新的区域用于存放重写的代码。而扩展则是调用一遍父类的方法,然后再执行子类方法里的代码。
1.4.代码实例
import cv2
import numpy as np
class SlideWindow:
def __init__(self, window_size, step_size):
self.window_size = window_size
self.step_size = step_size
if self.step_size >= self.window_size:
print('SlideWindow error')
self.val_list = []
def update_window_val(self, val):
self.val_list.append(val)
if len(self.val_list) > self.window_size:
for i in range(0, self.step_size):
self.val_list.pop(0)
return self.val_list
def clear(self):
self.val_list.clear()
class FrameDifferenceProcess(object):
def __init__(self): # 初始化一个滑动窗口来记录帧的数据
self.window_type = 2
self.image_process_slide_window = SlideWindow(self.window_type, 1)
self.diff_frame_flag = False
def process(self, frame): # 进行帧差计算
self.frame_copy = np.copy(frame)
self.frame_window = self.image_process_slide_window.update_window_val(self.frame_copy)
if len(self.frame_window) == self.window_type:
gray_image_1 = cv2.cvtColor(self.frame_window[0], cv2.COLOR_BGR2GRAY)
gray_image_1 = cv2.GaussianBlur(gray_image_1, (3, 3), 0)
gray_image_2 = cv2.cvtColor(self.frame_window[1], cv2.COLOR_BGR2GRAY)
gray_image_2 = cv2.GaussianBlur(gray_image_2, (3, 3), 0)
d_frame = cv2.absdiff(gray_image_1, gray_image_2)
ret, self.d_frame = cv2.threshold(d_frame, 15, 255, cv2.THRESH_BINARY) # 阈值要高
self.dframe_modification()
def dframe_modification(self): # 对帧差完成后的图像略作图像学修改
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
self.d_frame = cv2.dilate(self.d_frame, kernel, iterations=7) # 最终的三帧差结果
if not np.any(self.d_frame):
self.diff_frame_flag = True
def clear(self):
self.image_process_slide_window.clear()
class TwoFrameDifferenceProcess(FrameDifferenceProcess):
pass
class ThreeFrameDifferenceProcess(FrameDifferenceProcess):
def __init__(self):
super(ThreeFrameDifferenceProcess, self).__init__()
self.window_type = 3
self.image_process_slide_window = SlideWindow(self.window_type, 1)
def process(self, frame):
# print("在进行三帧差法")
self.frame_copy = np.copy(frame)
self.frame_window = self.image_process_slide_window.update_window_val(self.frame_copy)
if len(self.frame_window) == 3:
gray_image_1 = cv2.cvtColor(self.frame_window[0], cv2.COLOR_BGR2GRAY)
gray_image_1 = cv2.GaussianBlur(gray_image_1, (3, 3), 0)
gray_image_2 = cv2.cvtColor(self.frame_window[1], cv2.COLOR_BGR2GRAY)
gray_image_2 = cv2.GaussianBlur(gray_image_2, (3, 3), 0)
gray_image_3 = cv2.cvtColor(self.frame_window[2], cv2.COLOR_BGR2GRAY)
gray_image_3 = cv2.GaussianBlur(gray_image_3, (3, 3), 0)
d1_frame = cv2.absdiff(gray_image_1, gray_image_2)
ret, d1_frame = cv2.threshold(d1_frame, 15, 255, cv2.THRESH_BINARY) # 阈值要高
d2_frame = cv2.absdiff(gray_image_2, gray_image_3)
ret, d2_frame = cv2.threshold(d2_frame, 15, 255, cv2.THRESH_BINARY)
self.d_frame = cv2.bitwise_and(d1_frame, d2_frame)
super().dframe_modification()
2. 多继承
2.1. 基本语法
class 子类名(父类名1,父类名2,...)
pass
3. 关于继承的思考
- 父类中属性的变化会影响子类的值吗?
- 没有实例化前父类和子类的内存地址与所占空间?
- 实例化后父类和子类的所占地址和所占空间?
- 实例化后父类和子类方法地址是否相同?
import sys
class A:
def __init__(self):
self.num1 = 1
def change_num(self, num):
self.num1 = num
class B(A):
pass
class C:
def __init__(self, cc):
self.c = cc
self.c2 = 3
# 地址不同
print(id(A))
print(id(B))
# 地址相同
print(id(A.change_num))
print(id(B.change_num))
# 相同 1064
print(sys.getsizeof(A))
print(sys.getsizeof(B))
print(sys.getsizeof(C))
a = A()
b = B()
c = C(2)
# 相同 48
print(sys.getsizeof(a))
print(sys.getsizeof(b))
print(sys.getsizeof(c))
# 不同
print(id(a))
print(id(b))
# 相同
print(id(a.num1))
print(id(b.num1))
# 相同
print(id(a.change_num))
print(id(b.change_num))
# 值相同
print(a.num1)
print(b.num1)
a.change_num(2)
# 不同
print(a.num1) # 2
print(b.num1) # 1
# 不同
print(id(a.num1))
print(id(b.num1))