对于照度低或者相机质量差造成的密集的随机小噪点,可以通过拍摄多张图像求平均值的方法来减少噪点,获得较为清晰的画面。
import cv2
import numpy as np
class FilterCamera:
def __init__(self, cap, in_frame, num):
self.cap = cap # 定义的相机
self.num = num # 求平均值的帧数
frame_float = in_frame.astype(float)
self.frames = [frame_float] * self.num
self.sum_frame = sum(self.frames)
self.filtered_frame = self.sum_frame / self.num # 平均后的图像
# 输出画面
def frame_out(self):
# 从相机获取图像
r, f = self.cap.read()
if r:
frame_float = f.astype(float) # 转为浮点数,防溢出
# pop操作
self.sum_frame -= self.frames[0]
self.sum_frame += frame_float
# 求平均值并转换为uint8
self.filtered_frame = (self.sum_frame / self.num).astype(np.uint8)
self.frames = self.frames[1:] + [frame_float]
return self.filtered_frame
# cv2.imshow('Average Frame', self.average_frame)
# 释放相机资源
def release(self):
self.cap.release()
# #############################主程序###################################
if __name__ == '__main__':
import threading
cap = cv2.VideoCapture(0) # 连接到相机0
ret, frame = cap.read() # 读取相机数据
if ret:
filter_cam = FilterCamera(cap, frame, 5) # 定义相机
# 显示画面
def show_frame():
global timer
frame = filter_cam.frame_out() # 获取帧
cv2.imshow('Video Frame', frame) # 显示帧
# 帧定时器
timer = threading.Timer(0.05, show_frame)
timer.start()
show_frame()
# 进程守护循环
while True:
if cv2.waitKey(1) & 0xFF == ord('q'):
timer.cancel() # 取消定时器
filter_cam.release() # 释放相机资源
cv2.destroyAllWindows() # 销毁窗口
break
效果对比:
未降噪
降噪后
与高斯滤波的效果相比,这种方法在降噪的同时不会使画面模糊,甚至更锐利。缺点是降低了帧率,比较适合对帧率要求不高的场合。