对于照度低或者相机质量差造成的密集的随机小噪点,可以通过拍摄多张图像求平均值的方法来减少噪点,获得较为清晰的画面。
import cv2
import numpy as npclass 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.numself.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# 求平均值并转换为uint8self.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 threadingcap = cv2.VideoCapture(0) # 连接到相机0ret, frame = cap.read() # 读取相机数据if ret:filter_cam = FilterCamera(cap, frame, 5) # 定义相机# 显示画面def show_frame():global timerframe = 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
效果对比:
未降噪
降噪后
与高斯滤波的效果相比,这种方法在降噪的同时不会使画面模糊,甚至更锐利。缺点是降低了帧率,比较适合对帧率要求不高的场合。