Opencv——视频融合及人物影像探测

这篇具有很好参考价值的文章主要介绍了Opencv——视频融合及人物影像探测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

【知识点】
视觉处理技术结合模式识别方法。

【素材准备】
准备视频A和视频B。
其中 视频A 是网上下载的风景区的视频录制(如张家界、武夷山或五大名山之一)。
视频B是个人在白墙或纯色背景前的行走视频。

【要求】
(i)通过阈值方法,结合OPENCV的与或运算,将视频B的个人影像(消除背景后)融入视频A,得到视频C。(50%)
(ii)设计一种特征值,使得个人的影像能在图像中被探测到。 (20%)
(iii)利用 (ii) 的特征值计算方法,在视频C中找出个人在每帧中的位置,用矩形绘出大致位置(30%)


一、视频准备及函数定义

import os
import cv2
import matplotlib.pyplot as plt

os.chdir('C:/Users/Bert/PycharmProjects/模式识别与计算机视觉/实验三/video/')

# 定义视频路径
A_video = "A_3.mp4"  # 背景视频
B_video = "B_5.mp4"  # 人物视频
result_video = "A3_mingle_B5.mp4"  # 输出视频

# Define the codec and create VideoWriter object
cap_A = cv2.VideoCapture(A_video)  # 读取视频A
cap_B = cv2.VideoCapture(B_video)  # 读取视频B

fps_video_A = cap_A.get(cv2.CAP_PROP_FPS)  # 获取视频A帧率
fps_video_B = cap_B.get(cv2.CAP_PROP_FPS)  # 获取视频B帧率

fourcc = cv2.VideoWriter_fourcc(*"mp4v")  # 设置写入视频的编码格式

width_A = int(cap_A.get(cv2.CAP_PROP_FRAME_WIDTH))  # 获取视频A宽度
width_B = int(cap_B.get(cv2.CAP_PROP_FRAME_WIDTH))  # 获取视频B宽度

height_A = int(cap_A.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 获取视频A高度
height_B = int(cap_B.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 获取视频B高度

roi_width = int((width_A - width_B) / 2)  # 人物视频在背景视频起始宽度
roi_height = int((height_A - height_B) / 2)  # 人物视频在背景视频起始高度

videoWriter = cv2.VideoWriter(result_video, fourcc, fps_video_A, (width_A, height_A))  # 保存视频

print("视频A的宽度:{}  视频A的高度:{}  视频A的帧率:{}".format(width_A, height_A, fps_video_A))
print("视频B的宽度:{}  视频B的高度:{}  视频B的帧率:{}".format(width_B, height_B, fps_video_B))


## 去除视频的水印
def process_watermarkn(image):
    # 需要注意的是第一个范围是y轴坐标的范围,第二个是x轴坐标的范围
    image[140:220, 0:255] = image[140 - 80:220 - 80, 0:255]
    return image

## 视频融合
def video_mingle(frame_g, frame_m):
    ## 1. 根据背景大小提取感兴趣区域roi
    # 把人物放在背景视频中心位置,提取原图中要放置人物的区域roi
    rows, cols = frame_m.shape[:2]
    roi = frame_g[roi_height:rows + roi_height, roi_width:cols + roi_width]
    ## 2. 创建掩膜mask:用一副二值化图片对另外一幅图片进行局部的遮挡。
    img2gray = cv2.cvtColor(frame_m, cv2.COLOR_BGR2GRAY)  # 将图片灰度化,如果在读取人物时直接灰度化,该步骤可省略
    # cv2.THRESH_BINARY:如果一个像素值低于200,则像素值转换为255(白色色素值),否则转换成0(黑色色素值)
    # 即有内容的地方为黑色0,无内容的地方为白色255.
    # 白色的地方还是白色,除了白色的地方全变成黑色
    ret, mask = cv2.threshold(img2gray, 190, 255, cv2.THRESH_BINARY)  # 阙值操作
    mask_inv = cv2.bitwise_not(mask)  # 与mask颜色相反,白色变成黑色,黑变白
    ## 3. 人物与感兴趣区域roi融合
    # 保留除人物外的背景
    img1_bg = cv2.bitwise_and(roi, roi, mask=mask)
    img2_fg = cv2.bitwise_and(frame_m, frame_m, mask=mask_inv)
    dst = cv2.add(img1_bg, img2_fg)  # 人物与感兴趣区域roi进行融合
    frame_g[roi_height:rows + roi_height, roi_width:cols + roi_width] = dst  # 将融合后的区域放进原图
    img_new = frame_g.copy()  # 对处理后的图像进行拷贝
    return img2gray, mask, mask_inv, roi, img1_bg, img2_fg, dst, img_new


## cv2与matplotlib的图像颜色模式转换,cv2是BGR格式,matplotlib是RGB格式
def img_convert(cv2_img):
    # 灰度图片直接返回
    if len(cv2_img.shape) == 2:
        return cv2_img
    # 3通道的BGR图片
    elif len(cv2_img.shape) == 3 and cv2_img.shape[2] == 3:
        b, g, r = cv2.split(cv2_img)  # 分离原图像通道
        return cv2.merge((r, g, b))  # 合并新的图像通道
    # 4通道的BGR图片
    elif len(cv2_img.shape) == 3 and cv2_img.shape[2] == 4:
        b, g, r, a = cv2.split(cv2_img)
        return cv2.merge((r, g, b, a))
    # 未知图片格式
    else:
        return cv2_img

二、视频融合和抽取融合中视频帧变化过程

抽取第一张图片查看融合中视频帧变化过程,其余则根据cap_A.isOpened() & cap_B.isOpened()都为True条件下进行视频融合。

frame_id = 0
while cap_A.isOpened() & cap_B.isOpened():
    ret_A, frame_A = cap_A.read()  # 背景视频
    ret_B, frame_B = cap_B.read()  # 人物视频
    if ret_A == True & ret_B == True:
        frame_id += 1
        ## 抽取融合中视频帧变化过程
        if frame_id == 1:
            frame_B = process_watermarkn(frame_B)
            capture_new = video_mingle(frame_A, frame_B)
            titles = ['B', 'B_gray', 'B_mask', 'B_mask_inv', 'roi', 'img1_bg', 'img2_fg', 'dst']
            imgs = [frame_B, capture_new[0], capture_new[1], capture_new[2], capture_new[3], capture_new[4],
                    capture_new[5], capture_new[6]]
            for i in range(len(imgs)):
                plt.subplot(2, 4, i + 1), plt.imshow(img_convert(imgs[i]), 'gray')
                plt.title(titles[i])
                plt.xticks([]), plt.yticks([])
            plt.show()
            plt.close()
            continue
        ## 视频A和视频B融合过程
        else:
            frame_B = process_watermarkn(frame_B)
            img_new_add = video_mingle(frame_A, frame_B)[-1]
            videoWriter.write(img_new_add)
    else:
        break

# Release everything if job is finished
cap_A.release()
cap_B.release()
videoWriter.release()
cv2.destroyAllWindows()

结果如下:

原A.mp4:
Opencv——视频融合及人物影像探测

原B.mp4:
Opencv——视频融合及人物影像探测

A_mingle_B.mp4:
Opencv——视频融合及人物影像探测
视频帧变化过程:
Opencv——视频融合及人物影像探测参考链接:
OpenCV_Python官方文档7+——按位运算之给图像加logo

三、人物影像探测

将以上得到的融合视频进行特征检测,使得个人的影像能在图像中被探测到。 在视频中找出个人在每帧中的位置,用矩形绘出大致位置。

import cv2

#定义视频路径
org_video = "./video/A3_mingle_B5.mp4"
sub_video = "./video/A3_feature_extract_B5.mp4"

# Define the codec and create VideoWriter object
cap = cv2.VideoCapture(org_video)  # 读取视频
fps_video = cap.get(cv2.CAP_PROP_FPS)# 获取视频帧率
fourcc = cv2.VideoWriter_fourcc(*"mp4v")# 设置写入视频的编码格式
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))# 获取视频宽度
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))# 获取视频高度
videoWriter = cv2.VideoWriter(sub_video, fourcc, fps_video, (width, height))#保存视频
print(width,height)


def is_inside(o, i):
    '''
    判断矩形o是不是在i矩形中

    args:
        o:矩形o  (x,y,w,h)
        i:矩形i  (x,y,w,h)
    '''
    ox, oy, ow, oh = o
    ix, iy, iw, ih = i
    return ox > ix and oy > iy and ox + ow < ix + iw and oy + oh < iy + ih


def draw_person(img, person):
    '''
    在img图像上绘制矩形框person

    args:
        img:图像img
        person:人所在的边框位置 (x,y,w,h)
    '''
    x, y, w, h = person
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)


def detect_test(img):
    hog = cv2.HOGDescriptor()
    detector = cv2.HOGDescriptor_getDefaultPeopleDetector()
    hog.setSVMDetector(detector)

    # 多尺度检测,found是一个数组,每一个元素都是对应一个矩形,即检测到的目标框
    found, w = hog.detectMultiScale(img)

    # 过滤一些矩形,如果矩形o在矩形i中,则过滤掉o
    found_filtered = []
    for ri, r in enumerate(found):
        for qi, q in enumerate(found):
            if ri != qi and is_inside(r, q):
                break
        else:
            found_filtered.append(r)

    for person in found_filtered:
        draw_person(img, person)
    return img


while cap.isOpened():
    ret, frame = cap.read()
    if ret == True:
        # HOG:对象检测与模式匹配中是一种常见的特征提取算法,是基于本地像素块进行特征直方图提取的一种算法 + SVM
        # 方向梯度直方图:计算和统计图像局部区域的梯度方向直方图来构成特征.
        frame = detect_test(frame)
        videoWriter.write(frame)
    else:
        break

# Release everything if job is finished
cap.release()
videoWriter.release()
cv2.destroyAllWindows()

结果如下:
Opencv——视频融合及人物影像探测
参考链接:HOG特征详解与行人检测

四、建议

1.视频最终效果与视频B是个人在白墙或纯色背景前的行走视频有关,最好选取白色背景明显,整个人物明显区分于白色背景的视频,如面色,衣服等。

2.通过调节阈值也可以增强实验效果,具体代码在这一步:

ret, mask = cv2.threshold(img2gray, 215, 255, cv2.THRESH_BINARY)  # 阙值操作

该代码的解释为:将灰度图中灰度值小于215的点置0,灰度值大于215的点置255。因此可以改变代码中215数值来增强视频效果。

3.注意视频尺寸:背景视频尺寸一定要大于人物视频尺寸,无论长和宽。

4.人物影像探测那里建议适当添加如下参数值获取更好效果,但会增加检测时延:

found, w = hog.detectMultiScale(img)                                          

如以下参数值winStride=(4, 4), padding=(8, 8), scale=1.25, useMeanshiftGrouping=False。具体用法可以搜索 hog.detectMultiScale()用法

视频文件及代码链接:
https://pan.baidu.com/s/1XVcz9U_M9vLfr4k_4JMJhg?pwd=lkqd
提取码:lkqd文章来源地址https://www.toymoban.com/news/detail-405853.html

到了这里,关于Opencv——视频融合及人物影像探测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【OpenCV+Tkinter项目】同学,你要的OpenCV图像处理小系统已安排,终于有人把OpenCV那些必备的知识点讲透彻了~(太厉害了,已跪)

    OpenCV – 开源计算机视觉 。它是计算机视觉和图像处理任务中使用最广泛的工具之一。它被 用于各种应用,如面部检测、视频捕捉、跟踪移动物体、对象公开。如今应用在 Covid 中,如 口罩检测、社交距离等等。 今天让我们从零开始学习 OpenCV的入门小知识吧!🙌 粉丝白嫖源

    2024年02月01日
    浏览(25)
  • 使用Python基于opencv实现多视频画面拼接融合算法demo

    单个相机视频画面尺寸有限,在需要全景展示的场景下,就需要将多个相机视频进行拼接融合,得到一张全景图。本文基于opencv实现一个视频拼接的demo,熟悉视频拼接流程和opencv接口。 直接上代码吧,注释还是比较清楚的: 该demo使用ORB算法检测关键点,使用BFMatcher进行特征

    2024年02月04日
    浏览(39)
  • opencv -10 基础运算之 图像加权和(图像融合&图像修复&视频合成)

    所谓图像加权和,就是在计算两幅图像的像素值之和时,将每幅图像的权重考虑进来,可以用公式表示为: 式中,saturate()表示取饱和值(最大值)。图像进行加权和计算时,要求 src1 和 src2 必须大小、类型相同 ,但是对具体是什么类型和通道没有特殊限制。它们可以是任意

    2024年02月16日
    浏览(35)
  • c#多线程—基础概念到“双色球”项目实现(附知识点目录、代码、视频)

    总结:视频中对于多线程讲的非常透彻,从线程基础概念—.net不同版本出现的线程方法—多线程常出现问题—双色球项目实践,每个知识点都有代码实操,受益匪浅。附上学习笔记和实操代码。 视频 线程:程序执行的最小单位,任何操作都是由线程完成的,使用同步时,资

    2024年02月11日
    浏览(39)
  • 人工智能与医疗影像的互动与融合

    2023年08月22日
    浏览(40)
  • 【ArcGIS Pro微课1000例】0027:高分卫星全色影像与多光谱影像融合提高分辨率教程

    本文讲解ArcGIS Pro中图像增强:高分卫星影像融合(全色影像+多光谱影像)操作案例教程。 图像融合是指将不同类型传感器的影像进行融合,既能使图向具有较高的空间分辨率,又具有多光谱的特性。除了遥感软件如Erdas、Envi等能进行图像融合,ArcGIS及ArcGIS Pro软件也可以进行

    2024年02月16日
    浏览(33)
  • 【探测器】opencv显示探测器的raw图像

    对于探测器(相对于可见光成像的相机,这里的探测器指的是对X光成像的相机)。 RAW文件几乎是未经过处理而直接从CCD或CMOS上得到的信息。 RAW格式是无损格式,相比于JPG格式,RAW格式的好处有很多,它会记录下成像的的所有细节,这些细节在后期您可以根据场景进行修改。

    2024年02月07日
    浏览(35)
  • C# &OpenCV 从零开发(0):前言

    由于我想换个机器视觉+运动控制的工作,我就开始了自学机器视觉方向的技术。但是Halcon毕竟是商业化的库,国内用盗版还是怕被告。所以期望使用OpenCV。 OpenCV目前已知的方法的有两个版本 Python:用起来挺简单的,就是Python的语言不适合管理,感觉以后必定会出现问题,不适

    2024年01月18日
    浏览(51)
  • OpenCV基础知识(9)— 视频处理(读取并显示摄像头视频、播放视频文件、保存视频文件等)

    前言: Hello大家好,我是小哥谈。 OpenCV不仅能够处理图像,还能够处理视频。视频是由大量的图像构成的,这些图像是以固定的时间间隔从视频中获取的。这样,就能够使用图像处理的方法对这些图像进行处理,进而达到处理视频的目的。要想处理视频,需要先对视频进行读

    2024年02月11日
    浏览(45)
  • 《数字图像处理-OpenCV/Python》连载(1)前言

    本书京东优惠购书链接:https://item.jd.com/14098452.html 写作背景 编写本书的初衷,源自作者学习数字图像处理的经历。 在创新实验班开设的专业创新教育课程中,我选择的是数字图像处理方向。老师向我推荐的教材是冈萨雷斯的《数字图像处理》。学习的开始阶段非常困难。教

    2024年02月11日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包