diff --git a/README.md b/README.md index 7776789..a1bff0d 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,11 @@ when using this project as a library: | extra name | description | ---------- | ----------- -| tf | TensorFlow (required). But you may use your own build. -| tfjs | TensorFlow JS Model support -| image | Image loading via Pillow, required by the CLI. -| webcam | Webcam support via OpenCV and pyfakewebcam -| video | Video support via OpenCV +| tf | [TensorFlow](https://pypi.org/project/tensorflow/) (required). But you may use your own build. +| tfjs | TensorFlow JS Model support, using [tfjs-graph-converter](https://pypi.org/project/tfjs-graph-converter/) +| image | Image loading via [Pillow](https://pypi.org/project/Pillow/), required by the CLI. +| video | Video support via [OpenCV](https://pypi.org/project/opencv-python/) +| webcam | Webcam support via [OpenCV](https://pypi.org/project/opencv-python/) and [pyfakewebcam](https://pypi.org/project/pyfakewebcam/) | all | All of the libraries ## Python API @@ -90,6 +90,32 @@ Those URLs can be passed as the `--model-path` arguments below, or to the `downl The CLI will download and cache the model from the provided path. If no `--model-path` is provided, it will use a default model (mobilenet). +### Inputs and Outputs + +Most commands will work with inputs (source) and outputs. + +The source path can be specified via the `--source` parameter. + +The following inputs are supported: + +| type | description | +| -----| ----------- | +| image | Static image (e.g. `.png`) | +| video | Video (e.g. `.mp4`) | +| webcam | Linux Webcam (`/dev/videoN` or `webcam:0`) | + +If the source path points to an external file (e.g. `https://`), then it will be downloaded and locally cached. + +The output path can be specified via `--output`, unless `--show-output` is used. + +The following outpus are supported: + +| type | description | +| -----| ----------- | +| image_writer | Write to a static image (e.g. `.png`) | +| v4l2 | Linux Virtual Webcam (`/dev/videoN`) | +| window | Display a window (by using `--show-output`) | + ### Example commands #### Creating a simple body mask @@ -97,35 +123,60 @@ The CLI will download and cache the model from the provided path. If no `--model ```bash python -m tf_bodypix \ draw-mask \ - --source /path/to/input-image.jpg \ - --output /path/to/output-mask.jpg \ + --source \ + "https://www.dropbox.com/s/7tsaqgdp149d8aj/serious-black-businesswoman-sitting-at-desk-in-office-5669603.jpg?dl=1" \ + --show-output \ --threshold=0.75 ``` +Image Source: [Serious black businesswoman sitting at desk in office](https://www.pexels.com/photo/serious-black-businesswoman-sitting-at-desk-in-office-5669603/) + +#### Add the mask over the original image using `--mask-alpha` + +```bash +python -m tf_bodypix \ + draw-mask \ + --source \ + "https://www.dropbox.com/s/7tsaqgdp149d8aj/serious-black-businesswoman-sitting-at-desk-in-office-5669603.jpg?dl=1" \ + --show-output \ + --threshold=0.75 \ + --mask-alpha=0.5 +``` + +Image Source: [Serious black businesswoman sitting at desk in office](https://www.pexels.com/photo/serious-black-businesswoman-sitting-at-desk-in-office-5669603/) + #### Colorize the body mask depending on the body part ```bash python -m tf_bodypix \ draw-mask \ - --source /path/to/input-image.jpg \ - --output /path/to/output-colored-mask.jpg \ + --source \ + "https://www.dropbox.com/s/7tsaqgdp149d8aj/serious-black-businesswoman-sitting-at-desk-in-office-5669603.jpg?dl=1" \ + --show-output \ --threshold=0.75 \ + --mask-alpha=0.5 \ --colored ``` +Image Source: [Serious black businesswoman sitting at desk in office](https://www.pexels.com/photo/serious-black-businesswoman-sitting-at-desk-in-office-5669603/) + #### Additionally select the body parts ```bash python -m tf_bodypix \ draw-mask \ - --source /path/to/input-image.jpg \ - --output /path/to/output-colored-mask.jpg \ + --source \ + "https://www.dropbox.com/s/7tsaqgdp149d8aj/serious-black-businesswoman-sitting-at-desk-in-office-5669603.jpg?dl=1" \ + --show-output \ --threshold=0.75 \ + --mask-alpha=0.5 \ --parts left_face right_face \ --colored ``` -#### Render a Video, while adding mask overlay, showing the result in an image +Image Source: [Serious black businesswoman sitting at desk in office](https://www.pexels.com/photo/serious-black-businesswoman-sitting-at-desk-in-office-5669603/) + +#### Add mask overlay to a video ```bash python -m tf_bodypix \ @@ -140,7 +191,40 @@ python -m tf_bodypix \ Video Source: [Video Of A Man Laughing And Happy](https://www.pexels.com/video/video-of-a-man-laughing-and-happy-1608393/) -#### Capture Webcam and adding mask overlay, showing the result in an image +#### Blur background of a video + +```bash +python -m tf_bodypix \ + blur-background \ + --source \ + "https://www.dropbox.com/s/s7jga3f0dreavlb/video-of-a-man-laughing-and-happy-1608393-360p.mp4?dl=1" \ + --show-output \ + --threshold=0.75 \ + --mask-blur=5 \ + --background-blur=20 +``` + +Video Source: [Video Of A Man Laughing And Happy](https://www.pexels.com/video/video-of-a-man-laughing-and-happy-1608393/) + +#### Replace the background of a video + +```bash +python -m tf_bodypix \ + replace-background \ + --source \ + "https://www.dropbox.com/s/s7jga3f0dreavlb/video-of-a-man-laughing-and-happy-1608393-360p.mp4?dl=1" \ + --background \ + "https://www.dropbox.com/s/b22ss59j6pp83zy/brown-landscape-under-grey-sky-3244513.jpg?dl=1" \ + --show-output \ + --threshold=0.75 \ + --mask-blur=5 +``` + +Video Source: [Video Of A Man Laughing And Happy](https://www.pexels.com/video/video-of-a-man-laughing-and-happy-1608393/) + +Background: [Brown Landscape Under Grey Sky](https://www.pexels.com/photo/brown-landscape-under-grey-sky-3244513/) + +#### Capture Webcam and adding mask overlay ```bash python -m tf_bodypix \ @@ -187,11 +271,14 @@ python -m tf_bodypix \ python -m tf_bodypix \ replace-background \ --source webcam:0 \ - --background /path/to/background-image.jpg \ - --output /dev/videoN \ - --threshold=0.75 + --background \ + "https://www.dropbox.com/s/b22ss59j6pp83zy/brown-landscape-under-grey-sky-3244513.jpg?dl=1" \ + --threshold=0.75 \ + --output /dev/videoN ``` +Background: [Brown Landscape Under Grey Sky](https://www.pexels.com/photo/brown-landscape-under-grey-sky-3244513/) + ## TensorFlow Lite support (experimental) The model path may also point to a TensorFlow Lite model (`.tflite` extension). Whether that actually improves performance may depend on the platform and available hardware. @@ -236,6 +323,30 @@ docker run --rm \ --threshold=0.75 ``` +## Example Media + +Here are a few example media files you could try. + +Images: + +* [Serious black businesswoman sitting at desk in office](https://www.dropbox.com/s/7tsaqgdp149d8aj/serious-black-businesswoman-sitting-at-desk-in-office-5669603.jpg?dl=1) ([Source](https://www.pexels.com/photo/serious-black-businesswoman-sitting-at-desk-in-office-5669603/)) +* [Woman Wearing Gray Notch Lapel Suit Jacket](https://www.dropbox.com/s/ygfudebvbm1pksk/woman-wearing-gray-notch-lapel-suit-jacket-2381069-small.jpg?dl=1) ([Source](https://www.pexels.com/photo/woman-wearing-gray-notch-lapel-suit-jacket-2381069/)) +* [Smiling Woman Standing In Front Of A Colorful Flag](https://www.dropbox.com/s/ddyj89vkz7cmzmg/smiling-woman-standing-in-front-of-a-colorful-flag-5255422-small.jpg?dl=1) ([Source](https://www.pexels.com/photo/smiling-woman-standing-in-front-of-a-colorful-flag-5255422/)) +* [Man and Woman Smiling Inside Building](https://www.dropbox.com/s/5z7v5wtwx3dmrdu/man-and-woman-smiling-inside-building-1367269-small.jpg?dl=1) ([Source](https://www.pexels.com/photo/man-and-woman-smiling-inside-building-1367269/)) +* [Two Woman in Black Sits on Chair Near Table](https://www.dropbox.com/s/dq9e2dv86qd9ror/two-woman-in-black-sits-on-chair-near-table-1181605-small.jpg?dl=1) ([Source](https://www.pexels.com/photo/two-woman-in-black-sits-on-chair-near-table-1181605/)) +* [Female barista in beanie and apron resting chin on had](https://www.dropbox.com/s/88qb3yldsb4l2id/female-barista-in-beanie-and-apron-resting-chin-on-had-4350057-small.jpg?dl=1) ([Source](https://www.pexels.com/photo/female-barista-in-beanie-and-apron-resting-chin-on-had-4350057/)) +* [Smiling Woman Holding White Android Smartphone While Sitting Front of Table](https://www.dropbox.com/s/43awel6e1mxja5v/smiling-woman-holding-white-android-smartphone-while-sitting-front-of-table-1462631-small.jpg?dl=1) ([Source](https://www.pexels.com/photo/smiling-woman-holding-white-android-smartphone-while-sitting-front-of-table-1462631/)) +* [Woman Having Coffee and Rice Bowl](https://www.dropbox.com/s/zndltp65n93poy2/woman-having-coffee-and-rice-bowl-4058316-small.jpg?dl=1) ([Source](https://www.pexels.com/photo/woman-having-coffee-and-rice-bowl-4058316/)) +* [Woman Smiling While Holding a Coffee Cup](https://www.dropbox.com/s/0txws4j79o9hewr/woman-smiling-while-holding-a-coffee-cup-6787913-small.jpg?dl=1) ([Source](https://www.pexels.com/photo/woman-smiling-while-holding-a-coffee-cup-6787913/)) + +Videos: + +* [Video Of A Man Laughing And Happy](https://www.dropbox.com/s/s7jga3f0dreavlb/video-of-a-man-laughing-and-happy-1608393-360p.mp4?dl=1) ([Source](https://www.pexels.com/video/video-of-a-man-laughing-and-happy-1608393/)) + +Background: + +* [Brown Landscape Under Grey Sky](https://www.dropbox.com/s/b22ss59j6pp83zy/brown-landscape-under-grey-sky-3244513.jpg?dl=1) ([Source](https://www.pexels.com/photo/brown-landscape-under-grey-sky-3244513/)) + ## Experimental Downstream Projects * [Layered Vision](https://github.com/de-code/layered-vision) is an experimental project using the `tf-bodypix` Python API. diff --git a/tf_bodypix/cli.py b/tf_bodypix/cli.py index c6701ec..a59d86e 100644 --- a/tf_bodypix/cli.py +++ b/tf_bodypix/cli.py @@ -583,12 +583,16 @@ def get_app(self, args: argparse.Namespace) -> AbstractWebcamFilterApp: def parse_args(argv: List[str] = None) -> argparse.Namespace: - parser = argparse.ArgumentParser() + parser = argparse.ArgumentParser( + 'TensorFlow BodyPix (TF BodyPix)', + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) subparsers = parser.add_subparsers(dest="command") subparsers.required = True for sub_command in SUB_COMMANDS: sub_parser = subparsers.add_parser( - sub_command.name, help=sub_command.description + sub_command.name, help=sub_command.description, + formatter_class=argparse.ArgumentDefaultsHelpFormatter ) sub_command.add_arguments(sub_parser)