记录--视频质量评估方法(python版本)

1-- 前言

评估方法均为网上查询的传统图像处理方法,检测效果不是很好,仅供参考。

2-- 条纹干扰诊断

# 条纹干扰诊断
'''
诊断方法:参考https://github.com/ChengHaoHappy/VideoQualityDetection/blob/master/StripeDetect.cpp
https://www.cnblogs.com/wqvbjhc/p/3768995.html
'''

import cv2
import numpy as np

def streak_diagnosis(image):
    img_HSV = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 转HSV
    img_H = img_HSV[:, :, 0] # 取色度

    best_row = cv2.getOptimalDFTSize(img_H.shape[0]) # 返回给定向量尺寸经过DFT变换后的最优尺寸大小
    best_line = cv2.getOptimalDFTSize(img_H.shape[1])

    # 下面这段代码的作用是扩充img_H图像,新增像素点的像素值为0
    temp = np.zeros((best_row, best_line))
    temp[:img_H.shape[0], :img_H.shape[1]] = img_H
    img_H = temp

    img_dft = cv2.dft(np.float32(img_H), flags = cv2.DFT_COMPLEX_OUTPUT) # 傅里叶变换
    img_dft = np.fft.fftshift(img_dft)
    mRe = img_dft[:, :, 0] # 实部
    mIm = img_dft[:, :, 1] # 虚部

    # 计算二维矢量的幅值
    img_value = cv2.magnitude(mRe, mIm)
    # 转为自然对数
    img_value = 20 * np.log(img_value)

    # 计算均值和标准差
    means, std = cv2.meanStdDev(img_value)
    # 计算最大值和最小值
    minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(img_value)

    # 计算阈值
    T = float(max(means+3*std, maxVal/2))

    r, l = img_value.shape
    count = 0 # 统计异常点的个数
    for i in range(r):
        for j in range(l):
            if img_value[i, j] > T:
                count = count + 1

    stripe_rate = count / (r*l) # 计算条纹率
    if (stripe_rate > 0.008):
        print("条纹干扰异常")
    else:
        print("条纹干扰正常")


if __name__ == '__main__':
    img_path = '/civi/Video_and_Image_Diagnostics/streak_test1.jpg'
    img = cv2.imread(img_path, cv2.IMREAD_COLOR)
    streak_diagnosis(img)

3-- 视频抖动检测

# 视频抖动诊断
# 诊断方法,参考网页:https://www.it610.com/article/1303919958840872960.htm

import numpy as np
import cv2

# 计算行投影值
def cal_row_projection(image_frame):
    rows = image_frame.shape[0] # 输入图像帧的行数
    lines = image_frame.shape[1] # 输入图像帧的列数
    single_row_sum = np.zeros([rows, 1])
    all_rows_sum = 0
    for i in range(rows): # 遍历每一行   # 函数也可以用numpy.sum实现
        for j in range(lines): # 遍历每一列
            single_row_sum[i] = single_row_sum[i] + image_frame[i, j]  # 对每一行求和
        all_rows_sum = all_rows_sum + single_row_sum[i] # 所有行的灰度值求和
    avg_rows_sum = all_rows_sum / rows # 所有行灰度值总和的行平均值

    return (single_row_sum - avg_rows_sum) # rows*1


# 计算列投影值
def cal_line_projection(image_frame):
    rows = image_frame.shape[0]  # 输入图像帧的行数
    lines = image_frame.shape[1]  # 输入图像帧的列数
    single_line_sum = np.zeros([lines, 1])
    all_lines_sum = 0
    for i in range(lines):  # 遍历每一列 # 函数也可以用numpy.sum实现
        for j in range(rows):  # 遍历每一行
            single_line_sum[i] = single_line_sum[i] + image_frame[j, i]  # 对每一列求和

        all_lines_sum = all_lines_sum + single_line_sum[i]  # 所有列的灰度值求和
    avg_lines_sum = all_lines_sum / lines  # 所有行灰度值总和的行平均值

    return (single_line_sum - avg_lines_sum)  # lines*1

# 计算互相关最小值
def cal_min(img_frame_projection, ref_frame_projection, m): # 第一个参数为当前输入帧, 第二个参数为参考帧(一般取前一个帧)
    min_value = 999999999999 # 最小的互相关值
    idx = 0
    for w in range(2*m+1):
        w = w + 1 # 从1开始遍历
        sum_diff = 0
        for j in range(img_frame_projection.shape[0] - 2*m):
            sum_diff = (img_frame_projection[j + w - 1] - ref_frame_projection[m + j])**2
        if (sum_diff < min_value):
            min_value = sum_diff # 更新最小互相关值
            idx = w # 记录当前的w值
    return (m + 1 - min_value) # 返回位移矢量

# 抖动检测
def shake_detection(img_frame, ref_frame):
    m = 20
    threshold = 10 # 设置偏移阈值大小
    img_row_projection = cal_row_projection(img_frame) # 计算输入帧图像的行投影值
    img_line_projection = cal_line_projection(img_frame) # 计算输入帧图像的列投影值

    ref_row_projection = cal_row_projection(ref_frame) # 计算输入帧图像的行投影值
    ref_line_projection = cal_line_projection(ref_frame) # 计算输入帧图像的列投影值

    row_shift_val = cal_min(img_row_projection, ref_row_projection, m)
    line_shift_val = cal_min(img_line_projection, ref_line_projection, m)


    if (row_shift_val > threshold) or (line_shift_val > threshold):
        print("抖动异常")
    else:
        print("抖动正常")

if __name__ == '__main__':
    cap = cv2.VideoCapture('/civi/Video_and_Image_Diagnostics/car1.mp4')
    frame_sum = 0
    frame = []
    last_frame = []
    flag = 0

    while True:
        if frame_sum > 1:
            last_frame = frame
            flag = 1
        ret, frame = cap.read()  # 读取视频

        if ret is False: # 当所有帧读取完毕后退出循环
            print('视频读取失败 or 视频读取完毕')
            break
        else:
            frame_sum = frame_sum + 1
        if flag == 1:
            cur_img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 彩色图像转灰度图
            last_img_gray = cv2.cvtColor(last_frame, cv2.COLOR_BGR2GRAY)  # 彩色图像转灰度图
            shake_detection(cur_img_gray, last_img_gray)

4-- 场景变更诊断

# 场景变更诊断
'''
对彩色图像进行高斯建模,
提取高斯建模后的前景图像,
计算前景图像的变化量,若大于设定值后,则报警。
'''
import cv2
import numpy as np

if __name__ == '__main__':

    # 构造VideoCapture对象
    cap = cv2.VideoCapture('/civi/Video_and_Image_Diagnostics/car1.mp4')
    pBackgroundMOG = cv2.bgsegm.createBackgroundSubtractorMOG() # 创建一个背景分割器
    frame_sum = 0
    FGMask = []
    last_FGMask = []
    change_thresh = 100

    while True:
        ret, frame = cap.read()  # 读取视频

        if ret is False: # 当所有帧读取完毕后退出循环
            print('视频读取失败 or 视频读取完毕')
            break
        else:
            frame = cv2.resize(frame, (0, 0), fx=0.3, fy=0.3)
            frame_sum = frame_sum + 1
            if frame_sum > 1:
                last_FGMask = FGMask # 前一帧的前景图

            FGMask = pBackgroundMOG.apply(frame) # 当前帧的前景图

            #cv2.imshow('frame', frame)  # 显示当前原始帧
            #cv2.imshow('FGMask', FGMask)  # 显示当前帧的前景图像
            #if frame_sum > 1:
                #cv2.imshow('last_FGMask', last_FGMask)  # 显示前一帧的前景图像

        #if cv2.waitKey(10) & 0xff == 27:  # 按ESC键退出
            #break

        if frame_sum > 1:
            change = cv2.absdiff(FGMask, last_FGMask) # 计算当前帧和前一帧的前景差异
            if np.mean(change) > change_thresh: # 与设定的阈值比较
                print("场景异常")
                break
            else:
                print("场景正常")

    cap.release()

未完待续!

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
网络结构如下图,改进部分为CNN提取,使用了ResNet50和DenseNet101进行,改进神经网络降维部分,并使用LSTM来进行提取时序关系 ![未命名文件 (3)](https://user-images.githubusercontent.com/36041684/120127571-493e5400-c1f2-11eb-9962-3d57c0eecd90.jpg) 代码部分分为两部 - 第一部分是CNNfeatures,作用是对数据集视频进行特征提取并保存,方便后面的回归 - 第二部分是regression,对提取的特征,分为训练集、验证集、测试集,进行训练然后在验证集上提取最好的效果,并在测试集上进行测试 ``` python CNNfeatures.py python regression.py python test_demo.py -------- 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值