Add message box for decensoring

This commit is contained in:
deeppomf 2019-10-09 01:20:28 -04:00
parent a4de5bddb5
commit b0b054aff5
3 changed files with 96 additions and 45 deletions

View File

@ -32,6 +32,9 @@ def get_args():
parser.add_argument('--is_mosaic', type=str2bool, default='False', help='true if image has mosaic censoring, false otherwise')
parser.add_argument('--variations', type=int, choices=[1, 2, 4], default=1, help='number of decensor variations to be generated')
#Other settings
parser.add_argument('--ui_mode', default=False, help='true if you want ui mode, false if you want command line interface')
args = parser.parse_args()
return args

View File

@ -4,20 +4,28 @@ try:
import numpy as np
from PIL import Image
import os
import os, logging, sys
from copy import deepcopy
import config
import file
from model import InpaintNN
from libs.utils import *
except ImportError as e:
print("Error when importing libraries: ", e)
print("Some Python libraries are missing. You can install all required libraries by running in the command line 'pip install -r requirements.txt' ")
exit(1)
# #signals to the ui to print out
# class EmittingStream(QtCore.QObject):
# textWritten = QtCore.pyqtSignal(str)
# def write(self, text):
# self.textWritten.emit(str(text))
class Decensor:
def __init__(self):
def __init__(self, text_edit = None, text_cursor = None, ui_mode = None):
args = config.get_args()
self.is_mosaic = args.is_mosaic
self.variations = args.variations
@ -25,10 +33,20 @@ class Decensor:
self.decensor_input_path = args.decensor_input_path
self.decensor_input_original_path = args.decensor_input_original_path
self.decensor_output_path = args.decensor_output_path
if ui_mode is not None:
self.ui_mode = ui_mode
else:
self.ui_mode = args.ui_mode
if not os.path.exists(self.decensor_output_path):
os.makedirs(self.decensor_output_path)
if self.ui_mode:
self.text_edit = text_edit
self.text_cursor = text_cursor
self.ui_mode = True
def find_mask(self, colored):
mask = np.ones(colored.shape, np.uint8)
i, j = np.where(np.all(colored[0] == self.mask_color, axis=-1))
@ -60,12 +78,12 @@ class Decensor:
color_file_path = os.path.join(input_color_dir, file_name)
color_basename, color_ext = os.path.splitext(file_name)
if os.path.isfile(color_file_path) and color_ext.casefold() == ".png":
print("--------------------------------------------------------------------------")
print("Decensoring the image {}".format(color_file_path))
self.custom_print("--------------------------------------------------------------------------")
self.custom_print("Decensoring the image {}".format(color_file_path))
try :
colored_img = Image.open(color_file_path)
except:
print("Cannot identify image file (" +str(color_file_path)+")")
self.custom_print("Cannot identify image file (" +str(color_file_path)+")")
self.files_removed.append((color_file_path,3))
# incase of abnormal file format change (ex : text.txt -> text.png)
continue
@ -86,18 +104,18 @@ class Decensor:
self.decensor_image_variations(ori_img, colored_img, file_name)
break
else: #for...else, i.e if the loop finished without encountering break
print("Corresponding original, uncolored image not found in {}".format(color_file_path))
print("Check if it exists and is in the PNG or JPG format.")
self.custom_print("Corresponding original, uncolored image not found in {}".format(color_file_path))
self.custom_print("Check if it exists and is in the PNG or JPG format.")
#if we are doing a bar decensor
else:
self.decensor_image_variations(colored_img, colored_img, file_name)
else:
print("--------------------------------------------------------------------------")
print("Image can't be found: "+str(color_file_path))
print("--------------------------------------------------------------------------")
self.custom_print("--------------------------------------------------------------------------")
self.custom_print("Image can't be found: "+str(color_file_path))
self.custom_print("--------------------------------------------------------------------------")
if self.files_removed is not None:
file.error_messages(None, self.files_removed)
print("\nDecensoring complete!")
self.custom_print("\nDecensoring complete!")
def decensor_image_variations(self, ori, colored, file_name=None):
for i in range(self.variations):
@ -134,7 +152,7 @@ class Decensor:
if self.is_mosaic:
#if mosaic decensor, mask is empty
# mask = np.ones(ori_array.shape, np.uint8)
# print(mask.shape)
# self.custom_print(mask.shape)
colored = colored.convert('RGB')
color_array = image_to_array(colored)
color_array = np.expand_dims(color_array, axis = 0)
@ -148,10 +166,10 @@ class Decensor:
#colored image is only used for finding the regions
regions = find_regions(colored.convert('RGB'), [v*255 for v in self.mask_color])
print("Found {region_count} censored regions in this image!".format(region_count = len(regions)))
self.custom_print("Found {region_count} censored regions in this image!".format(region_count = len(regions)))
if len(regions) == 0 and not self.is_mosaic:
print("No green regions detected! Make sure you're using exactly the right color.")
self.custom_print("No green regions detected! Make sure you're using exactly the right color.")
return
output_img_array = ori_array[0].copy()
@ -179,11 +197,11 @@ class Decensor:
if not self.is_mosaic:
a, b = np.where(np.all(mask_array == 0, axis = -1))
# print(a,b)
# print(crop_img_array[a,b])
# print(crop_img_array[a,b,0])
# print(crop_img_array.shape)
# print(type(crop_img_array[0,0]))
# self.custom_print(a,b)
# self.custom_print(crop_img_array[a,b])
# self.custom_print(crop_img_array[a,b,0])
# self.custom_print(crop_img_array.shape)
# self.custom_print(type(crop_img_array[0,0]))
crop_img_array[a,b,:] = 0.
# temp = Image.fromarray((crop_img_array * 255.0).astype('uint8'))
# temp.show()
@ -191,15 +209,15 @@ class Decensor:
crop_img_array = np.expand_dims(crop_img_array, axis = 0)
mask_array = np.expand_dims(mask_array, axis = 0)
# print(np.amax(crop_img_array))
# print(np.amax(mask_array))
# print(np.amax(masked))
# self.custom_print(np.amax(crop_img_array))
# self.custom_print(np.amax(mask_array))
# self.custom_print(np.amax(masked))
# print(np.amin(crop_img_array))
# print(np.amin(mask_array))
# print(np.amin(masked))
# self.custom_print(np.amin(crop_img_array))
# self.custom_print(np.amin(mask_array))
# self.custom_print(np.amin(masked))
# print(mask_array)
# self.custom_print(mask_array)
crop_img_array = crop_img_array * 2.0 - 1
# mask_array = mask_array / 255.0
@ -215,8 +233,8 @@ class Decensor:
bounding_height = bounding_box[3]-bounding_box[1]
#convert np array to image
# print(bounding_width,bounding_height)
# print(pred_img_array.shape)
# self.custom_print(bounding_width,bounding_height)
# self.custom_print(pred_img_array.shape)
pred_img = Image.fromarray(pred_img_array.astype('uint8'))
# pred_img.show()
@ -225,7 +243,7 @@ class Decensor:
pred_img_array = image_to_array(pred_img)
# print(pred_img_array.shape)
# self.custom_print(pred_img_array.shape)
pred_img_array = np.expand_dims(pred_img_array, axis = 0)
# copy the decensored regions into the output image
@ -236,7 +254,7 @@ class Decensor:
bounding_height_index = row + bounding_box[1]
if (bounding_width_index, bounding_height_index) in region:
output_img_array[bounding_height_index][bounding_width_index] = pred_img_array[i,:,:,:][row][col]
print("{region_counter} out of {region_count} regions decensored.".format(region_counter=region_counter, region_count=len(regions)))
self.custom_print("{region_counter} out of {region_count} regions decensored.".format(region_counter=region_counter, region_count=len(regions)))
output_img_array = output_img_array * 255.0
@ -254,12 +272,23 @@ class Decensor:
save_path = os.path.join(self.decensor_output_path, file_name)
output_img.save(save_path)
print("Decensored image saved to {save_path}!".format(save_path=save_path))
self.custom_print("Decensored image saved to {save_path}!".format(save_path=save_path))
return
else:
print("Decensored image. Returning it.")
self.custom_print("Decensored image. Returning it.")
return output_img
#there are better ways to do this, but im sleepy
def custom_print(self, text):
if self.ui_mode:
from PySide2.QtGui import QTextCursor
self.text_cursor.insertText(text)
self.text_cursor.insertText("\n")
self.text_edit.moveCursor(QTextCursor.End)
else:
print(text)
if __name__ == '__main__':
decensor = Decensor()
decensor.decensor_all_images_in_folder()

45
main.py
View File

@ -4,10 +4,10 @@
# Please read this tutorial on how to prepare your images for use with DeepCreamPy.
# The greater the number of variations, the longer decensoring process will be.
import sys
from PySide2.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QGridLayout, QGroupBox, QDesktopWidget, QApplication, QAction, qApp, QApplication, QMessageBox, QRadioButton, QPushButton, QLabel, QSizePolicy
from PySide2.QtCore import Qt
from PySide2.QtGui import QFont
import sys, time
from PySide2.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QGridLayout, QGroupBox, QDesktopWidget, QApplication, QAction, qApp, QApplication, QMessageBox, QRadioButton, QPushButton, QTextEdit, QLabel, QSizePolicy
from PySide2.QtCore import Qt, QObject
from PySide2.QtGui import QFont, QTextCursor
from decensor import Decensor
@ -25,7 +25,7 @@ class MainWindow(QWidget):
#Tutorial
self.tutorialLabel = QLabel()
self.tutorialLabel.setText("Welcome to DeepCreamPy!\nIf you're new to DCP, please read the manual.")
self.tutorialLabel.setText("Welcome to DeepCreamPy!\n\nIf you're new to DCP, please read the README.\nThis program does nothing without the proper setup of your images.")
self.tutorialLabel.setAlignment(Qt.AlignCenter)
self.tutorialLabel.setFont(QFont('Sans Serif', 13))
@ -57,27 +57,40 @@ class MainWindow(QWidget):
# varLayout.addStretch(1)
self.variationsGroupBox.setLayout(varLayout)
#button
decensorButton = QPushButton('Decensor Your Images')
decensorButton.clicked.connect(self.decensorClicked)
decensorButton.setSizePolicy(
#Decensor button
self.decensorButton = QPushButton('Decensor Your Images')
self.decensorButton.clicked.connect(self.decensorClicked)
self.decensorButton.setSizePolicy(
QSizePolicy.Preferred,
QSizePolicy.Preferred)
#Progress message
# self.progressGroupBox = QGroupBox('Progress')
self.progressMessage = QTextEdit()
self.progressCursor = QTextCursor(self.progressMessage.document())
self.progressMessage.setTextCursor(self.progressCursor)
self.progressCursor.insertText("After you prepared your images, click on the decensor button once to begin decensoring.\nPlease be patient.\nDecensoring will take time.\n")
#put all groups into grid
grid_layout.addWidget(self.tutorialLabel, 0, 0, 1, 2)
grid_layout.addWidget(self.censorTypeGroupBox, 1, 0, 1, 1)
grid_layout.addWidget(self.variationsGroupBox, 1, 1, 1, 1)
grid_layout.addWidget(decensorButton, 2, 0, 1, 2)
grid_layout.addWidget(self.decensorButton, 2, 0, 1, 2)
grid_layout.addWidget(self.progressMessage, 3, 0, 4, 2)
#window size settings
self.resize(300, 300)
self.resize(500, 500)
self.center()
self.setWindowTitle('DeepCreamPy v2.2.0')
self.setWindowTitle('DeepCreamPy v2.2.0-alpha')
self.show()
def decensorClicked(self):
decensor = Decensor()
self.decensorButton.setEnabled(False)
self.progressMessage.clear()
self.progressCursor.insertText("Decensoring has begun!\n")
decensor = Decensor(text_edit = self.progressMessage, text_cursor = self.progressCursor, ui_mode = True)
#https://stackoverflow.com/questions/42349470/pyqt-find-checked-radiobutton-in-a-group
#set decensor to right settings
#censor type
@ -101,6 +114,12 @@ class MainWindow(QWidget):
decensor.decensor_all_images_in_folder()
self.progressCursor.insertText("--------------------------------------------------------------------------\nTo decensor a new batch of images, please close this program and reopen it.\nThis is because the developer encountered a hard-to-fix bug that messes up repeated use of the decensor button.\nThe bug will be fixed in a future update.")
# time.sleep(3)
# sys.exit()
# self.decensorButton.setEnabled(False)
# def showAbout(self):
# QMessageBox.about(self, 'About', "DeepCreamPy v2.2.0 \n Developed by deeppomf")