如何在視頻中的對象後面添加圖像

做者|PRATEEK JOSHI 編譯|VK 來源|Analytics Vidhyapython

概述

  • 在運動物體後面添加圖像是一個典型的計算機視覺項目數組

  • 瞭解如何使用傳統的計算機視覺技術在視頻中添加logo框架

介紹

個人一位同事向我提出了一個挑戰——創建一個計算機視覺模型,能夠在視頻中插入任何圖像,而不會扭曲移動的物體。dom

如你所想,這是一個很是有趣的項目。機器學習

衆所周知,處理視頻是很困難的,由於它們是動態的。與圖像不一樣,咱們沒有能夠輕易識別和跟蹤的靜態對象。複雜性水平上升了好幾個層次——這就須要咱們對圖像處理技術和計算機視覺技術的把握。ide

我決定在背景上加個logo。我稍後將詳細說明的挑戰是,在任何給定視頻中插入一個不會妨礙對象動態特性的logo。學習

我使用Python和OpenCV構建了這個計算機視覺系統,並在本文中分享了個人方法。網站

目錄

  • 理解問題陳述ui

  • 獲取此項目的數據google

  • 爲咱們的計算機視覺項目制定藍圖

  • 在Python中實現這項技術——讓咱們添加logo!

理解問題陳述

這將是一個很是罕見的計算機視覺使用案例。咱們將在視頻中嵌入一個logo。如今你必定在想-那有什麼大不了的?咱們能夠簡單地把標誌貼在視頻上,對吧?

然而,這個標誌可能只是隱藏了一些有趣的動做在視頻中。若是標誌妨礙了前面的移動物體怎麼辦?這會看起來很low。

所以,咱們必須弄清楚如何在背景中的某個地方添加logo,這樣就不會阻止視頻中正在進行的主要操做。

下面的視頻-左半部分是原始視頻,右半部分的logo出如今舞者身後的牆上:

視頻:https://youtu.be/L9KsuvO0VMs

這是咱們將在本文中實現的想法。

獲取此項目的數據

我從pexels.com網站,一個免費的股票視頻網站。如前所述,咱們的目標是在視頻中放置一個標誌,使其出如今某個移動對象的後面。

因此,目前,咱們將使用OpenCV自己的標誌。你可使用任何你想要的標誌(也許你最喜歡的運動隊?)。

你能夠從這裏下載視頻和logo。

https://drive.google.com/file/d/1mXJtJOMTZYm-W6rQavdclbBUEuj3JL4v/view?usp=sharing

爲咱們的計算機視覺項目制定藍圖

在實施這個項目以前,咱們先了解一下這個方法。要執行此任務,咱們將藉助圖像掩碼。讓我給你看一些插圖來了解這項技術。

假設咱們要在圖像(圖2)中放置一個矩形(圖1),使第二個圖像中的圓出如今矩形的頂部:

因此,指望的結果應該是這樣的:

然而,這並非那麼簡單。當咱們從圖1中選取矩形並將其插入圖2中時,它將出如今粉色圓圈的頂部:

這不是咱們想要的。圓圈應該在矩形的前面。因此,讓咱們瞭解如何解決這個問題。

這些圖像本質上是數組。這些數組的值是像素值,每種顏色都有本身的像素值。

所以,咱們能夠將矩形的像素值設置爲1,在這裏它應該與圓重疊(在圖5中),同時保持矩形的其他像素值不變。

在圖6中,藍色虛線包圍的區域是咱們放置矩形的區域。讓咱們用R來表示這個區域。咱們也將R的全部像素值設置爲1。可是,咱們將保持整個粉色圓圈的像素值不變:

咱們的下一步是將矩形的像素值與R的像素值相乘。由於任何數字乘以1都會獲得該數字自己,因此全部R的像素值都將被矩形的像素替換。

相似地,矩形的像素值1將被圖6的像素替換。最終的結果是這樣的:

這是咱們將要使用的技術,將OpenCV標誌嵌入到視頻中背後的原理。咱們來吧!

在Python中實現這項技術

你可使用Jupyter筆記本或任何你選擇的IDE,而後繼續。咱們將首先導入必要的庫。

導入庫

import cv2
import re
import os
import random
import numpy as np
import matplotlib.pyplot as plt
from os.path import isfile, join

注意:本教程使用的OpenCV庫版本是4.0.0。

加載圖像

接下來,咱們將指定保存logo和視頻的工做目錄的路徑。請注意,你應該在下面的代碼片斷中指定「path」:

# 指定工做目錄的路徑
path = ".../"

# 讀取logo圖像
logo = cv2.imread(path+"opencv_logo.png")

# 閱讀視頻的第一幀
cap = cv2.VideoCapture(path+"Pexels Videos 2675513.mp4")
ret, frame = cap.read()

因此,咱們已經加載了logo圖像和視頻的第一幀。如今讓咱們看看這些圖像或數組的形狀:

logo.shape, frame.shape

輸出:((240, 195, 3), (1080, 1920, 3))

兩個輸出都是三維的。第一個維度是圖像的高度,第二個維度是圖像的寬度,第三個維度是圖像中的通道數,即藍色、綠色和紅色。

如今,讓咱們繪製並查看logo和視頻的第一幀:

plt.imshow(logo)
plt.show()

plt.imshow(cv2.cvtColor(frame,cv2.COLOR_BGR2RGB))
plt.show()

圖像掩碼技術

框架尺寸比logo大得多。所以,咱們能夠把logo放在許多地方。

然而,把logo放在畫面的中心對我來講彷佛是完美的,由於大部分的動做都會發生在視頻中的那個區域。所以,咱們將把logo放入框架中,以下所示:

不用擔憂標誌中的黑色背景。咱們將在稍後的代碼中將黑色區域中的像素值設置爲1。如今咱們要解決的問題是處理移動物體出如今咱們放置標誌的同一區域。

如前所述,咱們須要使logo容許本身被移動對象遮擋。

如今,咱們將在其中放置logo的區域具備普遍的像素值。理想狀況下,此區域中的全部像素值都應相同。那咱們怎麼作呢?

咱們必須使綠色虛線框包圍的牆像素具備相同的值。咱們能夠藉助HSV(色調、飽和度、值)顏色空間來完成此操做:

咱們的圖像是在RGB色彩空間。咱們將把它轉換成HSV圖像。下圖是HSV版本:

下一步是僅查找綠色虛線框內零件的HSV值範圍。結果顯示框中的大多數像素的範圍從[6,10,68]到[30,36,122]。它們分別是HSV的上下範圍。

如今使用這個HSV值範圍,咱們能夠建立一個二進制掩碼。此掩碼只是像素值爲0或255的圖像。所以,在HSV值的上下範圍內的像素將等於255,其他像素將爲0。

下面是根據HSV圖像準備的掩碼。黃色區域中的全部像素的像素值爲255,其他像素值爲0:

如今,咱們能夠根據須要輕鬆地將綠色虛線框內的像素值設置爲1。讓咱們回到代碼:

# HSV的範圍
lower = np.array([6,10,68])
upper = np.array([30,36,122])

# 爲圖像建立核
kernel = np.ones((3,3),np.uint8)

# 每次運行如下while循環時,執行下面的兩行
cap = cv2.VideoCapture(path+"Pexels Videos 2675513.mp4")
cnt = 0

# 循環加載、預處理和顯示幀
while(True):
    ret, f = cap.read()
    
    # 提取咱們將放置logo的區域
    # 此區域的尺寸應與logo的尺寸相匹配
    mini_frame = f[500:740,875:1070,:]
    
    # 建立 HSV 圖像
    hsv = cv2.cvtColor(f, cv2.COLOR_BGR2HSV)
    
    # 建立掩碼
    mask = cv2.inRange(hsv, lower, upper)
    
    dil = cv2.dilate(mask,kernel,iterations = 5)
    
    # 建立3個通道
    mini_dil = np.zeros_like(mini_frame)
    mini_dil[:,:,0] = dil[500:740,875:1070]
    mini_dil[:,:,1] = dil[500:740,875:1070]
    mini_dil[:,:,2] = dil[500:740,875:1070]
    
    # 複製logo圖像
    logo_copy = logo.copy()
    
    # 當掩碼的像素值爲0時,將像素值設置爲1
    logo_copy[mini_dil == 0] = 1
    
    # 將標識的像素值設置爲1,其中標識的像素值爲0
    logo_copy[logo == 0] = 1    
    
    # 當logo的像素值不爲1時,將像素值設置爲1
    mini_frame[logo_copy != 1] = 1
    
    # 合併圖像(數組乘法)
    mini_frame = mini_frame*logo_copy
    
    # 在框架中插入logo
    f[500:740,875:1070,:] = mini_frame
    
    # 調整框架的大小(可選)
    f = cv2.resize(f, (480, 270), interpolation = cv2.INTER_AREA)

    # 顯示幀
    cv2.imshow('frame', f)
    
    # 保存幀
    # cv2.imwrite(path+'frames/'+str(cnt)+'.png',f)
    cnt+= 1
    
    if cv2.waitKey(20) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

上面的代碼片斷將從視頻中加載幀,對其進行預處理,並建立HSV圖像和掩碼,最後將logo插入到視頻中。你完成了!

結尾

在本文中,咱們介紹了一個很是有趣的計算機視覺用例,並從零開始實現它。在此過程當中,咱們還學習瞭如何使用圖像數組以及如何從這些數組建立掩碼。

當你處理其餘的計算機視覺任務時,這會對你有所幫助。

原文連接:https://www.analyticsvidhya.com/blog/2020/06/deep-learning-project-image-object-opencv/

歡迎關注磐創AI博客站: http://panchuang.net/

sklearn機器學習中文官方文檔: http://sklearn123.com/

歡迎關注磐創博客資源彙總站: http://docs.panchuang.net/

相關文章
相關標籤/搜索