欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何使用?Python為你的在線會議創(chuàng)建一個假的攝像頭

 更新時間:2022年08月29日 14:56:38   作者:woshicver  
這篇文章主要介紹了使用?Python為你的在線會議創(chuàng)建一個假的攝像頭,在?Python?的幫助下,不再強制開啟攝像頭,將向你展示如何為你的在線會議創(chuàng)建一個假的攝像頭,需要的朋友可以參考下

想象一下。你正在參加在線會議,出于某種原因,你并不想打開攝像頭。但是如果你看到其他人都打開了,你覺得你也得打開,所以迅速整理自己的頭發(fā),確保衣著整潔,然后不情愿地打開相機。我們都經歷過這種情況。

有一個好消息。在 Python 的幫助下,不再強制開啟攝像頭。將向你展示如何為你的在線會議創(chuàng)建一個假的攝像頭,如下所示:

d82f44ce06650e6dbc7ec36e1d324c2e.gif

aadc4345edf8cb12b0c7c494aa571a2a.gif

當然,這張臉不一定是比爾蓋茨的,它也可以是你自己。

現(xiàn)在將向你展示如何在 Python 中編寫代碼。在文章的最后,將解釋如何為自己使用這個假的攝像頭。

創(chuàng)建一個簡單的假網(wǎng)絡攝像頭

首先,我們將導入一些模塊,尤其是 openCV。

import cv2
import numpy as np
import pickle
import pyaudio
import struct
import math
import argparse
import os

接下來我們將創(chuàng)建一個函數(shù)來從視頻中提取所有幀:

def read_frames(file, video_folder):
    frames = []
    cap = cv2.VideoCapture(os.path.join('videos', video_folder, file))
    frame_rate = cap.get(cv2.CAP_PROP_FPS)
    if not cap.isOpened():
        print("Error opening video file")
    while cap.isOpened():
        ret, frame = cap.read()
        if ret:
            frames.append(frame)
        else:
            break
    cap.release()
    return frames, frame_rate

現(xiàn)在我們有了框架,我們可以創(chuàng)建一個循環(huán),一個接一個地顯示它們。當?shù)竭_最后一幀時,我們向后播放視頻,然后當我們到達第一幀時,我們將向前播放,我們將永遠重復這個過程。這樣就不會出現(xiàn)從最后一幀到第一幀的突然過渡。我們也會這樣做,以便我們可以按“q”停止網(wǎng)絡攝像頭。

frames, frame_rate = read_frames('normal.mov', 'bill_gates')
 
def next_frame_index(i, reverse):
    if i == len(frames) - 1:
        reverse = True
    if i == 0:
        reverse = False
    if not reverse:
        i += 1
    else:
        i -= 1
    return i, reverse
rev = False
i = 0
while True:
    frame = frames[i]
    cv2.imshow('Webcam', frame)
    pressed_key = cv2.waitKey(int(1000/frame_rate)) & 0xFF
    if pressed_key == ord("q"):
        break
    i, rev = next_frame_index(i, mode, rev)

有了這個,我們就有了一個可以無縫播放的簡單網(wǎng)絡攝像頭。

但我們并不止步于此。

添加不同的模式

如果我們的假網(wǎng)絡攝像頭頭像可以做的不僅僅是被動地凝視,那將更有說服力。例如,有時在開會時,你需要點頭表示同意、微笑、交談或做其他事情。

所以我們希望我們的網(wǎng)絡攝像頭有多種“模式”,我們可以隨時通過按下鍵盤上的一個鍵來切換。

為此,你需要為每種模式錄制一個簡短的錄音,例如你只是微笑的錄音。然后我們可以從每個視頻中讀取幀,并將它們存儲在字典中。當我們檢測到按鍵(例如,“s”切換到“微笑模式”)時,我們將活動模式更改為新模式并開始播放相應視頻中的幀。

video_files = [file for file in os.listdir(os.path.join('videos', folder))
               if file not in ['transitions_dict.p', '.DS_Store']]
frames, frame_rates = {}, {}
 
for file in video_files:
    mode_name = file.split('.')[0]
    frames[mode_name], frame_rates[mode_name] = read_frames(file, folder)
modes = list(frames.keys())
commands = {mode[0]: mode for mode in modes if mode != 'normal'}
 
mode = "normal"
frame_rate = frame_rates[mode]
rev = False
i = 0
while True:
    frame = frames[mode][i]
    cv2.imshow('Webcam', frame)
    pressed_key = cv2.waitKey(int(1000/frame_rate)) & 0xFF
    if pressed_key == ord("q"):
        break
    for command, new_mode in commands.items():
        if pressed_key == ord(command):
            i, mode, frame_rate = change_mode(mode, new_mode, i)
    i, rev = next_frame_index(i, mode, rev)

默認情況下,這樣做是為了切換到指定模式,鍵盤命令是模式名稱的第一個字母。現(xiàn)在我把這個'change_mode'函數(shù)作為一個黑盒子,稍后會解釋它。

優(yōu)化過渡

所以我們想從一個視頻切換到另一個,比如說從正常模式到點頭模式。如何以最佳方式從一個模式過渡到另一個模式(即過渡盡可能平滑)?

當我們進行過渡時,我們希望轉到與我們當前所處的最相似的新模式的框架。

為此,我們可以首先定義圖像之間的距離度量。這里使用一個簡單的歐幾里得距離,它查看兩個圖像的每個像素之間的差異。

有了這個距離,我們現(xiàn)在可以找到最接近我們當前的圖像,并切換到這個。例如,如果我們想從普通模式過渡到點頭模式,并且我們在普通視頻的第 132 幀,我們將知道我們必須轉到點頭視頻的第 86 幀才能獲得最平滑的過渡。

我們可以為每一幀以及從每種模式到所有其他模式預先計算所有這些最佳轉換。這樣我們就不必在每次想要切換模式時都重新計算。還壓縮了圖像,以便計算執(zhí)行時間更短。我們還將存儲圖像之間的最佳距離。

video_files = [file for file in os.listdir(os.path.join('videos', video_folder))
                       if file not in ['transitions_dict.p', '.DS_Store']]
frames = {}
for file in video_files:
    mode_name = file.split('.')[0]
    frames[mode_name] = read_frames(file, video_folder)
modes = list(frames.keys())
 
compression_ratio = 10
height, width = frames["normal"][0].shape[:2]
new_height, new_width = height // compression_ratio, width // compression_ratio, 
 
def compress_img(img):
    return cv2.resize(img.mean(axis=2), (new_width, new_height))
 
  
frames_compressed = {mode: np.array([compress_img(img) for img in frames[mode]]) for mode in modes}
 
transitions_dict = {mode:{} for mode in modes}
 
for i in range(len(modes)):
    for j in tqdm(range(i+1, len(modes))):
        mode_1, mode_2 = modes[i], modes[j]
        diff = np.expand_dims(frames_compressed[mode_1], axis=0) - np.expand_dims(frames_compressed[mode_2], axis=1)
        dists = np.linalg.norm(diff, axis=(2, 3))
        transitions_dict[mode_1][mode_2] = (dists.argmin(axis=0), dists.min(axis=0))
        transitions_dict[mode_2][mode_1] = (dists.argmin(axis=1), dists.min(axis=1))
 
pickle.dump(transitions_dict, open(os.path.join('videos', video_folder, 'transitions_dict.p'), 'wb'))

現(xiàn)在可以展示“change_mode”函數(shù),該函數(shù)從預先計算的字典中檢索要轉換到的最佳幀。這樣做是為了如果你按下例如“s”切換到微笑模式,再次按下它將切換回正常模式。

def change_mode(current_mode, toggled_mode, i):
    if current_mode == toggled_mode:
        toggled_mode = 'normal'
 
    new_i = transitions_dict[current_mode][toggled_mode][0][i]
    dist = transitions_dict[current_mode][toggled_mode][1][i]
    
    return new_i, toggled_mode, frame_rates[toggled_mode]

我們還可以添加另一項改進使我們的過渡更加無縫,不是總是立即切換模式,而是等待一段時間以獲得更好的過渡。例如,如果我們的頭像在點頭,我們可以等到頭部通過中間位置才轉換到正常模式。為此,我們將引入一個時間窗口(這里我將其設置為 0.5 秒),這樣我們將在切換模式之前等待在此窗口內轉換的最佳時間。

switch_mode_max_delay_in_s = 0.5
def change_mode(current_mode, toggled_mode, i):
    if current_mode == toggled_mode:
        toggled_mode = 'normal'
 
    # Wait for the optimal frame to transition within acceptable window
    max_frames_delay = int(frame_rate * switch_mode_max_delay_in_s)
    global rev
    if rev:
        frames_to_wait = max_frames_delay-1 - transitions_dict[current_mode][toggled_mode][1][max(0, i+1 - max_frames_delay):i+1].argmin()
    else:
        frames_to_wait = transitions_dict[current_mode][toggled_mode][1][i:i + max_frames_delay].argmin()
    print(f'Wait {frames_to_wait} frames before transitioning')
    for _ in range(frames_to_wait):
        i, rev = next_frame_index(i, current_mode, rev)
        frame = frames[mode][i]
        cv2.imshow('Frame', frame)
        cv2.waitKey(int(1000 / frame_rate))
    new_i = transitions_dict[current_mode][toggled_mode][0][i]
    dist = transitions_dict[current_mode][toggled_mode][1][i]
    
    return new_i, toggled_mode, frame_rates[toggled_mode]

現(xiàn)在我們的過渡更加順暢。但是,它們有時可能很明顯。所以另一個想法是有目的地為視頻添加凍結,就像那些在不穩(wěn)定連接時可能發(fā)生的凍結一樣(就是如果網(wǎng)絡不穩(wěn)定視頻就卡住了),并使用它們來掩蓋過渡(我們將使凍結持續(xù)時間與兩個圖像之間的距離成比例)。我們還將添加隨機凍結,這樣模式就不會變得明顯。所以我們添加了這些新的代碼:

# In the change_mode function:
    dist = transitions_dict[current_mode][toggled_mode][1][i]
    if freezes:
        freeze_duration = int(transition_freeze_duration_constant * dist)
        cv2.waitKey(freeze_duration)
# In the main loop:
    # Random freezes
    if freezes:
        if np.random.randint(frame_rate * 10) == 1:
            nb_frames_freeze = int(np.random.uniform(0.2, 1.5) * frame_rate)
            for _ in range(nb_frames_freeze):
                cv2.waitKey(int(1000 / frame_rate))
                i, rev = next_frame_index(i, mode, rev)

使用或不使用這些凍結保留為選項。

好的,現(xiàn)在我們已經真正涵蓋了這些過渡的基礎。我們還能為網(wǎng)絡攝像頭添加什么?

語音檢測

另一件有趣的事情是添加語音檢測,這樣當我們說話時,視頻里的“我”就會說話。

這是使用 pyaudio 完成的。感謝這個 stackoverflow 線程(https://stackoverflow.com/questions/4160175/detect-tap-with-pyaudio-from-live-mic)。

基本上,這個想法是查看一段時間內來自麥克風的聲音的平均幅度,如果它足夠高,可以認為我們一直在說話。最初這段代碼是為了檢測敲擊噪音,但它也可以很好地檢測語音。

AMPLITUDE_THRESHOLD = 0.010
FORMAT = pyaudio.paInt16
SHORT_NORMALIZE = (1.0/32768.0)
CHANNELS = 1
RATE = 44100
INPUT_BLOCK_TIME = 0.025
INPUT_FRAMES_PER_BLOCK = int(RATE*INPUT_BLOCK_TIME)
def get_rms(block):
    count = len(block)/2
    format = "%dh" % count
    shorts = struct.unpack(format, block)
 
    sum_squares = 0.0
    for sample in shorts:
        n = sample * SHORT_NORMALIZE
        sum_squares += n*n
    return math.sqrt( sum_squares / count )
pa = pyaudio.PyAudio()
 
stream = pa.open(format=FORMAT,
                 channels=CHANNELS,
                 rate=RATE,
                 input=True,
                 frames_per_buffer=INPUT_FRAMES_PER_BLOCK)
def detect_voice():
    error_count = 0
    voice_detected = False
    
    try:
        block = stream.read(INPUT_FRAMES_PER_BLOCK, exception_on_overflow=False)
    except (IOError, e):
        error_count += 1
        print("(%d) Error recording: %s" % (error_count, e))
 
    amplitude = get_rms(block)
    if amplitude > AMPLITUDE_THRESHOLD:
        voice_detected = True
    return voice_detected

現(xiàn)在我們可以將它添加到主循環(huán)中。這樣做是為了在切換回正常模式之前,我們需要在一定數(shù)量的連續(xù)幀內檢測到沒有聲音,這樣我們就不會太頻繁地切換。

# In the main loop:
  
  if voice_detection:
      if detect_voice():
          quiet_count = 0
          if mode != "talking":
              i, mode, frame_rate = change_mode(mode, "talking", i)
      else:
          if mode == "talking":
              quiet_count += 1
              if quiet_count > stop_talking_threshold:
                  quiet_count = 0
                  i, mode, frame_rate = change_mode(mode, "normal", i)

現(xiàn)在,當我們通過麥克風說話時,我們可以讓我們的頭像開始和停止說話。我這樣做是為了通過按“v”來激活或停用語音檢測。

這些都是迄今為止實現(xiàn)的所有功能。歡迎提出進一步改進的建議。

如何使用假網(wǎng)絡攝像頭

首先,從這里下載所有代碼:https://github.com/FrancoisLeRoux1/Fake-webcam

你要做的是錄制一些你自己的視頻(在我的 Mac 上,為此使用了 Photo Booth 應用程序),并將它們放在“視頻”文件夾內的一個新文件夾中。你將能夠為不同的設置創(chuàng)建不同的文件夾,例如,你可以在其中穿不同的襯衫,或者讓你的頭發(fā)看起來不同。

這些視頻可以而且應該很短(大約 10 秒的視頻),否則如果你拍攝較長的視頻,計算最佳過渡可能需要很長時間。你需要一個名為“normal”的視頻,這將是你的默認模式。

然后,如果你想讓你的化身說話,你必須錄制一個名為“talking”的視頻,你說的是隨機的胡言亂語。

在此之后,你可以錄制你想要的任何其他模式(例如,“微笑”、“點頭”、“再見”……)。默認情況下,激活/停用這些模式的命令將是其名稱的第一個字母(例如,對于“微笑”,請按“s”)。

然后你必須計算最佳轉換。為此,只需運行腳本 compute-transitions.py

這應該需要幾分鐘。

然后當你完成后,你就可以啟動你的假網(wǎng)絡攝像頭了。為此,請運行 fake-webcam.py 腳本。你需要指定視頻所在的“視頻”內的文件夾。你還可以指定是否要使用凍結。

所以現(xiàn)在你應該讓你的假相機運行起來。接下來,你可以將其設置為在線會議的網(wǎng)絡攝像頭。為此,我使用了 OBS:https://obsproject.com/

選擇正確的 Python 窗口作為源,然后單擊 Start Virtual Camera。

你現(xiàn)在應該可以在你最喜歡的在線會議應用程序中選擇此虛擬攝像頭作為你的網(wǎng)絡攝像頭了!

到此這篇關于使用Python為你的在線會議創(chuàng)建一個假的攝像頭的文章就介紹到這了,更多相關Python攝像頭內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • python實現(xiàn)兩字符串映射

    python實現(xiàn)兩字符串映射

    這篇文章主要介紹了python實現(xiàn)兩字符串映射方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • python3 xpath和requests應用詳解

    python3 xpath和requests應用詳解

    這篇文章主要介紹了python3 xpath和requests應用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Python換行與不換行的輸出實例

    Python換行與不換行的輸出實例

    這篇文章主要介紹了Python換行與不換行的輸出實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • Python學習筆記之列表和成員運算符及列表相關方法詳解

    Python學習筆記之列表和成員運算符及列表相關方法詳解

    這篇文章主要介紹了Python學習筆記之列表和成員運算符及列表相關方法,結合實例形式詳細分析了Python列表相關的概念、原理、成員函數(shù)與相關使用技巧,需要的朋友可以參考下
    2019-08-08
  • Pyhton爬蟲知識之正則表達式詳解

    Pyhton爬蟲知識之正則表達式詳解

    正則表達式又稱規(guī)則表達式,計算機科學的一個概念,正則表達式通常被用來檢索、替換那些符合某個模式(規(guī)則)的文本,這篇文章主要給大家介紹了關于Pyhton爬蟲知識之正則表達式的相關資料,需要的朋友可以參考下
    2022-04-04
  • pytorch點乘與叉乘示例講解

    pytorch點乘與叉乘示例講解

    今天小編就為大家分享一篇pytorch點乘與叉乘示例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • python 2.7.14安裝圖文教程

    python 2.7.14安裝圖文教程

    這篇文章主要為大家詳細介紹了python 2.7.14安裝圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • 使用PDB模式調試Python程序介紹

    使用PDB模式調試Python程序介紹

    這篇文章主要介紹了使用PDB模式調試Python程序介紹,本文講解了PDB模式的使用語法,著重講解PDB模式下的常用命令,需要的朋友可以參考下
    2015-04-04
  • 15個最近才知道的Python實用操作

    15個最近才知道的Python實用操作

    這篇文章主要和大家分享了15個最近才知道的Python實用操作,文中的示例代碼講解詳細,對我們深入了解Python有一定的幫助,感興趣的小伙伴可以了解一下
    2023-04-04
  • 利用Python寫個摸魚監(jiān)控進程

    利用Python寫個摸魚監(jiān)控進程

    繼打游戲、看視頻等摸魚行為被監(jiān)控后,現(xiàn)在打工人離職的傾向也會被監(jiān)控。今天就帶大家領略一下怎么寫幾行Python代碼,就能監(jiān)控電腦,感興趣的可以學習一下
    2022-02-02

最新評論