diff --git a/.gitignore b/.gitignore
index 973701941c8c07162d56b2656be17c5ea6bdf5e2..c1a7e93d334778204b805743b7469df3d456667a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -138,7 +138,7 @@ mask_old/
origin_image/
datasets/
dataset/
-test*/
+test*
video_tmp/
result/
#./
@@ -163,14 +163,12 @@ result/
/make_datasets/datasets_img
/make_datasets/videos
#./models
-/models/videoHD_model.py
+#/models/videoHD_model.py
#./train
/train/clean/dataset
#mediafile
*iter
*.pth
-*.png
-*.jpg
*.jpeg
*.bmp
*.mp4
diff --git a/README.md b/README.md
index 15977a2819e6f1e469117d76a40e5aed069ef58f..0aa37c9b8719993da38795058f571d23175a3838 100755
--- a/README.md
+++ b/README.md
@@ -1,44 +1,49 @@
![image](./imgs/hand.gif)
# DeepMosaics
You can use it to automatically remove the mosaics in images and videos, or add mosaics to them.
-This porject based on ‘semantic segmentation’ and ‘Image-to-Image Translation’.
-Master is not stable. Please use a [stable version](https://github.com/HypoX64/DeepMosaics/tree/stable)
-* [中文版](./README_CN.md)
+This porject based on "semantic segmentation" and "Image-to-Image Translation".
+
+* [中文版README](./README_CN.md)
### More example
origin | auto add mosaic | auto clean mosaic
:-:|:-:|:-:
-![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/lena.jpg) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/lena_add.jpg) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/lena_clean.jpg)
-![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/youknow.png) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/youknow_add.png) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/youknow_clean.png)
+![image](./imgs/example/lena.jpg) | ![image](./imgs/example/lena_add.jpg) | ![image](./imgs/example/lena_clean.jpg)
+![image](./imgs/example/youknow.png) | ![image](./imgs/example/youknow_add.png) | ![image](./imgs/example/youknow_clean.png)
* Compared with [DeepCreamPy](https://github.com/deeppomf/DeepCreamPy)
-
mosaic image | DeepCreamPy | ours
:-:|:-:|:-:
-![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/face_a_mosaic.jpg) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/a_dcp.png) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/face_a_clean.jpg)
-![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/face_b_mosaic.jpg) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/b_dcp.png) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/face_b_clean.jpg)
+![image](./imgs/example/face_a_mosaic.jpg) | ![image](./imgs/example/a_dcp.png) | ![image](./imgs/example/face_a_clean.jpg)
+![image](./imgs/example/face_b_mosaic.jpg) | ![image](./imgs/example/b_dcp.png) | ![image](./imgs/example/face_b_clean.jpg)
+* Style Transfer
+origin | to Van Gogh | to winter
+:-:|:-:|:-:
+![image](./imgs/example/SZU.jpg) | ![image](./imgs/example/SZU_vangogh.jpg) | ![image](./imgs/example/SZU_summer2winter.jpg)
+An interesting example:[Ricardo Milos to cat](https://www.bilibili.com/video/BV1Q7411W7n6)
## Run DeepMosaics
You can either run DeepMosaics via pre-built binary package or from source.
### Pre-built binary package
For windows, we bulid a GUI version for easy test.
-Download this version via [[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
+Download this version and pre-trained model via [[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
+* [[How to use]](./docs/exe_help.md)
![image](./imgs/GUI.png)
-
Attentions:
+
- Require Windows_x86_64, Windows10 is better.
- - Different pre-trained models are suitable for different effects.
- - Run time depends on computer performance.
- - If output video cannot be played, you can try with [potplayer](https://daumpotplayer.com/download/).
- - GUI version update slower than source.
+ - Different pre-trained models are suitable for different effects.[[Introduction to pre-trained models]](./docs/pre-trained_models_introduction.md)
+ - Run time depends on computer performance(The current version does not support gpu, if you need to use gpu please run source).
+ - If output video cannot be played, you can try with [potplayer](https://daumpotplayer.com/download/).
+ - GUI version update slower than source.
### Run from source
#### Prerequisites
- Linux, Mac OS, Windows
- Python 3.6+
- [ffmpeg 3.4.6](http://ffmpeg.org/)
- - [Pytorch 1.0+](https://pytorch.org/) [(Old version codes)](https://github.com/HypoX64/DeepMosaics/tree/Pytorch0.4)
+ - [Pytorch 1.0+](https://pytorch.org/)
- CPU or NVIDIA GPU + CUDA CuDNN
#### Dependencies
This code depends on opencv-python, torchvision available via pip install.
@@ -47,22 +52,23 @@ This code depends on opencv-python, torchvision available via pip install.
git clone https://github.com/HypoX64/DeepMosaics
cd DeepMosaics
```
-#### Get pre_trained models and test video
+#### Get pre-trained models
You can download pre_trained models and put them into './pretrained_models'.
-[[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
+[[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
+[[Introduction to pre-trained models]](./docs/pre-trained_models_introduction.md)
#### Simple example
-* Add Mosaic (output video will save in './result')
+* Add Mosaic (output video will save in './result')
```bash
python3 deepmosaic.py --media_path ./imgs/ruoruo.jpg --model_path ./pretrained_models/mosaic/add_face.pth --use_gpu -1
```
-* Clean Mosaic (output video will save in './result')
+* Clean Mosaic (output video will save in './result')
```bash
python3 deepmosaic.py --media_path ./result/ruoruo_add.jpg --model_path ./pretrained_models/mosaic/clean_face_HD.pth --use_gpu -1
```
#### More parameters
-If you want to test other image or video, please refer to this file.
-[[options.py]](./cores/options.py)
+If you want to test other image or video, please refer to this file.
+[[options_introduction.md]](./docs/options_introduction.md)
## Acknowledgments
This code borrows heavily from [[pytorch-CycleGAN-and-pix2pix]](https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix) [[Pytorch-UNet]](https://github.com/milesial/Pytorch-UNet)[[pix2pixHD]](https://github.com/NVIDIA/pix2pixHD).
diff --git a/README_CN.md b/README_CN.md
index b4bef9bc188dad0d4d5eb3251e944c36b2707cb4..d9f9c4c45005be129181ad7444ad34103c4b27ed 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -1,23 +1,22 @@
![image](./imgs/hand.gif)
# DeepMosaics
这是一个通过深度学习自动的为图片/视频添加马赛克,或消除马赛克的项目.
它基于“语义分割”以及“图像翻译”.
-主分支并不稳定,请移步[稳定版本](https://github.com/HypoX64/DeepMosaics/tree/stable)
+
### 更多例子
原始 | 自动打码 | 自动去码
:-:|:-:|:-:
-![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/lena.jpg) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/lena_add.jpg) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/lena_clean.jpg)
-![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/youknow.png) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/youknow_add.png) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/youknow_clean.png)
+![image](./imgs/example/lena.jpg) | ![image](./imgs/example/lena_add.jpg) | ![image](./imgs/example/lena_clean.jpg)
+![image](./imgs/example/youknow.png) | ![image](./imgs/example/youknow_add.png) | ![image](./imgs/example/youknow_clean.png)
* 与 [DeepCreamPy](https://github.com/deeppomf/DeepCreamPy)相比较
-
马赛克图片 | DeepCreamPy | ours
:-:|:-:|:-:
-![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/face_a_mosaic.jpg) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/a_dcp.png) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/face_a_clean.jpg)
-![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/face_b_mosaic.jpg) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/b_dcp.png) | ![image](https://github.com/HypoX64/DeepMosaics_example/blob/master/face_b_clean.jpg)
-
-## 一些说明
-* 训练部分并不完全
-* 现在,代码已经支持基于[pix2pixHD](https://github.com/NVIDIA/pix2pixHD)训练出的模型,但网络仍在训练中,这将使得输出结果看起来更加清晰,"真实".
-* 新的模型,可根据视频帧间关系进行马赛克恢复,在pretrained model 中被命名为*_video.pth
+![image](./imgs/example/face_a_mosaic.jpg) | ![image](./imgs/example/a_dcp.png) | ![image](./imgs/example/face_a_clean.jpg)
+![image](./imgs/example/face_b_mosaic.jpg) | ![image](./imgs/example/b_dcp.png) | ![image](./imgs/example/face_b_clean.jpg)
+* 风格转换
+原始 | 梵高风格 | 转化为冬天
+:-:|:-:|:-:
+![image](./imgs/example/SZU.jpg) | ![image](./imgs/example/SZU_vangogh.jpg) | ![image](./imgs/example/SZU_summer2winter.jpg)
+一个有意思的尝试:[香蕉君♂猫](https://www.bilibili.com/video/BV1Q7411W7n6)
## 如何运行
可以通过我们预编译好的二进制包或源代码运行.
@@ -26,12 +25,14 @@
对于Windows用户,我们提供了包含GUI界面的免安装软件包.
可以通过下面两种方式进行下载: [[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
+* [[使用教程]](./docs/exe_help_CN.md)
+
![image](./imgs/GUI.png)
注意事项:
- 程序的运行要求在64位Windows操作系统,我仅在Windows10运行过,其他版本暂未经过测试
- - 请根据需求选择合适的预训练模型进行测试
- - 运行时间取决于电脑性能,对于视频文件,我们建议可以先使用截图进行测试.
+ - 请根据需求选择合适的预训练模型进行测试,不同的预期训练模型具有不同的效果.[[预训练模型介绍]](./docs/pre-trained_models_introduction_CN.md)
+ - 运行时间取决于电脑性能,对于视频文件,我们建议使用源码并在GPU上运行.
- 如果输出的视频无法播放,这边建议您尝试[potplayer](https://daumpotplayer.com/download/).
- 相比于源码,该版本的更新将会延后.
@@ -40,7 +41,7 @@
- Linux, Mac OS, Windows
- Python 3.6+
- [ffmpeg 3.4.6](http://ffmpeg.org/)
- - [Pytorch 1.0+](https://pytorch.org/) [(Old version codes)](https://github.com/HypoX64/DeepMosaics/tree/Pytorch0.4)
+ - [Pytorch 1.0+](https://pytorch.org/)
- CPU or NVIDIA GPU + CUDA CuDNN
#### Python依赖项
代码依赖于opencv-python以及 torchvision,可有通过pip install 进行安装.
@@ -52,19 +53,20 @@ cd DeepMosaics
#### 下载预训练模型
可以通过以下两种方法下载预训练模型,并将他们置于'./pretrained_models'文件夹中.
[[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
+[[预训练模型介绍]](./docs/pre-trained_models_introduction_CN.md)
#### 简单的例子
-* 为视频添加马赛克,例子中认为脸是需要打码的区域 ,可以通过切换预训练模型切换自动打码区域(输出结果将储存到 './result')
+* 为视频添加马赛克,例子中认为脸是需要打码的区域 ,可以通过切换预训练模型切换自动打码区域(输出结果将储存到 './result')
```bash
python3 deepmosaic.py --media_path ./imgs/ruoruo.jpg --model_path ./pretrained_models/mosaic/add_face.pth --use_gpu -1
```
-* 将视频中的马赛克移除,对于不同的打码物体需要使用对应的预训练模型进行马赛克消除(输出结果将储存到 './result')
+* 将视频中的马赛克移除,对于不同的打码物体需要使用对应的预训练模型进行马赛克消除(输出结果将储存到 './result')
```bash
python3 deepmosaic.py --media_path ./result/ruoruo_add.jpg --model_path ./pretrained_models/mosaic/clean_face_HD.pth --use_gpu -1
```
#### 更多的参数
-如果想要测试其他的图片或视频,请参照以下文件输入参数.
-[[options.py]](./cores/options.py)
+如果想要测试其他的图片或视频,请参照以下文件输入参数.
+[[options_introduction_CN.md]](./docs/options_introduction_CN.md)
## 鸣谢
-代码大量的参考了以下项目:[[pytorch-CycleGAN-and-pix2pix]](https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix) [[Pytorch-UNet]](https://github.com/milesial/Pytorch-UNet)[[pix2pixHD]](https://github.com/NVIDIA/pix2pixHD)..
+代码大量的参考了以下项目:[[pytorch-CycleGAN-and-pix2pix]](https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix) [[Pytorch-UNet]](https://github.com/milesial/Pytorch-UNet)[[pix2pixHD]](https://github.com/NVIDIA/pix2pixHD).
\ No newline at end of file
diff --git a/cores/core.py b/cores/core.py
index e5ed377cf784d0f0d8c437eaf2d673d6c45df209..22a408a0cc6dec1663f83d4eff8ebe2e242356a8 100644
--- a/cores/core.py
+++ b/cores/core.py
@@ -150,7 +150,10 @@ def cleanmosaic_video_byframe(opt,netG,netM):
def cleanmosaic_video_fusion(opt,netG,netM):
path = opt.media_path
N = 25
- INPUT_SIZE = 128
+ if 'HD' in os.path.basename(opt.model_path):
+ INPUT_SIZE = 256
+ else:
+ INPUT_SIZE = 128
fps,imagepaths,height,width = video_init(opt,path)
positions = get_mosaic_positions(opt,netM,imagepaths,savemask=True)
diff --git a/cores/options.py b/cores/options.py
index cf31aacf7fb1a2319e89a29f6be75635a2a8865d..b3cb051608ad3fcf7e2e2786e2647e7cef8f01d3 100644
--- a/cores/options.py
+++ b/cores/options.py
@@ -13,36 +13,36 @@ class Options():
self.parser.add_argument('--use_gpu',type=int,default=0, help='if -1, do not use gpu')
# self.parser.add_argument('--use_gpu', action='store_true', help='if input it, use gpu')
self.parser.add_argument('--media_path', type=str, default='./imgs/ruoruo.jpg',help='your videos or images path')
- self.parser.add_argument('--mode', type=str, default='auto',help='auto | add | clean | style')
+ self.parser.add_argument('--mode', type=str, default='auto',help='Program running mode. auto | add | clean | style')
self.parser.add_argument('--model_path', type=str, default='./pretrained_models/mosaic/add_face.pth',help='pretrained model path')
self.parser.add_argument('--result_dir', type=str, default='./result',help='output media will be saved here')
self.parser.add_argument('--tempimage_type', type=str, default='png',help='type of temp image, png | jpg, png is better but occupy more storage space')
self.parser.add_argument('--netG', type=str, default='auto',
help='select model to use for netG(Clean mosaic and Transfer style) -> auto | unet_128 | unet_256 | resnet_9blocks | HD | video')
self.parser.add_argument('--fps', type=int, default=0,help='read and output fps, if 0-> origin')
- self.parser.add_argument('--output_size', type=int, default=0,help='size of output file,if 0 -> origin')
+ self.parser.add_argument('--output_size', type=int, default=0,help='size of output media, if 0 -> origin')
#AddMosaic
self.parser.add_argument('--mosaic_mod', type=str, default='squa_avg',help='type of mosaic -> squa_avg | squa_random | squa_avg_circle_edge | rect_avg | random')
self.parser.add_argument('--mosaic_size', type=int, default=0,help='mosaic size,if 0 auto size')
- self.parser.add_argument('--mask_extend', type=int, default=10,help='more mosaic area')
+ self.parser.add_argument('--mask_extend', type=int, default=10,help='extend mosaic area')
self.parser.add_argument('--mask_threshold', type=int, default=64,help='threshold of recognize mosaic position 0~255')
#CleanMosaic
self.parser.add_argument('--mosaic_position_model_path', type=str, default='auto',help='name of model use to find mosaic position')
- self.parser.add_argument('--traditional', action='store_true', help='if true, use traditional image processing methods to clean mosaic')
+ self.parser.add_argument('--traditional', action='store_true', help='if specified, use traditional image processing methods to clean mosaic')
self.parser.add_argument('--tr_blur', type=int, default=10, help='ksize of blur when using traditional method, it will affect final quality')
self.parser.add_argument('--tr_down', type=int, default=10, help='downsample when using traditional method,it will affect final quality')
- self.parser.add_argument('--no_feather', action='store_true', help='if true, no edge feather and color correction, but run faster')
- self.parser.add_argument('--all_mosaic_area', action='store_true', help='if true, find all mosaic area, else only find the largest area')
+ self.parser.add_argument('--no_feather', action='store_true', help='if specified, no edge feather and color correction, but run faster')
+ self.parser.add_argument('--all_mosaic_area', action='store_true', help='if specified, find all mosaic area, else only find the largest area')
self.parser.add_argument('--medfilt_num', type=int, default=11,help='medfilt window of mosaic movement in the video')
self.parser.add_argument('--ex_mult', type=str, default='auto',help='mosaic area expansion')
#StyleTransfer
self.parser.add_argument('--preprocess', type=str, default='resize', help='resize and cropping of images at load time [ resize | resize_scale_width | edges | gray] or resize,edges(use comma to split)')
- self.parser.add_argument('--edges', action='store_true', help='if true, use edges to generate pictures,(input_nc = 1)')
+ self.parser.add_argument('--edges', action='store_true', help='if specified, use edges to generate pictures,(input_nc = 1)')
self.parser.add_argument('--canny', type=int, default=150,help='threshold of canny')
- self.parser.add_argument('--only_edges', action='store_true', help='if true, output media will be edges')
+ self.parser.add_argument('--only_edges', action='store_true', help='if specified, output media will be edges')
self.initialized = True
@@ -67,7 +67,9 @@ class Options():
elif 'style' in model_name or 'edges' in model_name:
self.opt.mode = 'style'
else:
- print('Please input running mode!')
+ print('Please input running model!')
+ input('Please press any key to exit.\n')
+ exit(0)
if self.opt.output_size == 0 and self.opt.mode == 'style':
self.opt.output_size = 512
@@ -80,12 +82,14 @@ class Options():
self.opt.netG = 'unet_128'
elif 'resnet_9blocks' in model_name:
self.opt.netG = 'resnet_9blocks'
- elif 'HD' in model_name:
+ elif 'HD' in model_name and 'video' not in model_name:
self.opt.netG = 'HD'
elif 'video' in model_name:
self.opt.netG = 'video'
else:
print('Type of Generator error!')
+ input('Please press any key to exit.\n')
+ exit(0)
if self.opt.ex_mult == 'auto':
if 'face' in model_name:
diff --git a/deepmosaic.py b/deepmosaic.py
index dec510296deeb08d011adcaa4ea064a9d9782039..58a6031b86742ce458ecab61012a2c42a58fbef9 100644
--- a/deepmosaic.py
+++ b/deepmosaic.py
@@ -1,4 +1,6 @@
import os
+import sys
+import traceback
from cores import Options,core
from util import util
from models import loadmodel
@@ -58,12 +60,18 @@ def main():
util.clean_tempfiles(tmp_init = False)
-main()
-# if __name__ == '__main__':
-# try:
-# main()
-# except Exception as e:
-# print('Error:',e)
-# input('Please press any key to exit.\n')
-# util.clean_tempfiles(tmp_init = False)
-# exit(0)
+# main()
+if __name__ == '__main__':
+ try:
+ main()
+ except Exception as ex:
+ print('--------------------ERROR--------------------')
+ ex_type, ex_val, ex_stack = sys.exc_info()
+ print('Error Type:',ex_type)
+ print(ex_val)
+ for stack in traceback.extract_tb(ex_stack):
+ print(stack)
+ input('Please press any key to exit.\n')
+ util.clean_tempfiles(tmp_init = False)
+ exit(0)
+
diff --git a/docs/exe_help.md b/docs/exe_help.md
new file mode 100644
index 0000000000000000000000000000000000000000..1b5bc09f8cbcd57b76b99d1ba8fd1be9d6a7d97a
--- /dev/null
+++ b/docs/exe_help.md
@@ -0,0 +1,86 @@
+## DeepMosaics.exe Instructions
+[[中文版]](./exe_help_CN.md)
+This is a GUI version compiled in Windows.
+Download this version and pre-trained model via [[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
+Attentions:
+
+ - Require Windows_x86_64, Windows10 is better.
+ - Different pre-trained models are suitable for different effects.
+ - Run time depends on computer performance.
+ - If output video cannot be played, you can try with [potplayer](https://daumpotplayer.com/download/).
+ - GUI version update slower than source.
+### How to use
+* step 1: Choose image or video.
+* step 2: Choose model(Different pre-trained models are suitable for different effects)
+* step3: Run program and wait.
+* step4: Cheek reult in './result'.
+
+### Introduction to pre-trained models
+* Mosaic
+| Name | Description |
+| :------------------------------: | :---------------------------------------------------------: |
+| add_face.pth | Add mosaic to all faces in images/videos. |
+| clean_face_HD.pth | Clean mosaic to all faces in images/video.
(RAM > 8GB). |
+| add_youknow.pth | Add mosaic to all (FBI Warning) in images/videos. |
+| clean_youknow_resnet_9blocks.pth | Clean mosaic to all (FBI Warning) in images/videos. |
+| clean_youknow_video.pth | Clean mosaic to all (FBI Warning) in videos. |
+| clean_youknow_video_HD.pth | Clean mosaic to all (FBI Warning) in videos.
(RAM > 8GB) |
+
+* Style Transfer
+| Name | Description |
+| :---------------------: | :-------------------------------------------------------: |
+| style_apple2orange.pth | Convert apples to oranges. |
+| style_orange2apple.pth | Convert oranges to apples |
+| style_summer2winter.pth | Convert summer to winter. |
+| style_winter2summer.pth | Convert winter to summer. |
+| style_cezanne.pth | Convert photos/video to Paul Cézanne style. |
+| style_monet.pth | Convert photos/video to Claude Monet style. |
+| style_ukiyoe.pth | Convert photos/video to Ukiyoe style. |
+| style_vangogh.pth | Convert photos/video to Van Gogh style. |
+### Annotation
+![image](../imgs/GUI_Instructions.jpg)
+* 1. Choose image or video.
+* 2. Choose model(Different pre-trained models are suitable for different effects).
+* 3. Program running mode. (auto | add | clean | style)
+* 4. Use GPU to run deep learning model. (The current version does not support gpu, if you need to use gpu please run source).
+* 5. Limit the fps of the output video(0->original fps).
+* 6. More options.
+* 7. More options can be input.
+* 8. Run program.
+* 9. Open help file.
+* 10. Sponsor our project.
+* 11. Version information.
+* 12. Open the URL on github.
+
+### Introduction to options
+If you need more effects, use '--option your-parameters' to enter what you need.
+* Base
+| Option | Description | Default |
+| :----------: | :----------------------------------------: | :-------------------------------------: |
+| --use_gpu | if -1, do not use gpu | 0 |
+| --media_path | your videos or images path | ./imgs/ruoruo.jpg |
+| --mode | program running mode(auto/clean/add/style) | 'auto' |
+| --model_path | pretrained model path | ./pretrained_models/mosaic/add_face.pth |
+| --result_dir | output media will be saved here | ./result |
+| --fps | read and output fps, if 0-> origin | 0 |
+
+* AddMosaic
+| Option | Description | Default |
+| :--------------: | :----------------------------------------------------------: | :------: |
+| --mosaic_mod | type of mosaic -> squa_avg/ squa_random/ squa_avg_circle_edge/ rect_avg/random | squa_avg |
+| --mosaic_size | mosaic size,if 0 -> auto size | 0 |
+| --mask_extend | extend mosaic area | 10 |
+| --mask_threshold | threshold of recognize mosaic position 0~255 | 64 |
+
+* CleanMosaic
+| Option | Description | Default |
+| :-----------: | :----------------------------------------------------------: | :-----: |
+| --traditional | if specified, use traditional image processing methods to clean mosaic | |
+| --tr_blur | ksize of blur when using traditional method, it will affect final quality | 10 |
+| --tr_down | downsample when using traditional method,it will affect final quality | 10 |
+| --medfilt_num | medfilt window of mosaic movement in the video | 11 |
+
+* Style Transfer
+| Option | Description | Default |
+| :-----------: | :----------------------------------: | :-----: |
+| --output_size | size of output media, if 0 -> origin | 512 |
\ No newline at end of file
diff --git a/docs/exe_help_CN.md b/docs/exe_help_CN.md
new file mode 100644
index 0000000000000000000000000000000000000000..69624d48f2f1a5386f5567e49d0845386696656a
--- /dev/null
+++ b/docs/exe_help_CN.md
@@ -0,0 +1,85 @@
+## DeepMosaics.exe 使用说明
+下载程序以及预训练模型 [[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
+注意事项:
+
+ - 程序的运行要求在64位Windows操作系统,我仅在Windows10运行过,其他版本暂未经过测试
+ - 请根据需求选择合适的预训练模型进行测试
+ - 运行时间取决于电脑性能,对于视频文件,我们建议使用源码以及GPU运行
+ - 如果输出的视频无法播放,这边建议您尝试[potplayer](https://daumpotplayer.com/download/).
+ - 相比于源码,该版本的更新将会延后.
+
+### 如何使用
+* step 1: 选择需要处理的图片或视频
+* step 2: 选择预训练模型(不同的预训练模型有不同的效果)
+* step3: 运行程序并等待
+* step4: 查看结果(储存在result文件夹下)
+
+## 预训练模型说明
+当前的预训练模型分为两类——添加/移除马赛克以及风格转换.
+
+* 马赛克
+| 文件名 | 描述 |
+| :------------------------------: | :-------------------------------------------: |
+| add_face.pth | 对图片或视频中的脸部打码 |
+| clean_face_HD.pth | 对图片或视频中的脸部去码
(要求内存 > 8GB). |
+| add_youknow.pth | 对图片或视频中的十八禁内容打码 |
+| clean_youknow_resnet_9blocks.pth | 对图片或视频中的十八禁内容去码 |
+| clean_youknow_video.pth | 对视频中的十八禁内容去码 |
+| clean_youknow_video_HD.pth | 对视频中的十八禁内容去码
(要求内存 > 8GB) |
+
+* 风格转换
+| 文件名 | 描述 |
+| :---------------------: | :-------------------------------------------------------: |
+| style_apple2orange.pth | 苹果变橙子 |
+| style_orange2apple.pth | 橙子变苹果 |
+| style_summer2winter.pth | 夏天变冬天 |
+| style_winter2summer.pth | 冬天变夏天 |
+| style_cezanne.pth | 转化为Paul Cézanne 的绘画风格 |
+| style_monet.pth | 转化为Claude Monet的绘画风格 |
+| style_ukiyoe.pth | 转化为Ukiyoe的绘画风格 |
+| style_vangogh.pth | 转化为Van Gogh的绘画风格 |
+
+### GUI界面注释
+![image](../imgs/GUI_Instructions.jpg)
+* 1. 选择需要处理的图片或视频
+* 2. 选择预训练模型
+* 3. 程序运行模式 (auto | add | clean | style)
+* 4. 使用GPU (该版本目前不支持GPU,若需要使用GPU请使用源码运行).
+* 5. 限制输出的视频帧率(0->原始帧率).
+* 6. 更多的选项以及参数
+* 7. 自行输入更多参数,详见下文
+* 8. 运行
+* 9. 打开帮助文件
+* 10. 支持我们
+* 11. 版本信息
+* 12. 打开项目的github页面
+
+### 参数说明
+如果需要更多的效果, 请按照 '--option your-parameters' 输入所需要的参数
+* 基本
+| 选项 | 描述 | 默认 |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --use_gpu | if -1, do not use gpu | 0 |
+| --media_path | 需要处理的视频或者照片的路径 | ./imgs/ruoruo.jpg |
+| --mode | 运行模式(auto/clean/add/style) | 'auto' |
+| --model_path | 预训练模型的路径 | ./pretrained_models/mosaic/add_face.pth |
+| --result_dir | 保存路径 | ./result |
+| --fps | 限制视频输出的fps,0则为默认 | 0 |
+* 添加马赛克
+| 选项 | 描述 | 默认 |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --mosaic_mod | 马赛克类型 -> squa_avg/ squa_random/ squa_avg_circle_edge/ rect_avg/random | squa_avg |
+| --mosaic_size | 马赛克大小,0则为自动 | 0 |
+| --mask_extend | 拓展马赛克区域 | 10 |
+| --mask_threshold | 马赛克区域识别阈值 0~255 | 64 |
+* 去除马赛克
+| 选项 | 描述 | 默认 |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --traditional | 如果输入这个参数则使用传统方法清除马赛克 | |
+| --tr_blur | 传统方法模糊尺寸 | 10 |
+| --tr_down | 传统方法下采样尺寸 | 10 |
+| --medfilt_num | medfilt window of mosaic movement in the video | 11 |
+* 风格转换
+| 选项 | 描述 | 默认 |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --output_size | 输出媒体的尺寸,如果是0则为原始尺寸 |512|
\ No newline at end of file
diff --git a/docs/options_introduction.md b/docs/options_introduction.md
new file mode 100644
index 0000000000000000000000000000000000000000..c8cfa66885445c9f12ce0fd204d7c25b58264304
--- /dev/null
+++ b/docs/options_introduction.md
@@ -0,0 +1,33 @@
+## Introduction to options
+If you need more effects, use '--option your-parameters' to enter what you need.
+
+### Base
+| Option | Description | Default |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --use_gpu | if -1, do not use gpu | 0 |
+| --media_path | your videos or images path | ./imgs/ruoruo.jpg |
+| --mode | program running mode(auto/clean/add/style) | 'auto' |
+| --model_path | pretrained model path | ./pretrained_models/mosaic/add_face.pth |
+| --result_dir | output media will be saved here| ./result |
+| --fps | read and output fps, if 0-> origin | 0 |
+
+### AddMosaic
+| Option | Description | Default |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --mosaic_mod | type of mosaic -> squa_avg/ squa_random/ squa_avg_circle_edge/ rect_avg/random | squa_avg |
+| --mosaic_size | mosaic size,if 0 -> auto size | 0 |
+| --mask_extend | extend mosaic area | 10 |
+| --mask_threshold | threshold of recognize mosaic position 0~255 | 64 |
+
+### CleanMosaic
+| Option | Description | Default |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --traditional | if specified, use traditional image processing methods to clean mosaic | |
+| --tr_blur | ksize of blur when using traditional method, it will affect final quality | 10 |
+| --tr_down | downsample when using traditional method,it will affect final quality | 10 |
+| --medfilt_num | medfilt window of mosaic movement in the video | 11 |
+
+### Style Transfer
+| Option | Description | Default |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --output_size | size of output media, if 0 -> origin |512|
\ No newline at end of file
diff --git a/docs/options_introduction_CN.md b/docs/options_introduction_CN.md
new file mode 100644
index 0000000000000000000000000000000000000000..f40f4884ea7ac79419215e47a60c5a72690eeb76
--- /dev/null
+++ b/docs/options_introduction_CN.md
@@ -0,0 +1,33 @@
+## 参数说明
+如果需要更多的效果, 请按照 '--option your-parameters' 输入所需要的参数
+
+### 基本
+| 选项 | 描述 | 默认 |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --use_gpu | if -1, do not use gpu | 0 |
+| --media_path | 需要处理的视频或者照片的路径 | ./imgs/ruoruo.jpg |
+| --mode | 运行模式(auto/clean/add/style) | 'auto' |
+| --model_path | 预训练模型的路径 | ./pretrained_models/mosaic/add_face.pth |
+| --result_dir | 保存路径 | ./result |
+| --fps | 限制视频输出的fps,0则为默认 | 0 |
+
+### 添加马赛克
+| 选项 | 描述 | 默认 |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --mosaic_mod | 马赛克类型 -> squa_avg/ squa_random/ squa_avg_circle_edge/ rect_avg/random | squa_avg |
+| --mosaic_size | 马赛克大小,0则为自动 | 0 |
+| --mask_extend | 拓展马赛克区域 | 10 |
+| --mask_threshold | 马赛克区域识别阈值 0~255 | 64 |
+
+### 去除马赛克
+| 选项 | 描述 | 默认 |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --traditional | 如果输入这个参数则使用传统方法清除马赛克 | |
+| --tr_blur | 传统方法模糊尺寸 | 10 |
+| --tr_down | 传统方法下采样尺寸 | 10 |
+| --medfilt_num | medfilt window of mosaic movement in the video | 11 |
+
+### 风格转换
+| 选项 | 描述 | 默认 |
+| :----------: | :------------------------: | :-------------------------------------: |
+| --output_size | 输出媒体的尺寸,如果是0则为原始尺寸 |512|
\ No newline at end of file
diff --git a/docs/pre-trained_models_introduction.md b/docs/pre-trained_models_introduction.md
new file mode 100644
index 0000000000000000000000000000000000000000..a74355dab7f2343eed5402c3d8dbac399d056899
--- /dev/null
+++ b/docs/pre-trained_models_introduction.md
@@ -0,0 +1,26 @@
+## Introduction to pre-trained models
+The current pre-trained models are divided into two categories(Add/Clean mosaic and StyleTransfer).
+Download pre-trained model via [[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
+
+### Mosaic
+| Name | Description |
+| :------------------------------: | :---------------------------------------------------------: |
+| add_face.pth | Add mosaic to all faces in images/videos. |
+| clean_face_HD.pth | Clean mosaic to all faces in images/video.
(RAM > 8GB). |
+| add_youknow.pth | Add mosaic to all (FBI Warning) in images/videos. |
+| clean_youknow_resnet_9blocks.pth | Clean mosaic to all (FBI Warning) in images/videos. |
+| clean_youknow_video.pth | Clean mosaic to all (FBI Warning) in videos. |
+| clean_youknow_video_HD.pth | Clean mosaic to all (FBI Warning) in videos.
(RAM > 8GB) |
+
+### Style Transfer
+| Name | Description |
+| :---------------------: | :-------------------------------------------------------: |
+| style_apple2orange.pth | Convert apples to oranges. |
+| style_orange2apple.pth | Convert oranges to apples |
+| style_summer2winter.pth | Convert summer to winter. |
+| style_winter2summer.pth | Convert winter to summer. |
+| style_cezanne.pth | Convert photos/video to Paul Cézanne style. |
+| style_monet.pth | Convert photos/video to Claude Monet style. |
+| style_ukiyoe.pth | Convert photos/video to Ukiyoe style. |
+| style_vangogh.pth | Convert photos/video to Van Gogh style. |
+
diff --git a/docs/pre-trained_models_introduction_CN.md b/docs/pre-trained_models_introduction_CN.md
new file mode 100644
index 0000000000000000000000000000000000000000..95162d827fb5d8890f0a82670f5589bdc3b546c7
--- /dev/null
+++ b/docs/pre-trained_models_introduction_CN.md
@@ -0,0 +1,26 @@
+## 预训练模型说明
+当前的预训练模型分为两类——添加/移除马赛克以及风格转换.
+可以通过以下方式下载预训练模型 [[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
+
+### 马赛克
+| 文件名 | 描述 |
+| :------------------------------: | :-------------------------------------------: |
+| add_face.pth | 对图片或视频中的脸部打码 |
+| clean_face_HD.pth | 对图片或视频中的脸部去码
(要求内存 > 8GB). |
+| add_youknow.pth | 对图片或视频中的十八禁内容打码 |
+| clean_youknow_resnet_9blocks.pth | 对图片或视频中的十八禁内容去码 |
+| clean_youknow_video.pth | 对视频中的十八禁内容去码 |
+| clean_youknow_video_HD.pth | 对视频中的十八禁内容去码
(要求内存 > 8GB) |
+
+### 风格转换
+| 文件名 | 描述 |
+| :---------------------: | :-------------------------------------------------------: |
+| style_apple2orange.pth | 苹果变橙子 |
+| style_orange2apple.pth | 橙子变苹果 |
+| style_summer2winter.pth | 夏天变冬天 |
+| style_winter2summer.pth | 冬天变夏天 |
+| style_cezanne.pth | 转化为Paul Cézanne 的绘画风格 |
+| style_monet.pth | 转化为Claude Monet的绘画风格 |
+| style_ukiyoe.pth | 转化为Ukiyoe的绘画风格 |
+| style_vangogh.pth | 转化为Van Gogh的绘画风格 |
+
diff --git a/imgs/GUI.png b/imgs/GUI.png
index e9ffe2423665e63eb4db0e2e1e040c0dd3883508..7404e3bb52995fe04c352965f75f0ff35535c69e 100644
Binary files a/imgs/GUI.png and b/imgs/GUI.png differ
diff --git a/imgs/GUI_Instructions.jpg b/imgs/GUI_Instructions.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..600815241b6a3d3e4bfe5465af0ddf43f6873744
Binary files /dev/null and b/imgs/GUI_Instructions.jpg differ
diff --git a/imgs/example/SZU.jpg b/imgs/example/SZU.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..12c38a3a2d476fe4e9d48357214edde3a832f6df
Binary files /dev/null and b/imgs/example/SZU.jpg differ
diff --git a/imgs/example/SZU_summer2winter.jpg b/imgs/example/SZU_summer2winter.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..49af7fcc9e3ea8445c7b3841ff1d4e246f1693d2
Binary files /dev/null and b/imgs/example/SZU_summer2winter.jpg differ
diff --git a/imgs/example/SZU_vangogh.jpg b/imgs/example/SZU_vangogh.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d6d7ec0a1501704f7ef41e9275c27df1cda00826
Binary files /dev/null and b/imgs/example/SZU_vangogh.jpg differ
diff --git a/imgs/example/a_dcp.png b/imgs/example/a_dcp.png
new file mode 100644
index 0000000000000000000000000000000000000000..0450dc021f4391b099d4804ca611c615b180ae47
Binary files /dev/null and b/imgs/example/a_dcp.png differ
diff --git a/imgs/example/b_dcp.png b/imgs/example/b_dcp.png
new file mode 100644
index 0000000000000000000000000000000000000000..2095c71b566444de2a3e5f91ce974cfb1a0dd0f1
Binary files /dev/null and b/imgs/example/b_dcp.png differ
diff --git a/imgs/example/face_a_clean.jpg b/imgs/example/face_a_clean.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f00efca8faa195b6f6fe978fccb4f9e0bdab859e
Binary files /dev/null and b/imgs/example/face_a_clean.jpg differ
diff --git a/imgs/example/face_a_mosaic.jpg b/imgs/example/face_a_mosaic.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a898e6a40fd0d78c9b4dad8c1b3e037735609b62
Binary files /dev/null and b/imgs/example/face_a_mosaic.jpg differ
diff --git a/imgs/example/face_b_clean.jpg b/imgs/example/face_b_clean.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..432285fb7f5dcfa8711b91d499d8d7d7ec008d5a
Binary files /dev/null and b/imgs/example/face_b_clean.jpg differ
diff --git a/imgs/example/face_b_mosaic.jpg b/imgs/example/face_b_mosaic.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..8aabdacd38b79c086fccbc777d6ba9404fb6ea3c
Binary files /dev/null and b/imgs/example/face_b_mosaic.jpg differ
diff --git a/imgs/example/lena.jpg b/imgs/example/lena.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..bf55198823d616f1a8b8d9508cdfd4b97e8f31db
Binary files /dev/null and b/imgs/example/lena.jpg differ
diff --git a/imgs/example/lena_add.jpg b/imgs/example/lena_add.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..871a14c08a103549ce5b7ae4d20f2bd1b052e2bf
Binary files /dev/null and b/imgs/example/lena_add.jpg differ
diff --git a/imgs/example/lena_clean.jpg b/imgs/example/lena_clean.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..bfb97107c9214301089a0f018cb0523ba6e16e79
Binary files /dev/null and b/imgs/example/lena_clean.jpg differ
diff --git a/imgs/example/youknow.png b/imgs/example/youknow.png
new file mode 100644
index 0000000000000000000000000000000000000000..9b27ebb231757fb21e4f43a788630ad9fe5f154b
Binary files /dev/null and b/imgs/example/youknow.png differ
diff --git a/imgs/example/youknow_add.png b/imgs/example/youknow_add.png
new file mode 100644
index 0000000000000000000000000000000000000000..17cb4c0ac55025b46b3d5d1a24584ca629dbcf52
Binary files /dev/null and b/imgs/example/youknow_add.png differ
diff --git a/imgs/example/youknow_clean.png b/imgs/example/youknow_clean.png
new file mode 100644
index 0000000000000000000000000000000000000000..d6dad64d7c68b3af20d4a2f34587929263e16545
Binary files /dev/null and b/imgs/example/youknow_clean.png differ
diff --git a/models/loadmodel.py b/models/loadmodel.py
index 6257da075bd0919180395ce342609882bbb8bc36..00607d7970add0e373be78279c091e31a45fcd34 100755
--- a/models/loadmodel.py
+++ b/models/loadmodel.py
@@ -3,6 +3,7 @@ from .pix2pix_model import define_G
from .pix2pixHD_model import define_G as define_G_HD
from .unet_model import UNet
from .video_model import MosaicNet
+from .videoHD_model import MosaicNet as MosaicNet_HD
def show_paramsnumber(net,netname='net'):
parameters = sum(param.numel() for param in net.parameters())
@@ -63,7 +64,10 @@ def style(opt):
return netG
def video(opt):
- netG = MosaicNet(3*25+1, 3,norm = 'batch')
+ if 'HD' in opt.model_path:
+ netG = MosaicNet_HD(3*25+1, 3, norm='instance')
+ else:
+ netG = MosaicNet(3*25+1, 3,norm = 'batch')
show_paramsnumber(netG,'netG')
netG.load_state_dict(torch.load(opt.model_path))
netG.eval()
diff --git a/models/videoHD_model.py b/models/videoHD_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f214c50daf398b55184c759a59d64cd8dd7bb0e
--- /dev/null
+++ b/models/videoHD_model.py
@@ -0,0 +1,183 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from .pix2pixHD_model import *
+
+
+class encoder_2d(nn.Module):
+ def __init__(self, input_nc, output_nc, ngf=64, n_downsampling=3, n_blocks=9, norm_layer=nn.BatchNorm2d,
+ padding_type='reflect'):
+ assert(n_blocks >= 0)
+ super(encoder_2d, self).__init__()
+ activation = nn.ReLU(True)
+
+ model = [nn.ReflectionPad2d(3), nn.Conv2d(input_nc, ngf, kernel_size=7, padding=0), norm_layer(ngf), activation]
+ ### downsample
+ for i in range(n_downsampling):
+ mult = 2**i
+ model += [nn.Conv2d(ngf * mult, ngf * mult * 2, kernel_size=3, stride=2, padding=1),
+ norm_layer(ngf * mult * 2), activation]
+
+ self.model = nn.Sequential(*model)
+ def forward(self, input):
+ return self.model(input)
+
+class decoder_2d(nn.Module):
+ def __init__(self, input_nc, output_nc, ngf=64, n_downsampling=3, n_blocks=9, norm_layer=nn.BatchNorm2d,
+ padding_type='reflect'):
+ assert(n_blocks >= 0)
+ super(decoder_2d, self).__init__()
+ activation = nn.ReLU(True)
+
+ model = []
+
+ ### resnet blocks
+ mult = 2**n_downsampling
+ for i in range(n_blocks):
+ model += [ResnetBlock(ngf * mult, padding_type=padding_type, activation=activation, norm_layer=norm_layer)]
+
+ ### upsample
+ for i in range(n_downsampling):
+ mult = 2**(n_downsampling - i)
+ # if i%2 ==0:
+ # model += [ nn.Upsample(scale_factor = 2, mode='nearest'),
+ # nn.ReflectionPad2d(1),
+ # nn.Conv2d(ngf * mult, int(ngf * mult / 2),kernel_size=3, stride=1, padding=0),
+ # norm_layer(int(ngf * mult / 2)),
+ # nn.ReLU(True)]
+ # else:
+
+ # model += [nn.ConvTranspose2d(ngf * mult, int(ngf * mult / 2), kernel_size=3, stride=2, padding=1, output_padding=1),
+ # norm_layer(int(ngf * mult / 2)), activation]
+
+ # model += [ nn.Upsample(scale_factor = 2, mode='nearest'),
+ # nn.ReflectionPad2d(1),
+ # nn.Conv2d(ngf * mult, int(ngf * mult / 2),kernel_size=3, stride=1, padding=0),
+ # norm_layer(int(ngf * mult / 2)),
+ # nn.ReLU(True)]
+ model += [nn.ConvTranspose2d(ngf * mult, int(ngf * mult / 2), kernel_size=3, stride=2, padding=1, output_padding=1),
+ norm_layer(int(ngf * mult / 2)), activation]
+ model += [nn.ReflectionPad2d(3), nn.Conv2d(ngf, output_nc, kernel_size=7, padding=0), nn.Tanh()]
+ self.model = nn.Sequential(*model)
+
+ def forward(self, input):
+ return self.model(input)
+
+
+class conv_3d(nn.Module):
+ def __init__(self,inchannel,outchannel,kernel_size=3,stride=2,padding=1,norm_layer_3d=nn.BatchNorm3d,use_bias=True):
+ super(conv_3d, self).__init__()
+ self.conv = nn.Sequential(
+ nn.Conv3d(inchannel, outchannel, kernel_size=kernel_size, stride=stride, padding=padding, bias=use_bias),
+ norm_layer_3d(outchannel),
+ nn.ReLU(inplace=True),
+ )
+
+ def forward(self, x):
+ x = self.conv(x)
+ return x
+
+class conv_2d(nn.Module):
+ def __init__(self,inchannel,outchannel,kernel_size=3,stride=1,padding=1,norm_layer_2d=nn.BatchNorm2d,use_bias=True):
+ super(conv_2d, self).__init__()
+ self.conv = nn.Sequential(
+ nn.ReflectionPad2d(padding),
+ nn.Conv2d(inchannel, outchannel, kernel_size=kernel_size, stride=stride, padding=0, bias=use_bias),
+ norm_layer_2d(outchannel),
+ nn.ReLU(inplace=True),
+ )
+
+ def forward(self, x):
+ x = self.conv(x)
+ return x
+
+
+class encoder_3d(nn.Module):
+ def __init__(self,in_channel,norm_layer_2d,norm_layer_3d,use_bias):
+ super(encoder_3d, self).__init__()
+ self.inconv = conv_3d(1, 64, 7, 2, 3,norm_layer_3d,use_bias)
+ self.down1 = conv_3d(64, 128, 3, 2, 1,norm_layer_3d,use_bias)
+ self.down2 = conv_3d(128, 256, 3, 2, 1,norm_layer_3d,use_bias)
+ self.down3 = conv_3d(256, 512, 3, 2, 1,norm_layer_3d,use_bias)
+ self.down4 = conv_3d(512, 1024, 3, 1, 1,norm_layer_3d,use_bias)
+ self.pool = nn.AvgPool3d((5,1,1))
+ # self.conver2d = nn.Sequential(
+ # nn.Conv2d(256*int(in_channel/4), 256, kernel_size=3, stride=1, padding=1, bias=use_bias),
+ # norm_layer_2d(256),
+ # nn.ReLU(inplace=True),
+ # )
+
+
+ def forward(self, x):
+
+ x = x.view(x.size(0),1,x.size(1),x.size(2),x.size(3))
+ x = self.inconv(x)
+ x = self.down1(x)
+ x = self.down2(x)
+ x = self.down3(x)
+ x = self.down4(x)
+ #print(x.size())
+ x = self.pool(x)
+ #print(x.size())
+ # torch.Size([1, 1024, 16, 16])
+ # torch.Size([1, 512, 5, 16, 16])
+
+
+ x = x.view(x.size(0),x.size(1),x.size(3),x.size(4))
+
+ # x = self.conver2d(x)
+
+ return x
+
+ # def __init__(self, input_nc, output_nc, ngf=64, n_downsampling=3, n_blocks=9, norm_layer=nn.BatchNorm2d,
+ # padding_type='reflect')
+
+class ALL(nn.Module):
+ def __init__(self, in_channel, out_channel,norm_layer_2d,norm_layer_3d,use_bias):
+ super(ALL, self).__init__()
+
+ self.encoder_2d = encoder_2d(4,3,64,4,norm_layer=norm_layer_2d,padding_type='reflect')
+ self.encoder_3d = encoder_3d(in_channel,norm_layer_2d,norm_layer_3d,use_bias)
+ self.decoder_2d = decoder_2d(4,3,64,4,norm_layer=norm_layer_2d,padding_type='reflect')
+ # self.shortcut_cov = conv_2d(3,64,7,1,3,norm_layer_2d,use_bias)
+ self.merge1 = conv_2d(2048,1024,3,1,1,norm_layer_2d,use_bias)
+ # self.merge2 = nn.Sequential(
+ # conv_2d(128,64,3,1,1,norm_layer_2d,use_bias),
+ # nn.ReflectionPad2d(3),
+ # nn.Conv2d(64, out_channel, kernel_size=7, padding=0),
+ # nn.Tanh()
+ # )
+
+ def forward(self, x):
+
+ N = int((x.size()[1])/3)
+ x_2d = torch.cat((x[:,int((N-1)/2)*3:(int((N-1)/2)+1)*3,:,:], x[:,N-1:N,:,:]), 1)
+ #shortcut_2d = x[:,int((N-1)/2)*3:(int((N-1)/2)+1)*3,:,:]
+
+ x_2d = self.encoder_2d(x_2d)
+ x_3d = self.encoder_3d(x)
+ #x = x_2d + x_3d
+ x = torch.cat((x_2d,x_3d),1)
+ x = self.merge1(x)
+
+ x = self.decoder_2d(x)
+ #shortcut_2d = self.shortcut_cov(shortcut_2d)
+ #x = torch.cat((x,shortcut_2d),1)
+ #x = self.merge2(x)
+
+ return x
+
+def MosaicNet(in_channel, out_channel, norm='batch'):
+
+ if norm == 'batch':
+ # norm_layer_2d = nn.BatchNorm2d
+ # norm_layer_3d = nn.BatchNorm3d
+ norm_layer_2d = functools.partial(nn.BatchNorm2d, affine=True, track_running_stats=True)
+ norm_layer_3d = functools.partial(nn.BatchNorm3d, affine=True, track_running_stats=True)
+ use_bias = False
+ elif norm == 'instance':
+ norm_layer_2d = functools.partial(nn.InstanceNorm2d, affine=False, track_running_stats=False)
+ norm_layer_3d = functools.partial(nn.InstanceNorm3d, affine=False, track_running_stats=False)
+ use_bias = True
+
+ return ALL(in_channel, out_channel, norm_layer_2d, norm_layer_3d, use_bias)
diff --git a/train/clean/train.py b/train/clean/train.py
index 962aeeb12cb13e1df7f0a36395932adea649f850..102d08aaa635ac21ecde069eaf2a6ca822732ae7 100644
--- a/train/clean/train.py
+++ b/train/clean/train.py
@@ -16,12 +16,17 @@ from models import pix2pix_model,pix2pixHD_model,video_model,unet_model,loadmode
from matplotlib import pyplot as plt
import torch.backends.cudnn as cudnn
+'''
+--------------------------Get options--------------------------
+'''
+
opt = Options()
opt.parser.add_argument('--N',type=int,default=25, help='')
opt.parser.add_argument('--lr',type=float,default=0.0002, help='')
opt.parser.add_argument('--beta1',type=float,default=0.5, help='')
-opt.parser.add_argument('--gan', action='store_true', help='if input it, use gan')
-opt.parser.add_argument('--l2', action='store_true', help='if input it, use L2 loss')
+opt.parser.add_argument('--gan', action='store_true', help='if specified, use gan')
+opt.parser.add_argument('--l2', action='store_true', help='if specified, use L2 loss')
+opt.parser.add_argument('--hd', action='store_true', help='if specified, use HD model')
opt.parser.add_argument('--lambda_L1',type=float,default=100, help='')
opt.parser.add_argument('--lambda_gan',type=float,default=1, help='')
opt.parser.add_argument('--finesize',type=int,default=256, help='')
@@ -36,6 +41,10 @@ opt.parser.add_argument('--startiter',type=int,default=0, help='')
opt.parser.add_argument('--continuetrain', action='store_true', help='')
opt.parser.add_argument('--savename',type=str,default='MosaicNet', help='')
+
+'''
+--------------------------Init--------------------------
+'''
opt = opt.getparse()
dir_checkpoint = os.path.join('checkpoints/',opt.savename)
util.makedirs(dir_checkpoint)
@@ -54,17 +63,18 @@ print('check dataset...')
for video in videos:
video_images = os.listdir('./dataset/'+video+'/ori')
lengths.append(len(video_images))
-#unet_128
-#resnet_9blocks
-#netG = pix2pix_model.define_G(3*N+1, 3, 128, 'resnet_6blocks', norm='instance',use_dropout=True, init_type='normal', gpu_ids=[])
-netG = videoHD_model.MosaicNet(3*N+1, 3, norm=opt.norm)
+if opt.hd:
+ netG = videoHD_model.MosaicNet(3*N+1, 3, norm=opt.norm)
+else:
+ netG = video_model.MosaicNet(3*N+1, 3, norm=opt.norm)
loadmodel.show_paramsnumber(netG,'netG')
-# netG = unet_model.UNet(3*N+1, 3)
+
if opt.gan:
- netD = pix2pixHD_model.define_D(6, 64, 3, norm=opt.norm, use_sigmoid=False, num_D=2)
- #netD = pix2pix_model.define_D(3*2+1, 64, 'pixel', norm='instance')
- #netD = pix2pix_model.define_D(3*2, 64, 'basic', norm='instance')
- #netD = pix2pix_model.define_D(3*2+1, 64, 'n_layers', n_layers_D=5, norm='instance')
+ if opt.hd:
+ netD = pix2pixHD_model.define_D(6, 64, 3, norm = opt.norm, use_sigmoid=False, num_D=2)
+ else:
+ netD = pix2pix_model.define_D(3*2, 64, 'basic', norm = opt.norm)
+ netD.train()
if opt.continuetrain:
if not os.path.isfile(os.path.join(dir_checkpoint,'last_G.pth')):
@@ -82,10 +92,11 @@ optimizer_G = torch.optim.Adam(netG.parameters(), lr=opt.lr,betas=(opt.beta1, 0.
criterion_L1 = nn.L1Loss()
criterion_L2 = nn.MSELoss()
if opt.gan:
- optimizer_D = torch.optim.Adam(netG.parameters(), lr=opt.lr,betas=(opt.beta1, 0.999))
- # criterionGAN = pix2pix_model.GANLoss(gan_mode='lsgan').cuda()
- criterionGAN = pix2pixHD_model.GANLoss(tensor=torch.cuda.FloatTensor)
- netD.train()
+ optimizer_D = torch.optim.Adam(netD.parameters(), lr=opt.lr,betas=(opt.beta1, 0.999))
+ if opt.hd:
+ criterionGAN = pix2pixHD_model.GANLoss(tensor=torch.cuda.FloatTensor)
+ else:
+ criterionGAN = pix2pix_model.GANLoss(gan_mode='lsgan').cuda()
if opt.use_gpu:
netG.cuda()
@@ -94,6 +105,9 @@ if opt.use_gpu:
criterionGAN.cuda()
cudnn.benchmark = True
+'''
+--------------------------preload data--------------------------
+'''
def loaddata():
video_index = random.randint(0,len(videos)-1)
video = videos[video_index]
@@ -136,19 +150,19 @@ def preload():
# time.sleep(0.1)
except Exception as e:
print("error:",e)
-
import threading
t = threading.Thread(target=preload,args=()) #t为新创建的线程
t.daemon = True
t.start()
-
time_start=time.time()
while load_cnt < opt.perload_num:
time.sleep(0.1)
time_end=time.time()
print('load speed:',round((time_end-time_start)/opt.perload_num,3),'s/it')
-
+'''
+--------------------------train--------------------------
+'''
util.copyfile('./train.py', os.path.join(dir_checkpoint,'train.py'))
util.copyfile('../../models/videoHD_model.py', os.path.join(dir_checkpoint,'model.py'))
netG.train()
@@ -222,7 +236,7 @@ for iter in range(opt.startiter+1,opt.maxiter):
target, pred,os.path.join(dir_checkpoint,'result_train.jpg'))
except Exception as e:
print(e)
-
+ # plot
if (iter+1)%1000 == 0:
time_end = time.time()
if opt.gan:
@@ -255,7 +269,7 @@ for iter in range(opt.startiter+1,opt.maxiter):
loss_sum = [0.,0.,0.,0.]
time_start=time.time()
-
+ # save network
if (iter+1)%opt.savefreq == 0:
if iter+1 != opt.savefreq:
os.rename(os.path.join(dir_checkpoint,'last_G.pth'),os.path.join(dir_checkpoint,str(iter+1-opt.savefreq)+'G.pth'))
@@ -274,31 +288,32 @@ for iter in range(opt.startiter+1,opt.maxiter):
print('network saved.')
#test
- netG.eval()
-
- test_names = os.listdir('./test')
- test_names.sort()
- result = np.zeros((opt.finesize*2,opt.finesize*len(test_names),3), dtype='uint8')
+ if os.path.isdir('./test'):
+ netG.eval()
+
+ test_names = os.listdir('./test')
+ test_names.sort()
+ result = np.zeros((opt.finesize*2,opt.finesize*len(test_names),3), dtype='uint8')
- for cnt,test_name in enumerate(test_names,0):
- img_names = os.listdir(os.path.join('./test',test_name,'image'))
- img_names.sort()
- inputdata = np.zeros((opt.finesize,opt.finesize,3*N+1), dtype='uint8')
- for i in range(0,N):
- img = impro.imread(os.path.join('./test',test_name,'image',img_names[i]))
- img = impro.resize(img,opt.finesize)
- inputdata[:,:,i*3:(i+1)*3] = img
+ for cnt,test_name in enumerate(test_names,0):
+ img_names = os.listdir(os.path.join('./test',test_name,'image'))
+ img_names.sort()
+ inputdata = np.zeros((opt.finesize,opt.finesize,3*N+1), dtype='uint8')
+ for i in range(0,N):
+ img = impro.imread(os.path.join('./test',test_name,'image',img_names[i]))
+ img = impro.resize(img,opt.finesize)
+ inputdata[:,:,i*3:(i+1)*3] = img
- mask = impro.imread(os.path.join('./test',test_name,'mask.png'),'gray')
- mask = impro.resize(mask,opt.finesize)
- mask = impro.mask_threshold(mask,15,128)
- inputdata[:,:,-1] = mask
- result[0:opt.finesize,opt.finesize*cnt:opt.finesize*(cnt+1),:] = inputdata[:,:,int((N-1)/2)*3:(int((N-1)/2)+1)*3]
- inputdata = data.im2tensor(inputdata,bgr2rgb=False,use_gpu=opt.use_gpu,use_transform = False,is0_1 = False)
- pred = netG(inputdata)
-
- pred = data.tensor2im(pred,rgb2bgr = False, is0_1 = False)
- result[opt.finesize:opt.finesize*2,opt.finesize*cnt:opt.finesize*(cnt+1),:] = pred
+ mask = impro.imread(os.path.join('./test',test_name,'mask.png'),'gray')
+ mask = impro.resize(mask,opt.finesize)
+ mask = impro.mask_threshold(mask,15,128)
+ inputdata[:,:,-1] = mask
+ result[0:opt.finesize,opt.finesize*cnt:opt.finesize*(cnt+1),:] = inputdata[:,:,int((N-1)/2)*3:(int((N-1)/2)+1)*3]
+ inputdata = data.im2tensor(inputdata,bgr2rgb=False,use_gpu=opt.use_gpu,use_transform = False,is0_1 = False)
+ pred = netG(inputdata)
+
+ pred = data.tensor2im(pred,rgb2bgr = False, is0_1 = False)
+ result[opt.finesize:opt.finesize*2,opt.finesize*cnt:opt.finesize*(cnt+1),:] = pred
- cv2.imwrite(os.path.join(dir_checkpoint,str(iter+1)+'_test.jpg'), result)
- netG.train()
+ cv2.imwrite(os.path.join(dir_checkpoint,str(iter+1)+'_test.jpg'), result)
+ netG.train()