diff --git a/.gitignore b/.gitignore
index a02b7680b04cd558509843ee11afe0ebe3e80775..c273a7a8b1801851134b1bdea565d76d4ad77c2a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -142,8 +142,9 @@ test*
video_tmp/
result/
nohup.out
+.vscode/
+
#./
-/.vscode
/pix2pix
/pix2pixHD
/tmp
@@ -157,6 +158,7 @@ nohup.out
/deepmosaic_window
/sftp-config.json
/exe
+
#./make_datasets
/make_datasets/video
/make_datasets/tmp
@@ -172,6 +174,7 @@ nohup.out
#mediafile
*iter
*.pth
+*.pt
*.jpeg
*.bmp
*.mp4
@@ -185,4 +188,39 @@ nohup.out
*.JPEG
*.exe
*.npy
-*.psd
\ No newline at end of file
+*.psd
+
+
+##############################cpp###################################
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
\ No newline at end of file
diff --git a/README.md b/README.md
index 9ebb067932e4067dd80ec712025db54969c42519..371329ab2a2d1e65c92a128ad686ff05da533ec0 100755
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@ You can use it to automatically remove the mosaics in images and videos, or add
### Examples
![image](./imgs/hand.gif)
+
origin | auto add mosaic | auto clean mosaic
:-:|:-:|:-:
![image](./imgs/example/lena.jpg) | ![image](./imgs/example/lena_add.jpg) | ![image](./imgs/example/lena_clean.jpg)
@@ -33,7 +34,7 @@ An interesting example:[Ricardo Milos to cat](https://www.bilibili.com/video/BV1
You can either run DeepMosaics via a pre-built binary package, or from source.
### Try it on web
-You can simply try to remove the mosaic on the face at this [website](http://118.89.27.46:5000/).
+You can simply try to remove the mosaic on the **face** at this [website](http://118.89.27.46:5000/).
### Pre-built binary package
For Windows, we bulid a GUI version for easy testing.
Download this version, and a pre-trained model via [[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
@@ -61,7 +62,7 @@ Attentions:
This code depends on opencv-python, torchvision available via pip install.
#### Clone this repo
```bash
-git clone https://github.com/HypoX64/DeepMosaics
+git clone https://github.com/HypoX64/DeepMosaics.git
cd DeepMosaics
```
#### Get Pre-Trained Models
diff --git a/README_CN.md b/README_CN.md
index 090371df517cbb19333e11766a2fde85b3f03aa2..db8fa17f4c90b04fc1405b8a191b876dca6e8eab 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -10,6 +10,7 @@
### 例子
![image](./imgs/hand.gif)
+
原始 | 自动打码 | 自动去码
:-:|:-:|:-:
![image](./imgs/example/lena.jpg) | ![image](./imgs/example/lena_add.jpg) | ![image](./imgs/example/lena_clean.jpg)
@@ -33,7 +34,7 @@
## 如何运行
可以通过我们预编译好的二进制包或源代码运行.
### 在网页中运行
-打开[这个网站](http://118.89.27.46:5000/)上传照片,将获得去除马赛克后的结果,受限与当地法律,目前只支持人脸.
+打开[这个网站](http://118.89.27.46:5000/)上传照片,将获得去除马赛克后的结果,受限于当地法律,**目前只支持人脸**.
### 预编译的程序包
对于Windows用户,我们提供了包含GUI界面的免安装软件包.
可以通过下面两种方式进行下载: [[Google Drive]](https://drive.google.com/open?id=1LTERcN33McoiztYEwBxMuRjjgxh4DEPs) [[百度云,提取码1x0a]](https://pan.baidu.com/s/10rN3U3zd5TmfGpO_PEShqQ)
@@ -57,10 +58,10 @@
- [Pytorch 1.0+](https://pytorch.org/)
- CPU or NVIDIA GPU + CUDA CuDNN
#### Python依赖项
-代码依赖于opencv-python以及 torchvision,可有通过pip install 进行安装.
+代码依赖于opencv-python以及 torchvision,可以通过pip install 进行安装.
#### 克隆源代码
```bash
-git clone https://github.com/HypoX64/DeepMosaics
+git clone https://github.com/HypoX64/DeepMosaics.git
cd DeepMosaics
```
#### 下载预训练模型
diff --git a/cores/add.py b/cores/add.py
new file mode 100644
index 0000000000000000000000000000000000000000..edf8027c573ee9ddd47486d80a371b4d01a94045
--- /dev/null
+++ b/cores/add.py
@@ -0,0 +1,130 @@
+import os
+from queue import Queue
+from threading import Thread
+import time
+import numpy as np
+import cv2
+from models import runmodel
+from util import mosaic,util,ffmpeg,filt
+from util import image_processing as impro
+from .init import video_init
+
+
+'''
+---------------------Add Mosaic---------------------
+'''
+def addmosaic_img(opt,netS):
+ path = opt.media_path
+ print('Add Mosaic:',path)
+ img = impro.imread(path)
+ mask = runmodel.get_ROI_position(img,netS,opt)[0]
+ img = mosaic.addmosaic(img,mask,opt)
+ impro.imwrite(os.path.join(opt.result_dir,os.path.splitext(os.path.basename(path))[0]+'_add.jpg'),img)
+
+def get_roi_positions(opt,netS,imagepaths,savemask=True):
+ # resume
+ continue_flag = False
+ if os.path.isfile(os.path.join(opt.temp_dir,'step.json')):
+ step = util.loadjson(os.path.join(opt.temp_dir,'step.json'))
+ resume_frame = int(step['frame'])
+ if int(step['step'])>2:
+ mask_index = np.load(os.path.join(opt.temp_dir,'mask_index.npy'))
+ return mask_index
+ if int(step['step'])>=2 and resume_frame>0:
+ pre_positions = np.load(os.path.join(opt.temp_dir,'roi_positions.npy'))
+ continue_flag = True
+ imagepaths = imagepaths[resume_frame:]
+
+ positions = []
+ t1 = time.time()
+ if not opt.no_preview:
+ cv2.namedWindow('mask', cv2.WINDOW_NORMAL)
+ print('Step:2/4 -- Find mosaic location')
+
+ img_read_pool = Queue(4)
+ def loader(imagepaths):
+ for imagepath in imagepaths:
+ img_origin = impro.imread(os.path.join(opt.temp_dir+'/video2image',imagepath))
+ img_read_pool.put(img_origin)
+ t = Thread(target=loader,args=(imagepaths,))
+ t.daemon = True
+ t.start()
+
+ for i,imagepath in enumerate(imagepaths,1):
+ img_origin = img_read_pool.get()
+ mask,x,y,size,area = runmodel.get_ROI_position(img_origin,netS,opt)
+ positions.append([x,y,area])
+ if savemask:
+ t = Thread(target=cv2.imwrite,args=(os.path.join(opt.temp_dir+'/ROI_mask',imagepath), mask,))
+ t.start()
+ if i%1000==0:
+ save_positions = np.array(positions)
+ if continue_flag:
+ save_positions = np.concatenate((pre_positions,save_positions),axis=0)
+ np.save(os.path.join(opt.temp_dir,'roi_positions.npy'),save_positions)
+ step = {'step':2,'frame':i+resume_frame}
+ util.savejson(os.path.join(opt.temp_dir,'step.json'),step)
+
+ #preview result and print
+ if not opt.no_preview:
+ cv2.imshow('mask',mask)
+ cv2.waitKey(1) & 0xFF
+ t2 = time.time()
+ print('\r',str(i)+'/'+str(len(imagepaths)),util.get_bar(100*i/len(imagepaths),num=35),util.counttime(t1,t2,i,len(imagepaths)),end='')
+
+ if not opt.no_preview:
+ cv2.destroyAllWindows()
+
+ print('\nOptimize ROI locations...')
+ if continue_flag:
+ positions = np.concatenate((pre_positions,positions),axis=0)
+ mask_index = filt.position_medfilt(np.array(positions), 7)
+ step = {'step':3,'frame':0}
+ util.savejson(os.path.join(opt.temp_dir,'step.json'),step)
+ np.save(os.path.join(opt.temp_dir,'roi_positions.npy'),positions)
+ np.save(os.path.join(opt.temp_dir,'mask_index.npy'),np.array(mask_index))
+
+ return mask_index
+
+def addmosaic_video(opt,netS):
+ path = opt.media_path
+ fps,imagepaths = video_init(opt,path)[:2]
+ length = len(imagepaths)
+ start_frame = int(imagepaths[0][7:13])
+ mask_index = get_roi_positions(opt,netS,imagepaths)[(start_frame-1):]
+
+ t1 = time.time()
+ if not opt.no_preview:
+ cv2.namedWindow('preview', cv2.WINDOW_NORMAL)
+
+ # add mosaic
+ print('Step:3/4 -- Add Mosaic:')
+ t1 = time.time()
+ # print(mask_index)
+ for i,imagepath in enumerate(imagepaths,1):
+ mask = impro.imread(os.path.join(opt.temp_dir+'/ROI_mask',imagepaths[np.clip(mask_index[i-1]-start_frame,0,1000000)]),'gray')
+ img = impro.imread(os.path.join(opt.temp_dir+'/video2image',imagepath))
+ if impro.mask_area(mask)>100:
+ try:#Avoid unknown errors
+ img = mosaic.addmosaic(img, mask, opt)
+ except Exception as e:
+ print('Warning:',e)
+ t = Thread(target=cv2.imwrite,args=(os.path.join(opt.temp_dir+'/addmosaic_image',imagepath),img))
+ t.start()
+ os.remove(os.path.join(opt.temp_dir+'/video2image',imagepath))
+
+ #preview result and print
+ if not opt.no_preview:
+ cv2.imshow('preview',img)
+ cv2.waitKey(1) & 0xFF
+ t2 = time.time()
+ print('\r',str(i)+'/'+str(length),util.get_bar(100*i/length,num=35),util.counttime(t1,t2,i,length),end='')
+
+ print()
+ if not opt.no_preview:
+ cv2.destroyAllWindows()
+ print('Step:4/4 -- Convert images to video')
+ ffmpeg.image2video( fps,
+ opt.temp_dir+'/addmosaic_image/output_%06d.'+opt.tempimage_type,
+ opt.temp_dir+'/voice_tmp.mp3',
+ os.path.join(opt.result_dir,os.path.splitext(os.path.basename(path))[0]+'_add.mp4'))
\ No newline at end of file
diff --git a/cores/core.py b/cores/clean.py
similarity index 51%
rename from cores/core.py
rename to cores/clean.py
index f9cc64c74cbd784494505d981f9fd7fe004e3ec6..285542b79179f3a2cb0c47931d6133ebfa57375d 100644
--- a/cores/core.py
+++ b/cores/clean.py
@@ -1,173 +1,62 @@
import os
import time
-import torch
import numpy as np
import cv2
-
-from models import runmodel,loadmodel
-from util import mosaic,util,ffmpeg,filt,data
+import torch
+from models import runmodel
+from util import data,util,ffmpeg,filt
from util import image_processing as impro
-
-'''
----------------------Video Init---------------------
-'''
-def video_init(opt,path):
- fps,endtime,height,width = ffmpeg.get_video_infos(path)
- if opt.fps !=0:
- fps = opt.fps
-
- continue_flag = False
- imagepaths = []
-
- if os.path.isdir(opt.temp_dir):
- imagepaths = os.listdir(opt.temp_dir+'/video2image')
- if imagepaths != []:
- imagepaths.sort()
- last_frame = int(imagepaths[-1][7:13])
- if (opt.last_time != '00:00:00' and last_frame > fps*(util.stamp2second(opt.last_time)-1)) \
- or (opt.last_time == '00:00:00' and last_frame > fps*(endtime-1)):
- choose = input('There is an unfinished video. Continue it? [y/n] ')
- if choose.lower() =='yes' or choose.lower() == 'y':
- continue_flag = True
-
- if not continue_flag:
- print('Step:1/4 -- Convert video to images')
- util.file_init(opt)
- ffmpeg.video2voice(path,opt.temp_dir+'/voice_tmp.mp3',opt.start_time,opt.last_time)
- ffmpeg.video2image(path,opt.temp_dir+'/video2image/output_%06d.'+opt.tempimage_type,fps,opt.start_time,opt.last_time)
- imagepaths = os.listdir(opt.temp_dir+'/video2image')
- imagepaths.sort()
-
- return fps,imagepaths,height,width
-
-'''
----------------------Add Mosaic---------------------
-'''
-def addmosaic_img(opt,netS):
- path = opt.media_path
- print('Add Mosaic:',path)
- img = impro.imread(path)
- mask = runmodel.get_ROI_position(img,netS,opt)[0]
- img = mosaic.addmosaic(img,mask,opt)
- impro.imwrite(os.path.join(opt.result_dir,os.path.splitext(os.path.basename(path))[0]+'_add.jpg'),img)
-
-def addmosaic_video(opt,netS):
- path = opt.media_path
- fps,imagepaths = video_init(opt,path)[:2]
- length = len(imagepaths)
- # get position
- positions = []
- t1 = time.time()
- if not opt.no_preview:
- cv2.namedWindow('preview', cv2.WINDOW_NORMAL)
-
- print('Step:2/4 -- Find ROI location')
- for i,imagepath in enumerate(imagepaths,1):
- img = impro.imread(os.path.join(opt.temp_dir+'/video2image',imagepath))
- mask,x,y,size,area = runmodel.get_ROI_position(img,netS,opt)
- positions.append([x,y,area])
- cv2.imwrite(os.path.join(opt.temp_dir+'/ROI_mask',imagepath),mask)
-
- #preview result and print
- if not opt.no_preview:
- cv2.imshow('preview',mask)
- cv2.waitKey(1) & 0xFF
- t2 = time.time()
- print('\r',str(i)+'/'+str(length),util.get_bar(100*i/length,num=35),util.counttime(t1,t2,i,length),end='')
-
- print('\nOptimize ROI locations...')
- mask_index = filt.position_medfilt(np.array(positions), 7)
-
- # add mosaic
- print('Step:3/4 -- Add Mosaic:')
- t1 = time.time()
- for i,imagepath in enumerate(imagepaths,1):
- mask = impro.imread(os.path.join(opt.temp_dir+'/ROI_mask',imagepaths[mask_index[i-1]]),'gray')
- img = impro.imread(os.path.join(opt.temp_dir+'/video2image',imagepath))
- if impro.mask_area(mask)>100:
- try:#Avoid unknown errors
- img = mosaic.addmosaic(img, mask, opt)
- except Exception as e:
- print('Warning:',e)
- cv2.imwrite(os.path.join(opt.temp_dir+'/addmosaic_image',imagepath),img)
- os.remove(os.path.join(opt.temp_dir+'/video2image',imagepath))
-
- #preview result and print
- if not opt.no_preview:
- cv2.imshow('preview',img)
- cv2.waitKey(1) & 0xFF
- t2 = time.time()
- print('\r',str(i)+'/'+str(length),util.get_bar(100*i/length,num=35),util.counttime(t1,t2,i,length),end='')
-
- print()
- if not opt.no_preview:
- cv2.destroyAllWindows()
- print('Step:4/4 -- Convert images to video')
- ffmpeg.image2video( fps,
- opt.temp_dir+'/addmosaic_image/output_%06d.'+opt.tempimage_type,
- opt.temp_dir+'/voice_tmp.mp3',
- os.path.join(opt.result_dir,os.path.splitext(os.path.basename(path))[0]+'_add.mp4'))
-
-'''
----------------------Style Transfer---------------------
-'''
-def styletransfer_img(opt,netG):
- print('Style Transfer_img:',opt.media_path)
- img = impro.imread(opt.media_path)
- img = runmodel.run_styletransfer(opt, netG, img)
- suffix = os.path.basename(opt.model_path).replace('.pth','').replace('style_','')
- impro.imwrite(os.path.join(opt.result_dir,os.path.splitext(os.path.basename(opt.media_path))[0]+'_'+suffix+'.jpg'),img)
-
-def styletransfer_video(opt,netG):
- path = opt.media_path
- positions = []
- fps,imagepaths = video_init(opt,path)[:2]
- print('Step:2/4 -- Transfer')
- t1 = time.time()
- if not opt.no_preview:
- cv2.namedWindow('preview', cv2.WINDOW_NORMAL)
- length = len(imagepaths)
-
- for i,imagepath in enumerate(imagepaths,1):
- img = impro.imread(os.path.join(opt.temp_dir+'/video2image',imagepath))
- img = runmodel.run_styletransfer(opt, netG, img)
- cv2.imwrite(os.path.join(opt.temp_dir+'/style_transfer',imagepath),img)
- os.remove(os.path.join(opt.temp_dir+'/video2image',imagepath))
-
- #preview result and print
- if not opt.no_preview:
- cv2.imshow('preview',img)
- cv2.waitKey(1) & 0xFF
- t2 = time.time()
- print('\r',str(i)+'/'+str(length),util.get_bar(100*i/length,num=35),util.counttime(t1,t2,i,len(imagepaths)),end='')
-
- print()
- if not opt.no_preview:
- cv2.destroyAllWindows()
- suffix = os.path.basename(opt.model_path).replace('.pth','').replace('style_','')
- print('Step:4/4 -- Convert images to video')
- ffmpeg.image2video( fps,
- opt.temp_dir+'/style_transfer/output_%06d.'+opt.tempimage_type,
- opt.temp_dir+'/voice_tmp.mp3',
- os.path.join(opt.result_dir,os.path.splitext(os.path.basename(path))[0]+'_'+suffix+'.mp4'))
+from .init import video_init
+from multiprocessing import Queue, Process
+from threading import Thread
'''
---------------------Clean Mosaic---------------------
'''
def get_mosaic_positions(opt,netM,imagepaths,savemask=True):
- # get mosaic position
+ # resume
+ continue_flag = False
+ if os.path.isfile(os.path.join(opt.temp_dir,'step.json')):
+ step = util.loadjson(os.path.join(opt.temp_dir,'step.json'))
+ resume_frame = int(step['frame'])
+ if int(step['step'])>2:
+ pre_positions = np.load(os.path.join(opt.temp_dir,'mosaic_positions.npy'))
+ return pre_positions
+ if int(step['step'])>=2 and resume_frame>0:
+ pre_positions = np.load(os.path.join(opt.temp_dir,'mosaic_positions.npy'))
+ continue_flag = True
+ imagepaths = imagepaths[resume_frame:]
+
positions = []
t1 = time.time()
if not opt.no_preview:
cv2.namedWindow('mosaic mask', cv2.WINDOW_NORMAL)
print('Step:2/4 -- Find mosaic location')
+
+ img_read_pool = Queue(4)
+ def loader(imagepaths):
+ for imagepath in imagepaths:
+ img_origin = impro.imread(os.path.join(opt.temp_dir+'/video2image',imagepath))
+ img_read_pool.put(img_origin)
+ t = Thread(target=loader,args=(imagepaths,))
+ t.setDaemon(True)
+ t.start()
+
for i,imagepath in enumerate(imagepaths,1):
- img_origin = impro.imread(os.path.join(opt.temp_dir+'/video2image',imagepath))
+ img_origin = img_read_pool.get()
x,y,size,mask = runmodel.get_mosaic_position(img_origin,netM,opt)
positions.append([x,y,size])
if savemask:
- cv2.imwrite(os.path.join(opt.temp_dir+'/mosaic_mask',imagepath), mask)
-
+ t = Thread(target=cv2.imwrite,args=(os.path.join(opt.temp_dir+'/mosaic_mask',imagepath), mask,))
+ t.start()
+ if i%1000==0:
+ save_positions = np.array(positions)
+ if continue_flag:
+ save_positions = np.concatenate((pre_positions,save_positions),axis=0)
+ np.save(os.path.join(opt.temp_dir,'mosaic_positions.npy'),save_positions)
+ step = {'step':2,'frame':i+resume_frame}
+ util.savejson(os.path.join(opt.temp_dir,'step.json'),step)
+
#preview result and print
if not opt.no_preview:
cv2.imshow('mosaic mask',mask)
@@ -179,7 +68,12 @@ def get_mosaic_positions(opt,netM,imagepaths,savemask=True):
cv2.destroyAllWindows()
print('\nOptimize mosaic locations...')
positions =np.array(positions)
+ if continue_flag:
+ positions = np.concatenate((pre_positions,positions),axis=0)
for i in range(3):positions[:,i] = filt.medfilt(positions[:,i],opt.medfilt_num)
+ step = {'step':3,'frame':0}
+ util.savejson(os.path.join(opt.temp_dir,'step.json'),step)
+ np.save(os.path.join(opt.temp_dir,'mosaic_positions.npy'),positions)
return positions
@@ -216,8 +110,10 @@ def cleanmosaic_img_server(opt,img_origin,netG,netM):
def cleanmosaic_video_byframe(opt,netG,netM):
path = opt.media_path
- fps,imagepaths = video_init(opt,path)[:2]
- positions = get_mosaic_positions(opt,netM,imagepaths,savemask=True)
+ fps,imagepaths,height,width = video_init(opt,path)
+ start_frame = int(imagepaths[0][7:13])
+ positions = get_mosaic_positions(opt,netM,imagepaths,savemask=True)[(start_frame-1):]
+
t1 = time.time()
if not opt.no_preview:
cv2.namedWindow('clean', cv2.WINDOW_NORMAL)
@@ -240,7 +136,8 @@ def cleanmosaic_video_byframe(opt,netG,netM):
img_result = impro.replace_mosaic(img_origin,img_fake,mask,x,y,size,opt.no_feather)
except Exception as e:
print('Warning:',e)
- cv2.imwrite(os.path.join(opt.temp_dir+'/replace_mosaic',imagepath),img_result)
+ t = Thread(target=cv2.imwrite,args=(os.path.join(opt.temp_dir+'/replace_mosaic',imagepath), img_result,))
+ t.start()
os.remove(os.path.join(opt.temp_dir+'/video2image',imagepath))
#preview result and print
@@ -270,7 +167,8 @@ def cleanmosaic_video_fusion(opt,netG,netM):
init_flag = True
fps,imagepaths,height,width = video_init(opt,path)
- positions = get_mosaic_positions(opt,netM,imagepaths,savemask=True)
+ start_frame = int(imagepaths[0][7:13])
+ positions = get_mosaic_positions(opt,netM,imagepaths,savemask=True)[(start_frame-1):]
t1 = time.time()
if not opt.no_preview:
cv2.namedWindow('clean', cv2.WINDOW_NORMAL)
@@ -278,7 +176,24 @@ def cleanmosaic_video_fusion(opt,netG,netM):
# clean mosaic
print('Step:3/4 -- Clean Mosaic:')
length = len(imagepaths)
-
+ write_pool = Queue(4)
+ show_pool = Queue(4)
+ def write_result():
+ while True:
+ save_ori,imagepath,img_origin,img_fake,x,y,size = write_pool.get()
+ if save_ori:
+ img_result = img_origin
+ else:
+ mask = cv2.imread(os.path.join(opt.temp_dir+'/mosaic_mask',imagepath),0)
+ img_result = impro.replace_mosaic(img_origin,img_fake,mask,x,y,size,opt.no_feather)
+ if not opt.no_preview:
+ show_pool.put(img_result.copy())
+ cv2.imwrite(os.path.join(opt.temp_dir+'/replace_mosaic',imagepath),img_result)
+ os.remove(os.path.join(opt.temp_dir+'/video2image',imagepath))
+ t = Thread(target=write_result,args=())
+ t.setDaemon(True)
+ t.start()
+
for i,imagepath in enumerate(imagepaths,0):
x,y,size = positions[i][0],positions[i][1],positions[i][2]
input_stream = []
@@ -290,12 +205,17 @@ def cleanmosaic_video_fusion(opt,netG,netM):
img_pool.pop(0)
img_pool.append(impro.imread(os.path.join(opt.temp_dir+'/video2image',imagepaths[np.clip(i+LEFT_FRAME,0,len(imagepaths)-1)])))
img_origin = img_pool[LEFT_FRAME]
- img_result = img_origin.copy()
+
+ # preview result and print
+ if not opt.no_preview:
+ if show_pool.qsize()>3:
+ cv2.imshow('clean',show_pool.get())
+ cv2.waitKey(1) & 0xFF
if size>50:
try:#Avoid unknown errors
for pos in FRAME_POS:
- input_stream.append(impro.resize(img_pool[pos][y-size:y+size,x-size:x+size], INPUT_SIZE)[:,:,::-1])
+ input_stream.append(impro.resize(img_pool[pos][y-size:y+size,x-size:x+size], INPUT_SIZE,interpolation=cv2.INTER_CUBIC)[:,:,::-1])
if init_flag:
init_flag = False
previous_frame = input_stream[N]
@@ -307,28 +227,23 @@ def cleanmosaic_video_fusion(opt,netG,netM):
unmosaic_pred = netG(input_stream,previous_frame)
img_fake = data.tensor2im(unmosaic_pred,rgb2bgr = True)
previous_frame = unmosaic_pred
- # previous_frame = data.tensor2im(unmosaic_pred,rgb2bgr = True)
- mask = cv2.imread(os.path.join(opt.temp_dir+'/mosaic_mask',imagepath),0)
- img_result = impro.replace_mosaic(img_origin,img_fake,mask,x,y,size,opt.no_feather)
+ write_pool.put([False,imagepath,img_origin.copy(),img_fake.copy(),x,y,size])
except Exception as e:
init_flag = True
print('Error:',e)
else:
+ write_pool.put([True,imagepath,img_origin.copy(),-1,-1,-1,-1])
init_flag = True
- cv2.imwrite(os.path.join(opt.temp_dir+'/replace_mosaic',imagepath),img_result)
- os.remove(os.path.join(opt.temp_dir+'/video2image',imagepath))
- #preview result and print
- if not opt.no_preview:
- cv2.imshow('clean',img_result)
- cv2.waitKey(1) & 0xFF
t2 = time.time()
print('\r',str(i+1)+'/'+str(length),util.get_bar(100*i/length,num=35),util.counttime(t1,t2,i+1,len(imagepaths)),end='')
print()
+ write_pool.close()
+ show_pool.close()
if not opt.no_preview:
cv2.destroyAllWindows()
print('Step:4/4 -- Convert images to video')
ffmpeg.image2video( fps,
opt.temp_dir+'/replace_mosaic/output_%06d.'+opt.tempimage_type,
opt.temp_dir+'/voice_tmp.mp3',
- os.path.join(opt.result_dir,os.path.splitext(os.path.basename(path))[0]+'_clean.mp4'))
\ No newline at end of file
+ os.path.join(opt.result_dir,os.path.splitext(os.path.basename(path))[0]+'_clean.mp4'))
\ No newline at end of file
diff --git a/cores/init.py b/cores/init.py
new file mode 100644
index 0000000000000000000000000000000000000000..5993c584011ce876b4cd80795515acc294923cfb
--- /dev/null
+++ b/cores/init.py
@@ -0,0 +1,31 @@
+import os
+from util import util,ffmpeg
+
+'''
+---------------------Video Init---------------------
+'''
+def video_init(opt,path):
+ fps,endtime,height,width = ffmpeg.get_video_infos(path)
+ if opt.fps !=0:
+ fps = opt.fps
+
+ # resume
+ if os.path.isfile(os.path.join(opt.temp_dir,'step.json')):
+ step = util.loadjson(os.path.join(opt.temp_dir,'step.json'))
+ if int(step['step'])>=1:
+ choose = input('There is an unfinished video. Continue it? [y/n] ')
+ if choose.lower() =='yes' or choose.lower() == 'y':
+ imagepaths = os.listdir(opt.temp_dir+'/video2image')
+ imagepaths.sort()
+ return fps,imagepaths,height,width
+
+ print('Step:1/4 -- Convert video to images')
+ util.file_init(opt)
+ ffmpeg.video2voice(path,opt.temp_dir+'/voice_tmp.mp3',opt.start_time,opt.last_time)
+ ffmpeg.video2image(path,opt.temp_dir+'/video2image/output_%06d.'+opt.tempimage_type,fps,opt.start_time,opt.last_time)
+ imagepaths = os.listdir(opt.temp_dir+'/video2image')
+ imagepaths.sort()
+ step = {'step':2,'frame':0}
+ util.savejson(os.path.join(opt.temp_dir,'step.json'),step)
+
+ return fps,imagepaths,height,width
\ No newline at end of file
diff --git a/cores/options.py b/cores/options.py
index bba8bae9b2227dedc2e50bf7deb39ab0f86d6277..9574a9bee8231bae827d274e970c0ac74dbd04a8 100644
--- a/cores/options.py
+++ b/cores/options.py
@@ -26,7 +26,7 @@ class Options():
self.parser.add_argument('--fps', type=int, default=0,help='read and output fps, if 0-> origin')
self.parser.add_argument('--no_preview', action='store_true', help='if specified,do not preview images when processing video. eg.(when run it on server)')
self.parser.add_argument('--output_size', type=int, default=0,help='size of output media, if 0 -> origin')
- self.parser.add_argument('--mask_threshold', type=int, default=64,help='threshold of recognize clean or add mosaic position 0~255')
+ self.parser.add_argument('--mask_threshold', type=int, default=64,help='Mosaic detection threshold (0~255). The smaller is it, the more likely judged as a mosaic area.')
#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')
diff --git a/cores/style.py b/cores/style.py
new file mode 100644
index 0000000000000000000000000000000000000000..32834adc125ed2f0f08679b9958e45d71e80f3c0
--- /dev/null
+++ b/cores/style.py
@@ -0,0 +1,50 @@
+import os
+import time
+import numpy as np
+import cv2
+from models import runmodel
+from util import mosaic,util,ffmpeg,filt
+from util import image_processing as impro
+from .init import video_init
+
+'''
+---------------------Style Transfer---------------------
+'''
+def styletransfer_img(opt,netG):
+ print('Style Transfer_img:',opt.media_path)
+ img = impro.imread(opt.media_path)
+ img = runmodel.run_styletransfer(opt, netG, img)
+ suffix = os.path.basename(opt.model_path).replace('.pth','').replace('style_','')
+ impro.imwrite(os.path.join(opt.result_dir,os.path.splitext(os.path.basename(opt.media_path))[0]+'_'+suffix+'.jpg'),img)
+
+def styletransfer_video(opt,netG):
+ path = opt.media_path
+ fps,imagepaths = video_init(opt,path)[:2]
+ print('Step:2/4 -- Transfer')
+ t1 = time.time()
+ if not opt.no_preview:
+ cv2.namedWindow('preview', cv2.WINDOW_NORMAL)
+ length = len(imagepaths)
+
+ for i,imagepath in enumerate(imagepaths,1):
+ img = impro.imread(os.path.join(opt.temp_dir+'/video2image',imagepath))
+ img = runmodel.run_styletransfer(opt, netG, img)
+ cv2.imwrite(os.path.join(opt.temp_dir+'/style_transfer',imagepath),img)
+ os.remove(os.path.join(opt.temp_dir+'/video2image',imagepath))
+
+ #preview result and print
+ if not opt.no_preview:
+ cv2.imshow('preview',img)
+ cv2.waitKey(1) & 0xFF
+ t2 = time.time()
+ print('\r',str(i)+'/'+str(length),util.get_bar(100*i/length,num=35),util.counttime(t1,t2,i,len(imagepaths)),end='')
+
+ print()
+ if not opt.no_preview:
+ cv2.destroyAllWindows()
+ suffix = os.path.basename(opt.model_path).replace('.pth','').replace('style_','')
+ print('Step:4/4 -- Convert images to video')
+ ffmpeg.image2video( fps,
+ opt.temp_dir+'/style_transfer/output_%06d.'+opt.tempimage_type,
+ opt.temp_dir+'/voice_tmp.mp3',
+ os.path.join(opt.result_dir,os.path.splitext(os.path.basename(path))[0]+'_'+suffix+'.mp4'))
\ No newline at end of file
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b088e2a664e6dd6cce3d80357b0e30be5a78521
--- /dev/null
+++ b/cpp/CMakeLists.txt
@@ -0,0 +1,38 @@
+cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
+set(CMAKE_CXX_STANDARD 14)
+
+project(DeepMosaics)
+set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) #链接库路径
+
+set(Torch_DIR /home/hypo/libtorch/share/cmake/Torch)
+find_package(Torch REQUIRED)
+
+set(OpenCV_DIR /home/hypo/opencv-4.4.0)
+find_package(OpenCV REQUIRED)
+
+# Add sub directories
+add_subdirectory(example)
+add_subdirectory(utils)
+
+# set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
+# cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
+# project(main)
+# set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) #链接库路径
+
+# set(Torch_DIR /home/hypo/libtorch/share/cmake/Torch)
+# find_package(Torch REQUIRED)
+
+# set(OpenCV_DIR /home/hypo/opencv-4.4.0)
+# find_package(OpenCV REQUIRED)
+
+# # 查找当前目录下的所有源文件
+# # 并将名称保存到 DIR_SRCS 变量
+# # aux_source_directory(. DIR_SRCS)
+# add_subdirectory(utils)
+
+# add_executable(main main.cpp)
+# # target_link_libraries(main )
+# # include_directories( "${OpenCV_INCLUDE_DIRS}" )
+# target_link_libraries( main "${TORCH_LIBRARIES}" "${OpenCV_LIBS}" utils)
+
+# set_property(TARGET main PROPERTY CXX_STANDARD 14)
diff --git a/cpp/README.md b/cpp/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3be7e1b7ca308501c423ec5cf213a8e80558bf4c
--- /dev/null
+++ b/cpp/README.md
@@ -0,0 +1,3 @@
+### C++ version for DeepMosaics
+* I am learning c++ through this project...
+* It is under development...
\ No newline at end of file
diff --git a/cpp/example/CMakeLists.txt b/cpp/example/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8e27f616b29a3f42746e058b2e6783576c72302f
--- /dev/null
+++ b/cpp/example/CMakeLists.txt
@@ -0,0 +1,17 @@
+# project(example)
+# add_executable("${PROJECT_NAME}" deepmosaic.cpp)
+# target_link_libraries( "${PROJECT_NAME}"
+# "${TORCH_LIBRARIES}"
+# "${OpenCV_LIBS}"
+# utils)
+
+file(GLOB_RECURSE srcs RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
+foreach(sourcefile IN LISTS srcs)
+ string( REPLACE ".cpp" "" binname ${sourcefile})
+ add_executable( ${binname} ${sourcefile} )
+ target_link_libraries( ${binname}
+ "${TORCH_LIBRARIES}"
+ "${OpenCV_LIBS}"
+ utils)
+ # set_property(TARGET ${binname} PROPERTY CXX_STANDARD 14)
+endforeach()
\ No newline at end of file
diff --git a/cpp/example/deepmosaic.cpp b/cpp/example/deepmosaic.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dd7cde87b88912a3f7b45501d18378c64429c8b0
--- /dev/null
+++ b/cpp/example/deepmosaic.cpp
@@ -0,0 +1,52 @@
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "data.hpp"
+#include "util.hpp"
+
+int main() {
+ std::string path = util::current_path();
+
+ std::string net_path = "../res/models/mosaic_position.pth";
+ std::string img_path = "../res/test_media/face/d.jpg";
+
+ cv::Mat img = cv::imread(img_path);
+ cv::resize(img, img, cv::Size(360, 360), 2);
+ // img.convertTo(img, CV_32F);
+ torch::Tensor img_tensor =
+ torch::from_blob(img.data, {1, img.rows, img.cols, 3}, torch::kByte);
+ img_tensor = img_tensor.permute({0, 3, 1, 2});
+ img_tensor = img_tensor.toType(torch::kFloat);
+ img_tensor = img_tensor.div(255);
+ std::cout << img_tensor.sizes() << "\n";
+
+ // end = clock();
+ // dur = (double)(end - start);
+ // printf("Use Time:%f\n", (dur / CLOCKS_PER_SEC));
+
+ // std::string net_path = "../res/models/mosaic_position.pt";
+ // torch::jit::script::Module net;
+ // try{
+ // // if (!isfile(net_path)){
+ // // std::cerr<<"model does not exist\n";
+ // // }
+
+ // net = torch::jit::load(net_path);
+ // }
+ // catch(const std::exception& e){
+ // std::cerr << "error loading the model\n";
+ // return -1;
+ // }
+
+ // torch::Tensor example = torch::ones({1,3,360,360});
+ // torch::Tensor output = net.forward({example}).toTensor();
+ // std::cout<<"ok"<
+
+namespace data {
+void normalize(cv::Mat& matrix, double mean = 0.5, double std = 0.5);
+
+} // namespace data
+
+#endif
\ No newline at end of file
diff --git a/cpp/utils/include/util.hpp b/cpp/utils/include/util.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..104ebb5f7b9d09601721c88985ebdad2b8aff40b
--- /dev/null
+++ b/cpp/utils/include/util.hpp
@@ -0,0 +1,26 @@
+#ifndef UTIL_H
+#define UTIL_H
+#include
+#include
+namespace util {
+
+class Timer {
+ private:
+ clock_t tstart, tend;
+
+ public:
+ void start();
+ void end();
+};
+
+// std::string path = util::current_path();
+std::string current_path();
+
+// std::string out = util::pathjoin({path, "b", "c"});
+std::string pathjoin(const std::list& strs);
+
+bool isfile(const std::string& name);
+
+} // namespace util
+
+#endif
\ No newline at end of file
diff --git a/cpp/utils/src/data.cpp b/cpp/utils/src/data.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..47b3b64f794c09cce465b970469adbb940733baa
--- /dev/null
+++ b/cpp/utils/src/data.cpp
@@ -0,0 +1,10 @@
+#include "data.hpp"
+#include
+
+namespace data {
+void normalize(cv::Mat& matrix, double mean, double std) {
+ // matrix = (matrix / 255.0 - mean) / std;
+ matrix = matrix / (255.0 * std) - mean / std;
+}
+
+} // namespace data
\ No newline at end of file
diff --git a/cpp/utils/src/util.cpp b/cpp/utils/src/util.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0929cb64aa5efd13e74d21060c6e7bfe468b8532
--- /dev/null
+++ b/cpp/utils/src/util.cpp
@@ -0,0 +1,49 @@
+#include "util.hpp"
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace util {
+
+void Timer::start() {
+ tstart = clock();
+}
+void Timer::end() {
+ tend = clock();
+ double dur;
+ dur = (double)(tend - tstart);
+ std::cout << "Cost Time:" << (dur / CLOCKS_PER_SEC) << "\n";
+}
+
+std::string current_path() {
+ char* buffer;
+ buffer = getcwd(NULL, 0);
+ return buffer;
+}
+
+std::string pathjoin(const std::list& strs) {
+ std::string res = "";
+ int cnt = 0;
+ for (std::string s : strs) {
+ if (cnt == 0) {
+ res += s;
+ } else {
+ if (s[0] != '/') {
+ res += ("/" + s);
+ } else {
+ res += s;
+ }
+ }
+ cnt++;
+ }
+ return res;
+}
+
+bool isfile(const std::string& name) {
+ struct stat buffer;
+ return (stat(name.c_str(), &buffer) == 0);
+}
+} // namespace util
\ No newline at end of file
diff --git a/deepmosaic.py b/deepmosaic.py
index 1d5c4e6530d5bf65e96ee77b3b99133bf23559e0..5a59f19a71fedee46c5533a0ad65a95ff95c98ce 100644
--- a/deepmosaic.py
+++ b/deepmosaic.py
@@ -2,7 +2,7 @@ import os
import sys
import traceback
try:
- from cores import Options,core
+ from cores import Options,add,clean,style
from util import util
from models import loadmodel
except Exception as e:
@@ -25,9 +25,9 @@ def main():
for file in files:
opt.media_path = file
if util.is_img(file):
- core.addmosaic_img(opt,netS)
+ add.addmosaic_img(opt,netS)
elif util.is_video(file):
- core.addmosaic_video(opt,netS)
+ add.addmosaic_video(opt,netS)
util.clean_tempfiles(opt, tmp_init = False)
else:
print('This type of file is not supported')
@@ -45,12 +45,12 @@ def main():
for file in files:
opt.media_path = file
if util.is_img(file):
- core.cleanmosaic_img(opt,netG,netM)
+ clean.cleanmosaic_img(opt,netG,netM)
elif util.is_video(file):
if opt.netG == 'video' and not opt.traditional:
- core.cleanmosaic_video_fusion(opt,netG,netM)
+ clean.cleanmosaic_video_fusion(opt,netG,netM)
else:
- core.cleanmosaic_video_byframe(opt,netG,netM)
+ clean.cleanmosaic_video_byframe(opt,netG,netM)
util.clean_tempfiles(opt, tmp_init = False)
else:
print('This type of file is not supported')
@@ -60,9 +60,9 @@ def main():
for file in files:
opt.media_path = file
if util.is_img(file):
- core.styletransfer_img(opt,netG)
+ style.styletransfer_img(opt,netG)
elif util.is_video(file):
- core.styletransfer_video(opt,netG)
+ style.styletransfer_video(opt,netG)
util.clean_tempfiles(opt, tmp_init = False)
else:
print('This type of file is not supported')
@@ -79,7 +79,7 @@ if __name__ == '__main__':
except Exception as ex:
print('--------------------ERROR--------------------')
print('--------------Environment--------------')
- print('DeepMosaics: 0.5.0')
+ print('DeepMosaics: 0.5.1')
print('Python:',sys.version)
import torch
print('Pytorch:',torch.__version__)
diff --git a/docs/Release_notes.txt b/docs/Release_notes.txt
index b62014f75e02e1def47f34eafcc912fc180ae07c..c48fbb59e02f25facf5ec48491ce7661a2ee7ba2 100644
--- a/docs/Release_notes.txt
+++ b/docs/Release_notes.txt
@@ -1,23 +1,43 @@
-DeepMosaics V0.3.0
-Core program building with windows10_1703_x86_64
- + python 3.68
- + pyinstaller 3.5
+DeepMosaics: 0.5.1
+Core building with:
+ Python: 3.7.3 (default, Apr 24 2019, 15:29:51) [MSC v.1915 64 bit (AMD64)]
+ Pytorch: 1.7.1
+ OpenCV: 4.1.2
+ Platform: Windows-10-10.0.19041-SP0
+ Driver Version: 461.40
+ CUDA:11.0
GUI building with C#
For more detail, please view on github: https://github.com/HypoX64/DeepMosaics
Releases History
- V0.3.0
- 1. Support BiSeNet(Better recognition of mosaics).
- 2. New videoHD model.
- 3. Better feathering method.
- V0.2.0
- 1. Add video model.
- 2. Now you can input chinese path
- 3. Support style transfer
- 4. Support fps limit
- V0.1.2
- 1. Support pix2pixHD model
- V0.1.1
- 1. Check path, can't input illegal path
- V0.1.0
- 1. Initial release.
\ No newline at end of file
+ V0.5.1
+ Fix:
+ 1.Fix Some BUGs when restore unfinished tasks.
+ 2.Fix that audio and video are not synchronized when the video is too long.
+ New:
+ 1.Speed up video processing by Asynchronous.
+ V0.5.0
+ 1.New video model (Perform better)
+ V0.4.1
+ 1.Allow unfinished tasks to be restored.
+ 2.Clean cache during processing.
+ 3.Support CUDA 11.0.
+ V0.4.0
+ 1.Support GPU.
+ 2.Preview images when processing video.
+ 3.Choose start position of video.
+ V0.3.0
+ 1. Support BiSeNet(Better recognition of mosaics).
+ 2. New videoHD model.
+ 3. Better feathering method.
+ V0.2.0
+ 1. Add video model.
+ 2. Now you can input chinese path
+ 3. Support style transfer
+ 4. Support fps limit
+ V0.1.2
+ 1. Support pix2pixHD model
+ V0.1.1
+ 1. Check path, can't input illegal path
+ V0.1.0
+ 1. Initial release.
\ No newline at end of file
diff --git a/server.py b/tools/server.py
similarity index 90%
rename from server.py
rename to tools/server.py
index f76ca1c22ea020c937b82284a3f42647f9b21b2a..f6fe0647c8a7ef81c062a7d3473495b0eca136da 100644
--- a/server.py
+++ b/tools/server.py
@@ -4,7 +4,7 @@ import traceback
import cv2
import numpy as np
try:
- from cores import Options,core
+ from cores import Options,clean
from util import util
from util import image_processing as impro
from models import loadmodel
@@ -44,7 +44,7 @@ def handle():
try:
if max(img.shape)>1080:
img = impro.resize(img,720,interpolation=cv2.INTER_CUBIC)
- img = core.cleanmosaic_img_server(opt,img,netG,netM)
+ img = clean.cleanmosaic_img_server(opt,img,netG,netM)
except Exception as e:
result['img'] = imgRec
result['info'] = 'procfailed'
diff --git a/tools/trace_model.py b/tools/trace_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..d69cb937410d2ac4d9cfe4b0f9808cc47263dc7c
--- /dev/null
+++ b/tools/trace_model.py
@@ -0,0 +1,95 @@
+import os
+import sys
+import traceback
+sys.path.append("..")
+from util import mosaic
+import torch
+
+try:
+ from cores import Options,add,clean,style
+ from util import util
+ from models import loadmodel
+except Exception as e:
+ print(e)
+ input('Please press any key to exit.\n')
+ sys.exit(0)
+
+opt = Options().getparse(test_flag = False)
+if not os.path.isdir(opt.temp_dir):
+ util.file_init(opt)
+
+def saveScriptModel(model,example,savepath):
+ model.cpu()
+ traced_script_module = torch.jit.trace(model, example)
+ # try ScriptModel
+ output = traced_script_module(example)
+ print(output)
+ traced_script_module.save(savepath)
+
+savedir = '../cpp/res/models/'
+util.makedirs(savedir)
+
+opt.mosaic_position_model_path = '../pretrained_models/mosaic/mosaic_position.pth'
+model = loadmodel.bisenet(opt,'mosaic')
+example = torch.ones((1,3,360,360))
+saveScriptModel(model,example,os.path.join(savedir,'mosaic_position.pt'))
+
+
+
+# def main():
+
+# if os.path.isdir(opt.media_path):
+# files = util.Traversal(opt.media_path)
+# else:
+# files = [opt.media_path]
+# if opt.mode == 'add':
+# netS = loadmodel.bisenet(opt,'roi')
+# for file in files:
+# opt.media_path = file
+# if util.is_img(file):
+# add.addmosaic_img(opt,netS)
+# elif util.is_video(file):
+# add.addmosaic_video(opt,netS)
+# util.clean_tempfiles(opt, tmp_init = False)
+# else:
+# print('This type of file is not supported')
+# util.clean_tempfiles(opt, tmp_init = False)
+
+# elif opt.mode == 'clean':
+# netM = loadmodel.bisenet(opt,'mosaic')
+# if opt.traditional:
+# netG = None
+# elif opt.netG == 'video':
+# netG = loadmodel.video(opt)
+# else:
+# netG = loadmodel.pix2pix(opt)
+
+# for file in files:
+# opt.media_path = file
+# if util.is_img(file):
+# clean.cleanmosaic_img(opt,netG,netM)
+# elif util.is_video(file):
+# if opt.netG == 'video' and not opt.traditional:
+# clean.cleanmosaic_video_fusion(opt,netG,netM)
+# else:
+# clean.cleanmosaic_video_byframe(opt,netG,netM)
+# util.clean_tempfiles(opt, tmp_init = False)
+# else:
+# print('This type of file is not supported')
+
+# elif opt.mode == 'style':
+# netG = loadmodel.style(opt)
+# for file in files:
+# opt.media_path = file
+# if util.is_img(file):
+# style.styletransfer_img(opt,netG)
+# elif util.is_video(file):
+# style.styletransfer_video(opt,netG)
+# util.clean_tempfiles(opt, tmp_init = False)
+# else:
+# print('This type of file is not supported')
+
+# util.clean_tempfiles(opt, tmp_init = False)
+
+# if __name__ == '__main__':
+# main()
\ No newline at end of file
diff --git a/util/ffmpeg.py b/util/ffmpeg.py
index 20881422a4cbec633982d5f2ccad254e762b4881..eb82ed00dedc629f40d2b5856bb0bae767e672fa 100755
--- a/util/ffmpeg.py
+++ b/util/ffmpeg.py
@@ -43,7 +43,7 @@ def video2image(videopath, imagepath, fps=0, start_time='00:00:00', last_time='0
run(args)
def video2voice(videopath, voicepath, start_time='00:00:00', last_time='00:00:00'):
- args = ['ffmpeg', '-i', '"'+videopath+'"','-f mp3','-b:a 320k']
+ args = ['ffmpeg', '-i', '"'+videopath+'"','-async 1 -f mp3','-b:a 320k']
if last_time != '00:00:00':
args += ['-ss', start_time]
args += ['-t', last_time]
diff --git a/util/image_processing.py b/util/image_processing.py
index 6f1dd91308b2e5274806cd894a064f550c8d5748..e55a53d4f18035075f36368367278243cfd8f0ba 100755
--- a/util/image_processing.py
+++ b/util/image_processing.py
@@ -1,6 +1,7 @@
import cv2
import numpy as np
import random
+from threading import Thread
import platform
@@ -39,15 +40,22 @@ def imread(file_path,mod = 'normal',loadsize = 0, rgb=False):
return img
-def imwrite(file_path,img):
+def imwrite(file_path,img,use_thread=False):
'''
in other to save chinese path images in windows,
this fun just for save final output images
'''
- if system_type == 'Linux':
- cv2.imwrite(file_path, img)
+ def subfun(file_path,img):
+ if system_type == 'Linux':
+ cv2.imwrite(file_path, img)
+ else:
+ cv2.imencode('.jpg', img)[1].tofile(file_path)
+ if use_thread:
+ t = Thread(target=subfun,args=(file_path, img,))
+ t.daemon()
+ t.start
else:
- cv2.imencode('.jpg', img)[1].tofile(file_path)
+ subfun(file_path,img)
def resize(img,size,interpolation=cv2.INTER_LINEAR):
'''
@@ -183,7 +191,7 @@ def mask_area(mask):
except:
area = 0
return area
-import time
+
def replace_mosaic(img_origin,img_fake,mask,x,y,size,no_feather):
img_fake = cv2.resize(img_fake,(size*2,size*2),interpolation=cv2.INTER_CUBIC)
if no_feather:
diff --git a/util/util.py b/util/util.py
index 4952df8383ce3938d60a44cc4d524c4e95293b32..3d21f6034e61c5408a7b8a74a5b1e5e29300d622 100755
--- a/util/util.py
+++ b/util/util.py
@@ -1,3 +1,4 @@
+import json
import os
import random
import string
@@ -52,13 +53,25 @@ def is_dirs(paths):
tmp.append(path)
return tmp
-def writelog(path,log,isprint=False):
+def writelog(path,log,isprint=False):
f = open(path,'a+')
f.write(log+'\n')
f.close()
if isprint:
print(log)
+def savejson(path,data_dict):
+ json_str = json.dumps(data_dict)
+ f = open(path,'w+')
+ f.write(json_str)
+ f.close()
+
+def loadjson(path):
+ f = open(path, 'r')
+ txt_data = f.read()
+ f.close()
+ return json.loads(txt_data)
+
def makedirs(path):
if os.path.isdir(path):
print(path,'existed')