Skip to content

Commit

Permalink
added instructions on how to use Windows + OBS
Browse files Browse the repository at this point in the history
  • Loading branch information
alew3 committed Apr 11, 2020
1 parent 8c5de4e commit 3ef5b58
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 54 deletions.
134 changes: 91 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# faceit_live3
This is an update to http://github.com/faceit_live using [first order model](https://github.com/AliaksandrSiarohin/first-order-model) by Aliaksandr Siarohin to generate the images. This model only requires a single image, so no training is needed and things are much easier.
This is an update to http://github.com/faceit_live using [first order model](https://github.com/AliaksandrSiarohin/first-order-model) by Aliaksandr Siarohin to generate the images. This model only requires a single image, so no training is needed and things are much easier. I've included instructions on how to set it up under **Windows 10** and **Linux**.

# Demo

Expand All @@ -11,17 +11,76 @@ Here is a video of the program running. It uses a single page I took from partne
# Setup

## Requirements
This has been tested on **Ubuntu 18.04 with a Titan RTX/X GPU**.
This has only been tested on **Ubuntu 18.04 and Win 10 with a Titan RTX/X GPU**.
You will need the following to make it work:

Linux host OS
Linux host OS / Win 10
NVidia fast GPU (GTX 1080, GTX 1080i, Titan, etc ...)
Fast Desktop CPU (Quad Core or more)
NVidia CUDA 10 and cuDNN 7 libraries installed

Webcam
Anaconda Environment (https://www.anaconda.com/distribution/)


## Setup Host System
# Clone this repository
Don't forget to use the *--recurse-submodules* parameter to checkout all dependencies. In Windows you might need to install a [Git Client](https://git-scm.com/download/win).

$ git clone --recurse-submodules https://github.com/alew3/faceit_live3.git

## Download 'vox-adv-cpk.pth.tar' to /model folder

You can find it at: [google-drive](https://drive.google.com/open?id=1PyQJmkdCsAkOYwUyaj_l-l0as-iLDgeH) or [yandex-disk](https://yadi.sk/d/lEw8uRm140L_eQ).

# Install Nvidia Deep Learning Drivers / Libs
Install the latest Nvidia video driver then the Deep Learning infrastructure:

* NVidia [CUDA 10.1 driver](https://developer.nvidia.com/cuda-downloads) - 2.6GB Download!
* [cuDNN](https://developer.nvidia.com/cudnn) version for CUDA 10.1 - you will need to register to download it.

Other versions might work, but I haven't tested them.


## Usage

Put in the `/media` directory the images in jpg/png you want to play with. Squared images that have just a face filling most of the space will work better.


# Setup Windows Version

## Create an Anaconda environment and install requirements
```
$ conda create -n faceit_live3 python=3.8
$ conda activate faceit_live3
$ conda install pytorch=1.4 torchvision=0.5 cudatoolkit=10.1 -c pytorch
$ pip install -r requirements.txt
```

## Setup Virtual Camera for streaming

Download [OBS Studio for Win](https://obsproject.com/download) and install it, afterwards install the [OBS Virtual CAM plugin](https://github.com/CatxFish/obs-virtual-cam/releases) by following instructions on the page.

After you install Virtual CAM.
- Create a Scene
- Add a Window Capture item to Sources and select the "Stream Window"
- Add a Filter to the Window Capture by right clicking and selecting Filters, then "+" and choose Virtual CAM
- Start the Virtual CAM from the Tools Menu

[![Select the OBSCAM](https://raw.githubusercontent.com/alew3/faceit_live3/master/docsobs.png)]

Open Firefox and joing Google Hangout to test it, don't forget to choose the OBS CAM from the camera options under settings.

[![Select the OBSCAM](https://raw.githubusercontent.com/alew3/faceit_live3/master/docs/obscam.png)]

# Setup Linux Version

## Create an Anaconda environment and install requirements
```
$ conda create -n faceit_live3 python=3.8
$ source activate faceit_live3
$ conda install pytorch=1.4 torchvision=0.5 cudatoolkit=10.1 -c pytorch
$ pip install -r requirements.txt
```

To use the fake webcam feature to enter conferences with our stream we need to insert the **v4l2loopback** kernel module in order to create */dev/video1*. Follow the install instructions at (https://github.com/umlaeute/v4l2loopback), then let's setup our fake webcam:

```
Expand Down Expand Up @@ -65,61 +124,50 @@ $ v4l2-ctl --list-formats -d /dev/video1
```


If you have more than one GPU, you might need to set some environment variables:
```
# specify which display to use for rendering
$ export DISPLAY=:1
# which CUDA DEVICE to use (run nvidia-smi to discover the ID)
$ export CUDA_VISIBLE_DEVICES=0
```

## Clone this repository
Don't forget to use the *--recurse-submodules* parameter to checkout all dependencies.

$ git clone --recurse-submodules https://github.com/alew3/faceit_live3.git /local_path/

## Create an Anaconda environment and install requirements
```
$ conda create -n faceit_live3 python=3.8
$ source activate faceit_live3
$ conda install pytorch=1.4 torchvision=0.5 cudatoolkit=10.1 -c pytorch
$ pip install -r requirements.txt
```

## Download 'vox-adv-cpk.pth.tar' to /model folder

You can find it at: [google-drive](https://drive.google.com/open?id=1PyQJmkdCsAkOYwUyaj_l-l0as-iLDgeH) or [yandex-disk](https://yadi.sk/d/lEw8uRm140L_eQ).


# Usage

Put in the `./media/` directory the images in jpg/png you want to play with.


# Run the program
# Run the program

```
$ python faceit_live.py
```

## Parameters
--system # win or linux (default is win)
--webcam_id # the videoid of the Webcam e.g. 0 if /dev/video0 (default is 0)
--stream_id # the /dev/video number to stream to (default is 1)
--stream_id # only used in Linux. Set the /dev/video number to stream to (default is 1)
--gpu_id # for multiple GPU setups, select which GPU to use (default is 0)

## Example
```
$ python faceit_live.py --webcam_id 0 --stream_id 1
```

## Shortcuts when running
## Key Shortcuts when running
```
N - cycle next image in media folder
C - recenter webcam and create a new base image
T - option to alter between 'Relative' and 'Absolute' transformations mode
Q - to quit and close all Windows
```

# Tip
For better results, look into the webcam when starting the program or when pressing C, as this will create a base image from your face that is used for the transformation. Move away and closer to the webcam to find the ideal distance for better results.
For better results, look into the webcam when starting the program or when pressing C, as this will create a base image from your face that is used for the transformation. Move away and closer to the webcam to find the ideal distance for better results.

## Troubleshooting

### Slow
If it is running slow, check that it is running on the GPU by looking at the TASK MANAGER under Windows and NVidia Control Panel for Linux.


### Multiple GPU

If you have more than one GPU, you might need to set some environment variables:
```
# specify which display to use for rendering (Linux)
$ export DISPLAY=:1
# which CUDA DEVICE to use (run nvidia-smi to discover the ID)
$ export CUDA_VISIBLE_DEVICES=0 (LINUX)
or
$ SET CUDA_VISIBLE_DEVICES=0,1 (WIN)
```
Binary file added docs/obs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/obscam.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 34 additions & 11 deletions faceit_live.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
import PIL.ImageFilter
import io
from io import BytesIO
import pyfakewebcam
import pyautogui
import os
import glob
from argparse import Namespace
import argparse
import timeit
import torch
warnings.filterwarnings("ignore")

############## setup ####
Expand All @@ -25,16 +25,24 @@
model_path = 'model/'

parser = argparse.ArgumentParser()
parser.add_argument('--webcam_id', type = int, default = 2)
parser.add_argument('--webcam_id', type = int, default = 0)
parser.add_argument('--stream_id', type = int, default = 1)
args = parser.parse_args()

parser.add_argument('--gpu_id', type = int, default = 0)
parser.add_argument('--system', type = str, default = "win")

args = parser.parse_args()
webcam_id = args.webcam_id
gpu_id = args.gpu_id

webcam_height = 480
webcam_width = 640
screen_width, screen_height = pyautogui.size()

system = args.system
if system=="linux":
import pyfakewebcam


stream_id = args.stream_id
first_order_path = 'first-order-model/'
sys.path.insert(0,first_order_path)
Expand All @@ -47,13 +55,25 @@
# prevent tqdm from outputting to console
demo.tqdm = lambda *i, **kwargs: i[0]

print("CUDA is available: ",torch.cuda.is_available())
if (torch.cuda.is_available()):
torch.cuda.device("cuda:" + str(gpu_id))
print("Device Name:",torch.cuda.get_device_name(gpu_id))
print("Device Count:",torch.cuda.device_count())
print("CUDA: ",torch.version.cuda)
print("cuDNN",torch.backends.cudnn.version())
print("Device",torch.cuda.current_device())



img_list = []
print("Scanning /media folder for images to use...")
for filename in os.listdir(media_path):
if filename.endswith(".jpg") or filename.endswith(".jpeg") or filename.endswith(".png"):
img_list.append(os.path.join(media_path, filename))
print(os.path.join(media_path, filename))

print(img_list, len(img_list))
#print(img_list, len(img_list))



Expand All @@ -66,9 +86,10 @@ def main():
source_image = readnextimage(0)

# start streaming
camera = pyfakewebcam.FakeWebcam(f'/dev/video{stream_id}', webcam_width, webcam_height)
camera.print_capabilities()
print(f"Fake webcam created on /dev/video{stream_id}. Use Firefox and join a Google Meeting to test.")
if system=="linux":
camera = pyfakewebcam.FakeWebcam(f'/dev/video{stream_id}', webcam_width, webcam_height)
camera.print_capabilities()
print(f"Fake webcam created on /dev/video{stream_id}. Use Firefox and join a Google Meeting to test.")

# capture webcam
video_capture = cv2.VideoCapture(webcam_id)
Expand Down Expand Up @@ -135,7 +156,8 @@ def main():
stream_v = (stream_v*255).astype(np.uint8)

# stream to fakewebcam
camera.schedule_frame(stream_v)
if system=="linux":
camera.schedule_frame(stream_v)


k = cv2.waitKey(1)
Expand All @@ -160,8 +182,9 @@ def main():

# transform face with first-order-model
def process_image(source_image,base,current,net, generator,kp_detector,relative):
predictions = make_animation(source_image, [base,current], generator, kp_detector, relative=relative, adapt_movement_scale=False)

predictions = make_animation(source_image, [base,current], generator, kp_detector, relative=relative, adapt_movement_scale=False, cpu=False)
#print("Device",torch.cuda.current_device())
#print("Device Name:",torch.cuda.get_device_name(gpu_id))
# predictions = [1]# predictions[..., ::-1]
# predictions = (np.clip(predictions, 0, 1) * 255).astype(np.uint8)
return predictions[1]
Expand Down

0 comments on commit 3ef5b58

Please sign in to comment.