使用python+OpenCV实现抖音特效“蓝线挑战”

使用OpenCV实现抖音“蓝线挑战”特效。原理比较简单,当蓝线在视频画面中滑动,然后从滑过的每一帧中截取部分画面生成一幅静态图片,由于上一帧画面已经定格,那么通过调整下一帧画面可以生成各种奇怪的场景。

处理过程可分为几个步骤:

  1. 读取原始视频信息(宽、高、fps和总帧数);
  2. 计算蓝线在视频中的移动速度,横向移动:宽÷总帧数,纵向移动:高÷总帧数;
  3. 分解原视频每一帧画面,计算蓝线在当前帧中的位置;
  4. 绘制当前静态画面和蓝线;
  5. 将绘制后的画面作为帧生成视频文件。

以蓝线从左往右为例:

  1. 首先使用OpenCV读取原始视频,获取视频信息并通过视频宽与总帧数计算蓝线移动速度;
  2. 蓝线从左往右移动,当蓝线滑过第一帧,第一帧画面上滑过的部分将作为静态画面保留到下一帧。因此需要定义一个img来保留之前帧生成的画面;
  3. 当读取到下一帧画面frame后,根据当前蓝线所处位置对当前帧frame进行裁切,用裁切后的画面替换掉img上相同位置的画面。(需要注意的是image_block=frame[0:height,x:width],这里是图像高在前宽在后);
  4. 生成画面之后再使用OpenCV绘制蓝线cv2.line(img,(int(x + 3),0),(int(x + 3),height),(255,0,0),3),蓝线宽度设定为3个像素,最后将处理好的画面写入视频文件。

一、蓝线从左往右滑动:

from cv2 import cv2

#绘制静态画面和蓝线

def drawline(frame,img,x,width,height,bluelinespeed):

    bulelinelocation = int(x + bluelinespeed + 2)

    if bulelinelocation < width:

        image_block = frame[0:height,int(x):width]

        tempimg[0:height,int(x):width] = image_block

        cv2.line(img,(bulelinelocation,0),(bulelinelocation,height),(255,0,0),2)

videoCapture = cv2.VideoCapture('C:/Users/admin/Desktop/test/video/2.avi')

fps = videoCapture.get(cv2.CAP_PROP_FPS)

width = int(videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH))

height = int(videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))

totalCount = videoCapture.get(cv2.CAP_PROP_FRAME_COUNT)

size = (width,height)

bluelinespeed = width / totalCount     

videoWriter = cv2.VideoWriter('C:/Users/admin/Desktop/test/video/222.avi',cv2.VideoWriter_fourcc('X','V','I','D'),fps,size)

success,frame = videoCapture.read()

tempimg = frame

img = frame

remianing = totalCount

x = 0

while success and remianing > 0:

    x = x + bluelinespeed

    drawline(frame,img,x,width,height,bluelinespeed)

    videoWriter.write(img)

    success,frame = videoCapture.read()

    remianing -= 1

效果:

二、蓝线从右往左

from cv2 import cv2

#绘制静态画面和蓝线

def drawline(frame,img,x,width,height,bluelinespeed):

    bulelinelocation = int(x - bluelinespeed - 2)

    if bulelinelocation > 0:

        image_block = frame[0:height,0:int(x)]

        tempimg[0:height,0:int(x)] = image_block

        cv2.line(img,(bulelinelocation,0),(bulelinelocation,height),(255,0,0),2)

videoCapture = cv2.VideoCapture('C:/Users/admin/Desktop/test/video/2.avi')

fps = videoCapture.get(cv2.CAP_PROP_FPS)

width = int(videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH))

height = int(videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))

totalCount = videoCapture.get(cv2.CAP_PROP_FRAME_COUNT)

size = (width,height)

bluelinespeed = width / totalCount     

videoWriter = cv2.VideoWriter('C:/Users/admin/Desktop/test/video/222.avi',cv2.VideoWriter_fourcc('X','V','I','D'),fps,size)

success,frame = videoCapture.read()

tempimg = frame

img = frame

remianing = totalCount

x = width

while success and remianing > 0:

    x = x - bluelinespeed

    drawline(frame,img,x,width,height,bluelinespeed)

    videoWriter.write(img)

    success,frame = videoCapture.read()

    remianing -= 1

效果:

三、蓝线从上往下

from cv2 import cv2

#绘制静态画面和蓝线

def drawline(frame,img,x,width,height,bluelinespeed):

    bulelinelocation = int(x + bluelinespeed + 2)

    if bulelinelocation < height:

        image_block = frame[int(x):height,0:width]

        tempimg[int(x):height,0:width] = image_block

        cv2.line(img,(0,bulelinelocation),(width,bulelinelocation),(255,0,0),2)

videoCapture = cv2.VideoCapture('C:/Users/admin/Desktop/test/video/2.avi')

fps = videoCapture.get(cv2.CAP_PROP_FPS)

width = int(videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH))

height = int(videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))

totalCount = videoCapture.get(cv2.CAP_PROP_FRAME_COUNT)

size = (width,height)

bluelinespeed = height / totalCount     

videoWriter = cv2.VideoWriter('C:/Users/admin/Desktop/test/video/222.avi',cv2.VideoWriter_fourcc('X','V','I','D'),fps,size)

success,frame = videoCapture.read()

tempimg = frame

img = frame

remianing = totalCount

x = 0

while success and remianing > 0:

    x = x + bluelinespeed

    drawline(frame,img,x,width,height,bluelinespeed)

    videoWriter.write(img)

    success,frame = videoCapture.read()

    remianing -= 1

效果:

四、蓝线从下往上滑动:

from cv2 import cv2

#绘制静态画面和蓝线

def drawline(frame,img,x,width,height,bluelinespeed):

    bulelinelocation = int(x - bluelinespeed - 2)

    if bulelinelocation < height:

        image_block = frame[0:int(x),0:width]

        tempimg[0:int(x),0:width] = image_block

        cv2.line(img,(0,bulelinelocation),(width,bulelinelocation),(255,0,0),2)

videoCapture = cv2.VideoCapture('C:/Users/admin/Desktop/test/video/1.avi')

fps = videoCapture.get(cv2.CAP_PROP_FPS)

width = int(videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH))

height = int(videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))

totalCount = videoCapture.get(cv2.CAP_PROP_FRAME_COUNT)

size = (width,height)

bluelinespeed = height / totalCount     

videoWriter = cv2.VideoWriter('C:/Users/admin/Desktop/test/video/11.avi',cv2.VideoWriter_fourcc('X','V','I','D'),fps,size)

success,frame = videoCapture.read()

tempimg = frame

img = frame

remianing = totalCount

x = height

while success and remianing > 0:

    x = x - bluelinespeed

    drawline(frame,img,x,width,height,bluelinespeed)

    videoWriter.write(img)

    success,frame = videoCapture.read()

    remianing -= 1

效果:

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TheMatrixs

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值