栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python学习 | 2021-10-15 视频图像处理(二)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python学习 | 2021-10-15 视频图像处理(二)

目录

一、图像直方图

完整代码:

运行结果:

函数使用:

二、视频分镜

1、基于均值哈希

运行结果:

 完整代码:

2、基于直方图相似度

运行结果:

完整代码:

三、截取视频(1分钟)

完整代码:

参数含义:

问题记录:


一、图像直方图

完整代码:
import cv2
import matplotlib.pyplot as plt

img= cv2.imread("girl.png")

histb = cv2.calcHist([img], [0], None, [256], [0, 255])
histg = cv2.calcHist([img], [1], None, [256], [0, 255])
histr = cv2.calcHist([img], [2], None, [256], [0, 255])
print(type(histb))
print(histb.size)
print(histb.shape)

plt.plot(histb, color="b")
plt.plot(histg, color="g")
plt.plot(histr, color="r")
plt.show()

运行结果:

函数使用:

cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) ->hist

imaes        输入的图像,要带[]号
channels        选择图像的通道,012对应着BGR,要带[]号
mask        掩膜,是一个大小和image一样的np数组,其中把需要处理的部分指定为1,不需要处理的部分指定为0,一般设置为None,表示处理整幅图像
histSize        灰度级的个数,使用多少个bin,一般为256,要带[]号
ranges        像素值的范围,一般为[0,255],要带[]号

二、视频分镜

 (人工分镜结果)

1、基于均值哈希 运行结果:

 (少识别了两个分镜头,误识别了三个分镜头) 

 完整代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 均值哈希算法
def aHash(img):
    # 缩放为8*8
    plt.imshow(img)
    plt.axis('off')  
    plt.show()
    img = cv2.resize(img, (8, 8))
    plt.imshow(img)
    plt.axis('off') 
    plt.show()
    # 转换为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # s为像素和初值为0,hash_str为hash值初值为''
    s = 0
    hash_str = ''
    # 遍历累加求像素和
    for i in range(8):
        for j in range(8):
            s = s + gray[i, j]
    # 求平均灰度
    avg = s / 64
    # 灰度大于平均值为1相反为0生成图片的hash值
    for i in range(8):
        for j in range(8):
            if gray[i, j] > avg:
                hash_str = hash_str + '1'
            else:
                hash_str = hash_str + '0'
    return hash_str

# Hash值对比
def cmpHash(hash1, hash2):
    n = 0
    print(hash1)
    print(hash2)
    # hash长度不同则返回-1代表传参出错
    if len(hash1)!=len(hash2):
        return -1
    # 遍历判断
    for i in range(len(hash1)):
        # 不相等则n计数+1,n最终为相似度
        if hash1[i] != hash2[i]:
            n = n + 1
    return n

for i in range(549):
    img1=cv2.imread('./pic2/image{}.jpg'.format(i)) 
    img2=cv2.imread('./pic2/image{}.jpg'.format(i+1)) 
    hash1 = aHash(img1)
    hash2 = aHash(img2)
    n = cmpHash(hash1, hash2)
    if(n>22):
        print('均值哈希算法相似度:', n/64)
        cv2.imwrite('./shot/image{}.jpg'.format(i+1),img2)

2、基于直方图相似度 运行结果:

(少识别了两个分镜头) 

完整代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 通过得到RGB每个通道的直方图来计算相似度
def classify_hist_with_split(image1, image2, size=(256, 256)):
    # 将图像resize后,分离为RGB三个通道,再计算每个通道的相似值
    image1 = cv2.resize(image1, size)
    image2 = cv2.resize(image2, size)
    plt.imshow(image1)
    plt.show()
    plt.axis('off')
    
    plt.imshow(image2)
    plt.show()
    plt.axis('off')
    
    sub_image1 = cv2.split(image1)    #cv2.split()拆分通道
    sub_image2 = cv2.split(image2)
    sub_data = 0
    
    for im1, im2 in zip(sub_image1, sub_image2):
        sub_data += calculate(im1, im2)
    sub_data = sub_data / 3
    return sub_data

# 计算单通道的直方图的相似值
def calculate(image1, image2):
    hist1 = cv2.calcHist([image1], [0], None, [256], [0.0, 255.0])
    hist2 = cv2.calcHist([image2], [0], None, [256], [0.0, 255.0])
    plt.plot(hist1, color="r")
    plt.plot(hist2, color="g")
    plt.show()
    # 计算直方图的重合度
    degree = 0
    for i in range(len(hist1)):
        if hist1[i] != hist2[i]:
            degree = degree + (1 - abs(hist1[i] - hist2[i]) / max(hist1[i], hist2[i]))
        else:
            degree = degree + 1    #统计相似
    degree = degree / len(hist1)
    return degree

for i in range(549):
    img1=cv2.imread('./pic2/image{}.jpg'.format(i)) 
    img2=cv2.imread('./pic2/image{}.jpg'.format(i+1)) 
    n = classify_hist_with_split(img1,img2)
    if(n<0.6):
        cv2.imwrite('./shot2/image{}.jpg'.format(i+1),img2)

三、截取视频(1分钟) 完整代码:

截取视频前一分钟:

ffmpeg  -i input.mp4 -vcodec copy -acodec copy -ss 00:00:00 -to 00:01:00 cut.mp4 -y 

截取视频中间一分钟:

ffmpeg  -i input.mp4 -vcodec copy -acodec copy -ss 00:00:05 -t 00:01:00 cut.mp4 -y

或ffmpeg -i input.mp4 -ss 5 -c copy -t 60 cut.mp4 -y

参数含义:

-to        截到视频的哪个时间点结束

-t         表示截取多长的时间

-vcodec copy        表示使用跟原视频一样的视频编解码器

-acodec copy        表示使用跟原视频一样的音频编解码器

问题记录:

ffmpeg 为了加速,会使用关键帧技术(-ss 选项放在 -i 之前时), 有时剪切出来的结果在起止时间上未必准确,解决方法:ffmpeg -ss 00:01:00 -i video.mp4 -to 00:02:00 -c copy -copyts cut.mp4

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/339869.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号