视频帧的黑、花屏的检测是视频质量检测中比较重要的一部分,传统做法是由测试人员通过肉眼来判断视频中是否有黑、花屏的现象,这种方式不仅耗费人力且效率较低。为了进一步节省人力、提高效率,一种自动的检测方法是大家所期待的。目前,通过分类网络模型对视频帧进行分类来自动检测是否有黑、花屏是比较可行且高效的。然而,在项目过程中,视频帧数据的收集比较困难,数据量较少,部分花屏和正常屏之间差异不够明显,导致常用的分类算法难以满足项目对分类准确度的要求。因此本文尝试了一种利用目标检测算法实现分类的方式,帮助改善单纯的分类的算法效果不够理想的问题。

核心技术与架构图

一般分类任务的流程如下图,首先需要收集数据,构成数据集;并为每一类数据定义一个类型标签,例如:0、1、2;再选择一个合适的分类网络进行分类模型的训练,图像分类的网络有很多,常见的有VggNet, ResNet,DenseNet等;最后用训练好的模型对新的数据进行预测,输出新数据的类别。

900×116 38.7 KB

目标检测任务的流程不同于分类任务,其在定义类别标签的时候还需要对目标位置进行标注;目标检测的方法也有很多,例如Fast R-CNN, SSD,YOLO等;模型训练的中间过程也比分类模型要复杂,其输出一般为目标的位置、目标置信度以及分类结果。

900×120 46.2 KB

由于分类算法依赖于一定量的数据,在项目实践中,数据量较少或图像类间差异较小时,传统分类算法效果不一定能满足项目需求。这时,不妨考虑用目标检测的方式来做‘分类’。接下来以Yolov5为例来介绍如何将目标检测框架用于实现单纯的分类任务。

技术实现

除了分类之外,目标检测还可以从自然图像中的大量预定义类别中识别出目标实例的位置。大家可能会考虑目标检测模型用于分类是不是过于繁琐或者用目标检测框架来做单纯的分类对代码的修改比较复杂。这里,我们将用一种非常简单的方式直接在数据标注和输出内容上稍作修改就能实现单纯的分类了。接下来将介绍一下具体实现方法:

no.1

数据的标注

OBJECT_DICT = {"Normalscreen": 0, "Colorfulscreen": 1, "Blackscreen": 2}
def parse_json_file(image_path):imageName = os.path.basename(image_path).split('.')[0]img = cv2.imread(image_path)size = img.shapelabel = image_path.split('/')[4].split('\\')[0]label = OBJECT_DICT.get(label)imageWidth = size[0]imageHeight = size[1]label_dict = {}xmin, ymin = (0, 0)xmax, ymax = (imageWidth, imageHeight)xcenter = (xmin + xmax) / 2xcenter = xcenter / float(imageWidth)ycenter = (ymin + ymax) / 2ycenter = ycenter / float(imageHeight)width = ((xmax - xmin) / float(imageWidth))heigt = ((ymax - ymin) / float(imageHeight))label_dict.update({label: [str(xcenter), str(ycenter), str(width), str(heigt)]})label_dict = sorted(label_dict.items(), key=lambda x: x[0])return imageName, label_dict

no.2

训练过程

# 加载数据,获取训练集、测试集图片路径
with open(opt.data) as f:data_dict = yaml.load(f, Loader=yaml.FullLoader)  with torch_distributed_zero_first(rank):check_dataset(data_dict)
train_path = data_dict['train']
test_path = data_dict['val']
Number_class, names = (1, ['item']) if opt.single_cls else (int(data_dict['nc']), data_dict['names']) # 创建模型
model = Model(opt.cfg, ch=3, nc=Number_class).to(device)# 学习率的设置
lf = lambda x: ((1 + math.cos(x * math.pi / epochs)) / 2) * (1 - hyp['lrf']) + hyp['lrf']
scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lf)# 训练
for epoch in range(start_epoch, epochs):
model.train()

no.3

损失的计算

def compute_loss(p, targets, model):device = targets.deviceloss_cls, loss_box, loss_obj = torch.zeros(1, device=device), torch.zeros(1, device=device), torch.zeros(1, device=device)tcls, tbox, indices, anchors = build_targets(p, targets, model)
h = model.hyp# 定义损失函数BCEcls = nn.BCEWithLogitsLoss(pos_weight=torch.Tensor([h['cls_pw']])).to(device)BCEobj = nn.BCEWithLogitsLoss(pos_weight=torch.Tensor([h['obj_pw']])).to(device)cp, cn = smooth_BCE(eps=0.0)# 损失nt = 0  np = len(p) balance = [4.0, 1.0, 0.4] if np == 3 else [4.0, 1.0, 0.4, 0.1]
for i, pi in enumerate(p): image, anchor, gridy, gridx = indices[i]  tobj = torch.zeros_like(pi[..., 0], device=device) n = image.shape[0]  if n:nt += n  # 计算目标ps = pi[anchor, image, gridy, gridx]pxy = ps[:, :2].sigmoid() * 2. - 0.5pwh = (ps[:, 2:4].sigmoid() * 2) ** 2 * anchors[i]predicted_box = torch.cat((pxy, pwh), 1).to(device)                     giou = bbox_iou(predicted_box.T, tbox[i], x1y1x2y2=False, CIoU=True)                 loss_box += (1.0 - giou).mean() tobj[image, anchor, gridy, gridx] = (1.0 - model.gr) + model.gr *   giou.detach().clamp(0).type(tobj.dtype) if model.nc > 1:t = torch.full_like(ps[:, 5:], cn, device=device)t[range(n), tcls[i]] = cploss_cls += BCEcls(ps[:, 5:], t)  loss_obj += BCEobj(pi[..., 4], tobj) * balance[i]  s = 3 / nploss_box *= h['giou'] * sloss_obj *= h['obj'] * s * (1.4 if np == 4 else 1.)loss_cls *= h['cls'] * sbs = tobj.shape[0]loss = loss_box + loss_obj + loss_clsreturn loss * bs, torch.cat((loss_box, loss_obj, loss_cls, loss)).detach()

no.4

对输出内容的处理

def detect(opt,img):out, source, weights, view_img, save_txt, imgsz = \opt.output, img, opt.weights, opt.view_img, opt.save_txt, opt.img_sizedevice = select_device(opt.device)half = device.type != 'cpu'model = experimental.attempt_load(weights, map_location=device)imgsz = check_img_size(imgsz, s=model.stride.max())if half:model.half()img = letterbox(img)[0]img = img[:, :, ::-1].transpose(2, 0, 1)img = np.ascontiguousarray(img)img_warm = torch.zeros((1, 3, imgsz, imgsz), device=device)_ = model(img_warm.half() if half else img_warm) if device.type != 'cpu' else None img = torch.from_numpy(img).to(device)img = img.half() if half else img.float()img /= 255.0if img.ndimension() == 3:img = img.unsqueeze(0)pred = model(img, augment=opt.augment)[0]# 应用非极大值抑制pred = non_max_suppression(pred, opt.conf_thres, opt.iou_thres, classes=opt.classes, agnostic=opt.agnostic_nms)# 处理检测的结果for i, det in enumerate(pred): if det is not None and len(det):det[:, :4] = scale_coords(img.shape[2:], det[:, :4], img.shape).round()all_conf = det[:, 4]if len(det[:, -1]) > 1:ind = torch.max(all_conf, 0)[1]c = torch.take(det[:, -1], ind)
detect_class = int(c)else:for c in det[:, -1]:detect_class = int(c)return detect_class

效果展示

为了将视频帧进行黑、花屏分类,测试人员根据经验将屏幕分为正常屏(200张)、花屏(200张)和黑屏(200张)三类,其中正常屏幕标签为0,花屏的标签为1,黑屏的标签为2。

为了进一步说明该方法的有效性,我们将基于Yolov5的‘分类’效果与ResNet分类效果做了对比。根据测试人员对ResNet分类效果的反馈来看,ResNet模型容易将正常屏与花屏错误分类,例如,下图被测试人员定义为正常屏:

ResNet的分类结果为1,即为花屏,显然,这不是我们想要的结果。

基于Yolov5的分类结果为0,即为正常屏,这是我们所期待的结果。

同时,通过对一批测试数据的分类效果来看,Yolov5的分类效果比ResNet的分类准确度更高,ResNet的分类准确率为88%,而基于Yolov5的分类准确率高达97%。

总 结

对于较小数据集的黑、花屏的分类问题,采用Yolov5来实现分类相较于ResNet的分类效果会更好一些。当我们在做图像分类任务时,纯粹的分类算法不能达到想要的效果时,不妨尝试一下用目标检测框架来分类吧!虽然过程稍微复杂一些,但可能会有不错的效果。目前目标检测框架有很多,用它们完成分类任务的处理方式大致和本文所描述的类似,可以根据数据集的特征选择合适目标检测架构来实现分类。本文主要介绍了如何将现有的目标检测框架直接用于单纯的图像分类任务,当然,为了使得结构更简洁,也可以将目标检测中的分类网络提取出来用于分类。

软件测试 | 测试开发 | 一种基于目标检测实现黑花屏分类任务的方案相关推荐

  1. 一种基于目标检测实现黑花屏分类任务的方案

    背 景 视频帧的黑.花屏的检测是视频质量检测中比较重要的一部分,传统做法是由测试人员通过肉眼来判断视频中是否有黑.花屏的现象,这种方式不仅耗费人力且效率较低.为了进一步节省人力.提高效率,一种自动的检 ...

  2. 目标检测实现黑花屏分类任务

    视频帧的黑.花屏的检测是视频质量检测中比较重要的一部分,传统做法是由测试人员通过肉眼来判断视频中是否有黑.花屏的现象,这种方式不仅耗费人力且效率较低.为了进一步节省人力.提高效率,一种自动的检测方法是 ...

  3. 软件测试 | 测试开发 | 一种基于视频帧差异视频卡顿检测方案

    背景 在视频质量检测中,检测视频是否卡顿也属于视频质量检测的标准之一,在构建视频检测平台中,这一步至关重要. 本文要说明的是把视频转换为帧序列,根据计算帧之间的差值,寻找帧序列中是否有断层,来判断当前 ...

  4. 软件测试 | 测试开发 | 一种能有效缓解环境噪声对音频质量干扰的方案

    背景 随着数字技术的发展,我们的生活越来越离不开音频,对音频使用和呈现方式也越来越多样化,人们也从去单纯的听录制好的音频转向录制属于自己的音频,例如录歌.会议录音.录制短视频等.我们这些音频是高质量, ...

  5. 软件测试 | 测试开发 | 一种通过云配置处理应用权限弹框的方案

    背景 在兼容性测试中,对于一个App进行兼容性测试,需要安装,冷启动,热启动,卸载四个步骤,在这四个步骤都正确的情况下,才确定App兼容这款手机. 在国内,Android手机的型号,品牌有很多,各个品 ...

  6. 基于目标检测的海上舰船图像超分辨率研究

    基于目标检测的海上舰船图像超分辨率研究 人工智能技术与咨询 来源:< 图像与信号处理> ,作者张坤等 关键词: 目标检测:生成对抗网络:超分辨率 摘要: 针对海上舰船图像有效像素在整体像素 ...

  7. 目标检测实战:4种YOLO目标检测的C++和Python两种版本实现

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨nihate 审稿丨邓富城 编辑丨极市平台 导读 本文作者使用C++编写一套基于OpenCV的Y ...

  8. 何恺明大神新作:一种用于目标检测的主流ViT架构,效果SOTA

    链接:https://arxiv.org/abs/2203.16527 作者单位:Facebook AI Research 1导读 3月30日,何恺明大神团队在ArXiv上发布了最新研究工作,该工作主 ...

  9. 【深度学习】目标检测实战:4种YOLO目标检测的C++和Python两种版本实现

    作者丨nihate 审稿丨邓富城 编辑丨极市平台 导读 本文作者使用C++编写一套基于OpenCV的YOLO目标检测,包含了经典的YOLOv3,YOLOv4,Yolo-Fastest和YOLObile ...

最新文章

  1. PMcaff微课堂 | 洋葱淘elya妞,前百度UX Leader:独门创业经验,产品秘籍
  2. mysql 日期 时间戳 转换
  3. nginx添加第三方模块,以及启用nginx本身支持的模块
  4. Docker多主机安装Zookeeper集群
  5. 重装系统后删除Cygwin的安装文件
  6. 计算机设计大赛安徽农业大学经济技术学院,信息与计算机系开展“学习‘学生违纪处分办法’”主题班会活动总结...
  7. Mysql多源复制半同步_MySQL多源复制搭建
  8. 有关C#中的引用类型的内存问题
  9. nodejs实战案例(Express框架+mongoDB)——(15)——爬虫功能
  10. Angularjs的真分页,服务端分页,后台分页的解决方案
  11. canvas实现点连线动画
  12. [Windows] 专业的家谱族谱制作软件My Family Tree v10.3.4
  13. matlab画五棱柱
  14. spring boot(四):thymeleaf使用详解
  15. 如何判断List 集合和Map 集合是否为空
  16. 实时数仓到底是什么呢?与传统数仓有什么区别?
  17. C语言打开微信提示找不到文件,电脑提示系统找不到指定文件怎么办?
  18. 刘强东:B2C电商本质在于娇惯消费者
  19. python可以做二维码吗_Python制作二维码真的这么简单?
  20. 点聚weboffice打开服务器文件,对点聚weboffice插件的使用说明

热门文章

  1. QPainter绘制图片填充方式(正常大小、剪切大小、自适应大小、平铺)
  2. c语言while的作用范围,C语言中While语句使用规则
  3. 神经网络算法可以用来干什么
  4. oracle repeatable read,Oracle和Mysql中的数据库事务有关问题:Mysql Read-Repeatable有有关问题...
  5. Python color logging
  6. echarts legend 排列问题
  7. C语言输入输出函数的返回值(超详细)
  8. Linux(二十)服务器网络知识- 网络配置
  9. 陈经纶2021年高考成绩查询时间,陈经纶中学2020年高考成绩
  10. a标签download属性不起作用