基于相机云台周期运动的“远帧差”图像处理算法

        传统的帧差法针对前后两帧或者某几帧进行图像处理,一旦相机视角转动,就不能获得很好的检测效果,我所参与的项目就是一个云台搭载一台红外相机进行取像,这样可以大幅度的节约成本,但是对图像处理算法的要求就有所提高。

        本项目对检测的实时性和精确性不高,遂提出基于相机云台周期运动的远帧差图像处理算法,因为项目不同核心的图像处理方式也是不一样的,本文隐去了本项目的核心处理算法,但是完整的保留了算法框架,大家只需要调整周期视频参数,结合自己的核心图像处理算法就可以顺利运行。

        简单来说,云台一个运动周期的拍摄帧数,也就是拍摄的照片数目是固定的,取一个周期的照片和下一个周期的照片进行对比,虽然时间是不同的,但是在空间上它们所拍摄的视野是一致的,我们就可以针对这两张图片进行处理。

        写在最后:在刚接触cv2时,很难顺利安装成功,在其官网也有提到,网上的处理方法有很多,尝试过后没能解决问题。猜测和电脑配置,文件夹路径,下载的版本都有很大的关系。最后,我是通过安装Conda进行了问题的解决,建议直接安装:Conda + Pycharm,便于管理和使用。

        本文章写作初衷仅仅时为了分享,也曾查阅过部分CSDN大佬的帖子,有所借鉴,在此一并表示感谢!

# 必要的库需要导入,有的同学可能加载会有问题,最后再说
import cv2

# 参数为0就表示第1个摄像头;也可以直接输入需要检测的视频的地址;
camera = cv2.VideoCapture(0)
# 判断视频或摄像头是否打开:
if camera.isOpened():
    print('摄像头已打开')
else:
    print('摄像头未打开')
# 选择了一个形态学核:椭圆形;具体的图像处理算法根据自己的项目改变
es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
one_time_frames = 105  # 全局变量:一个云台运动周期的视频总帧数,可以自行设置
all_frames = []  # 全局变量创建一个空数组,用来储存一个周期的所有帧
test_count = 0  # 全局变量:对比次数
i = -1  # 全局变量:计数器
# 一个循环,用于读取图像并进行图像处理:
while True:
    # ret参数代表是否成功读入图像;frame参数代表传入的一帧图像
    ret, frame = camera.read()  # 读入摄像头或者视频的一帧
    if frame is None:  # 假如传入的是一段视频,此代码用来检测是否已经处理完成
        break
    if len(all_frames) == one_time_frames:  # 判断第一个周期的图像是否收集完成
        while True:
            cv2.imshow('2', frame)  # 展示当前周期视频
            cv2.waitKey(1)
            i = i + 1  # 计数器
            # frame 开始和 all_frames【i】(上一周期的帧图像)进行对比:
            # 对帧进行预处理,先转灰度图,再进行高斯滤波。
            # 用高斯滤波进行模糊处理,进行处理的原因:每个输入的视频都会因自然震动、光照变化或者摄像头本身等原因而产生噪声。对噪声进行平滑是为了避免在运动和跟踪时将其检测出来。
            gray_lwpCV = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            gray_lwpCV = cv2.GaussianBlur(gray_lwpCV, (21, 21), 0)
            # 对帧进行预处理,先转灰度图,再进行高斯滤波。
            # 用高斯滤波进行模糊处理,进行处理的原因:每个输入的视频都会因自然震动、光照变化或者摄像头本身等原因而产生噪声。对噪声进行平滑是为了避免在运动和跟踪时将其检测出来。
            gray_lwpCV_i = cv2.cvtColor(all_frames[i], cv2.COLOR_BGR2GRAY)
            all_frames[i] = ''  # 图像取出后进行删除操作,节约内存空间
            gray_lwpCV_i = cv2.GaussianBlur(gray_lwpCV_i, (21, 21), 0)
            diff = cv2.absdiff(gray_lwpCV_i, gray_lwpCV)
            diff = cv2.threshold(diff, 40, 255, cv2.THRESH_BINARY)[1]  # 二值化阈值处理,总之,这句话是把diff图像当中阈值高于40的部分转为255。
            diff = cv2.dilate(diff, es, iterations=2)  # 形态学膨胀操作
            # ......
            # 此处只是进行了简单的处理,根据你的项目在进行丰富
            # ......
            print("正在与上一周期的第:", i, "张图像进行对比:")  # 便于观察当前进程
            cv2.imshow('result', diff)  # 图像处理结果
            cv2.waitKey(1)
            test_count = test_count + 1
            break
    if len(all_frames) != one_time_frames:  # 收集一个周期内的视频图像放入all_frames数组
        cv2.imshow('1', frame)  # 一个窗口,展示一个周期内的视频,便于观察
        cv2.waitKey(1)  # 必要的cv2算子,保证我们能看到,而不是一闪而过
        all_frames.append(frame)  # 添加图像到数组中
        print("正在收集上一周期的第:", len(all_frames), "张图像,请稍后")  # 打印出当前数组的长度,便于观察当前进程
    if test_count == one_time_frames:
        all_frames = []
        test_count = 0
        i = -1
camera.release()  # 释放相机或者视频流
cv2.destroyAllWindows()  # 关闭所有窗口

第一次发帖难免会有错误,敬请指正。

点个赞吧~

猜你喜欢

转载自blog.csdn.net/m0_63104578/article/details/126752148