【opencv】获取视频中的“黑白蓝绿”屏
【诉求】
长视频文件中,检测异常画面帧出现的次数以及截图报错,替代人工检查(附代码)
【学习】
方案一:像素点:(height, width, channels)
方案二:二级图:RGB/HSV颜色
> 颜色区间:https://blog.csdn.net/qq78442761/article/details/83056346# 定义灰色识别模型
lower_orange = np.array([0, 0, 100])
upper_orange = np.array([180, 43, 220])
> opencv导入:
import cv2
import numpy as np
from numpy import array
灰屏:
1.RGB与HSB颜色,灰色是一个区域范围
2.cv将灰度图像二值化
3.计算灰色轮廓的模型
4.根据张数计算图片发生的时刻
【实现顺序】
- 传入待测文件:mp4、mp3
- 对视频文件进行切割/每帧,变成对图片的处理
- 关于如何获取文件时长
- 关于获取到问题帧/区间:通过像素点占比以及数组区间范围判定
- 如何定位时间戳(相对时间点)
- 自动化定位/对比、打印信息
【拓展运用】
一个回放文件里,灰屏帧在的时间戳以及统计次数
复现设备概率性出现绿屏或者闪现绿屏等,截图并获取全屏信息
【代码】方案一
def test_video_opencv(url):start_time_1 = time.time()# 将切割的文件进行cp和moverm_cmd = "rm -rf ./tmp/*.png *.txt"os.popen(rm_cmd).read()pre_cmd1 = "mkdir tmp"os.popen(pre_cmd1).read()make_file_cmd = "touch video_tmp.txt"os.popen(make_file_cmd).read()file = open('./video_tmp.txt', 'w', encoding='utf-8')# 将视频转化成数据帧-调试start_time = time.time()cmd = "ffmpeg -i " + url + " -r 2 -s 1080,960 -ss 00:00:00 ./tmp/%d.png"print(cmd)os.popen(cmd).read()end_time = time.time()file.write("切割耗时:" + str(end_time-start_time) + "\n\n")info_cmd = "ffprobe -v quiet -print_format json -show_format -show_streams " + urldata_json = os.popen(info_cmd).read()# 获取文件时长d = json.loads(data_json)duration = d["format"]["duration"]file.write("视频总时长:" + str(duration) + "\n\n")pic_len = len(os.listdir("../tmp"))file.write("切割视频图片个数:"+str(pic_len) + "\n\n")start_time = time.time()for png_num in range(1,pic_len):img = cv2.imread("./tmp/" + str(png_num) + ".png")# gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 转换了灰度化# ret, img = cv2.threshold(gray, 160, 255, cv2.THRESH_BINARY) # 将灰度图像二值化# img = 255 - img# 定义灰色识别模型lower_orange = np.array([0, 0, 100])upper_orange = np.array([180, 43, 220])#RGB 转 HSV 颜色模型hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)# 低于lower_orange/高于upper_orange的值,图像值为0# 在此之间的值变成255,即涂白色mask = cv2.inRange(hsv, lower_orange, upper_orange)# cv2.imshow('image', mask)# cv2.waitKey(0)binary = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)[1] # 将灰度图像二值化binary = cv2.dilate(binary, None, iterations=2) # 图像膨胀# cv2的版本不同,findContours的返回值个数也不一样,此处是为了兼容不同版本if int(cv2.__version__[0]) > 2:contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)else:_, contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 3-求轮廓的面积pic_sum = 0space = img.shape[0] * img.shape[1]for cts in contours:pic_sum += cv2.contourArea(cts)print(pic_sum/space)if pic_sum / space > 0.8: # 这里假定是80%,file.write("第 " + str(png_num) + " 张图片灰屏,在第 " + str(float(duration)/pic_len * png_num) + " 秒, 灰屏面积占比:" + str(pic_sum / space) + "\n\n")end_time = time.time()file.write("循环判断耗时:"+ str(end_time - start_time) + "\n\n")end_time_1 = time.time()file.write("总耗时:" + str(end_time_1 - start_time_1) + "\n\n")
【代码】方案二
def test_video_pixel(url):# 将切割的文件进行cp和moverm_cmd = "rm -rf ./tmp/*.png"os.popen(rm_cmd).read()pre_cmd1 = "mkdir tmp"os.popen(pre_cmd1).read()make_file_cmd = "touch video_tmp.txt"os.popen(make_file_cmd).read()file = open('./video_tmp.txt', 'w', encoding='utf-8')# 将视频转化成数据帧-调试lcmd = "ffmpeg -i " + url + " -r 1 -s 1080,960 -ss 00:00:00 ./tmp/%03d.png"os.popen(cmd).read()info_cmd = "ffprobe -v quiet -print_format json -show_format -show_streams " + urldata_json = os.popen(info_cmd).read()# 获取文件时长d = json.loads(data_json)duration = d["format"]["duration"]file.write("视频总时长:" + str(duration) + "\n\n")pic_len = len(os.listdir("../tmp"))# 循环将每张图片转换为numpy数组for png_num in range(1,pic_len+1):start_time = time.time()im = array(Image.open("./tmp/00" + str(png_num) +".png").convert("RGB"))image_arr = np.array(im)img_red = image_arr[:, :, 0]height, width = img_red.shapepic_num = 0gray_pic_sum = 0black_pic_sum = 0green_pic_sum = 0for i in range(0, height):for j in range(0, width):# 判断每一点的像素值 == 灰色,有多少个gray_pic_sum += 1black_pic_sum += 1green_pic_sum += 1if (image_arr[i, j,] == [140, 143, 146]).all():gray_pic_sum = gray_pic_sum + 1if (image_arr[i, j,] == [0, 0, 0]).all():black_pic_sum = black_pic_sum + 1if (image_arr[i, j,] == [40, 220, 60]).all():green_pic_sum = green_pic_sum + 1file.write("第 " + str(png_num) + " 张图片,一共 " + str(gray_pic_sum) + " 个灰色像素点,共 " + str(gray_pic_sum) + " 个像素点 \n\n")file.write("第 " + str(png_num) + " 张图片,一共 " + str(black_pic_sum) + " 个黑色像素点,共 " + str(black_pic_sum) + " 个像素点 \n\n")file.write("第 " + str(png_num) + " 张图片,一共 " + str(green_pic_sum) + " 个绿色像素点,共 " + str(black_pic_sum) + " 个像素点 \n\n")# 计算问题图片的时长if pic_num/gray_pic_sum >= 0.2:file.write("!! 第 " + str(png_num) + " 是灰屏问题帧,时长是:" + str(float(duration)/pic_len * png_num) + " \n\n")if pic_num/black_pic_sum >= 0.2:file.write("!! 第 " + str(png_num) + " 是黑屏问题帧,时长是:" + str(float(duration)/pic_len * png_num) + " \n\n")if pic_num/green_pic_sum >= 0.2:file.write("!! 第 " + str(png_num) + " 是绿屏问题帧,时长是:" + str(float(duration)/pic_len * png_num) + " \n\n")end_time = time.time()file.write("该帧判断像素点耗时:" + str(end_time - start_time) + "\n\n")
【效率问题】
方案一像素点判定,因为需要将每张图片像素化,建议是将1080X720P的图片裁剪到360X640P
方案二图片二级值,处理成黑白,明显效率更高,推荐~
【opencv】获取视频中的“黑白蓝绿”屏相关推荐
- 使用Python,OpenCV在视频中进行实时条形码检测
使用Python,OpenCV在视频中进行实时条形码检测 1. 步骤 2. 适用场景及优化 3. 总结 4. 源码 参考 上一篇博客介绍了如何检测和查找图像中的条形码.这篇博客将进行一些优化以检测实时 ...
- java使用FFmpeg合成视频和音频,获取视频中的音频等操作
FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序. ffmpeg命令参数如下: 参数名称 输入值 备注 -i ffmpmg -i pingcap-xxx.mp4 输 ...
- OpenCV实现视频中目标的跟踪
meanshift实现视频跟踪 import matplotlib.pyplot as plt import cv2 as cv import numpy as np plt.rcParams['fo ...
- 万字长文带你全面认识 Kubernetes 中如何实现蓝绿部署、金丝雀发布和滚动更新...
Kubernetes 中的部署策略 在本文中,我们将学习使用 Kubernetes 容器编排系统部署容器时的部署策略.在本文的最后,我们将学习如何在 Kubernetes 集群中使用不同的方式进行部署 ...
- qt6+opencv获取视频帧
QT版本:QT 6.3 OpenCV版本:opencv 4.6 编译环境:MSVC 2019 64bit 主要功能:通过OpenCV实现提取视频的单个视频帧图像或者全部视频帧图像,还可以获取视频的宽度 ...
- 解决网页在线看视频时窗口会变成绿屏问题
解决网页在线看视频时窗口会变成绿屏问题: 因为我用的win7,所以就拿win7做个例子,我们用IE打开一个有网页视频的页面,点击进去待开始播放候单击右键设置,把启用硬件加速前面的钩去掉就OK了
- 使用OpenCV为视频中美女加上眼线
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 计算机视觉是最令人兴奋的领域之一,其应用范围非常广泛.从医学成像到 ...
- 肝!使用OpenCV为视频中美女加上眼线
计算机视觉是最令人兴奋的领域之一,其应用范围非常广泛.从医学成像到创建最有趣的面部滤镜等各个领域都充分见证了计算机视觉技术的强大.在本文中,我们将尝试创建一个人造眼线笔来模仿Snapchat或Inst ...
- k8s中通过Jenkins蓝绿/灰度发布微服务
1.滚动发布 常用发布方式有蓝绿发布.灰度发布.滚动发布,由于k8s中deployment的特性,默认情况下是滚动发布,其实只要更新deployment中的镜像标签,即是滚动发布,通过spec.str ...
最新文章
- PHP如何防止XSS攻击
- 基础补充:使用xlrd模块读取excel文件
- XML指南——XML 确认
- linux php gd库安装,Linux系统gd库安装步骤说明
- C# textBox1.Append/Text实现换行
- imagick php 缩放,php使用imagick模块实现图片缩放、裁剪、压缩示例
- 数据eda_银行数据EDA:逐步
- inputstream转fileinputstream对象_FileInputStream类:文件字节输入流
- powerdesigner辅助导入导出excel文件
- C++多线程Demo
- LINUX下三个内核文件详解(vmlinuz/initrd.img/System.map)
- 免费可商用字体 超好用的德拉黑体
- class文件反编译成java文件
- SQL中的comment语法
- 飞行棋技巧:你以为想赢只需要运气吗?
- YUV2RGB Opencv
- 三年是程序员的一个坎
- 1.8.ARM裸机第八部分-按键和CPU的中断系统
- 解决mysql的赋权操作之GRANT ALL PRIVILEGES ON *.* TO ‘root‘@‘%‘ IDENTIFIED BY ‘123456‘ WITH GRANT OPTION问题
- 语音标注的具体应用场景