diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..41463bce09527ae73bc1c23f8502f9b04d4bd91d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,10 @@ +*.pth filter=lfs diff=lfs merge=lfs -text +*.h5 filter=lfs diff=lfs merge=lfs -text +*.hdf5 filter=lfs diff=lfs merge=lfs -text +*.npy filter=lfs diff=lfs merge=lfs -text +app/ui/assets/components_backgrounds/main_window_welcome_bg.png filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text +*.jpeg filter=lfs diff=lfs merge=lfs -text +*.ico filter=lfs diff=lfs merge=lfs -text +*.json filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..62c893550adb53d3a8fc29a1584ff831cb829062 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6fc602a1cea20006d377355808f83d47acd33921 --- /dev/null +++ b/README.md @@ -0,0 +1,100 @@ +

+ InvisiCipher : Deep Learning-Based image Steganography with Chaotic Encryption and +Enhanced Super Resolution +

+ +

+ Project Logo +

+ +

+ Hide secrets, enhance images! +

+ +## Overview + +Welcome to our Steganography and Super Resolution project! This project combines the power of steganography techniques and super-resolution using deep learning models. Our goal is to hide a secret image within a cover image using advanced convolutional neural networks (CNNs) and then enhance the quality of the hidden image using an Enhanced Super Resolution Generative Adversarial Network (ESRGAN). We also provide an option to encrypt the steg image using various chaos encryption algorithms for added security. + +## Features + +✨ **Interactive Hiding**: Utilize our intuitive hide network powered by CNNs to embed secret images within cover images effortlessly. + +πŸ”’ **Secure Encryption**: Choose from multiple chaos encryption algorithms such as AES, Blowfish to encrypt your steg image and protect your secrets. + +🌟 **Enhanced Super Resolution**: Witness the magic of our ESRGAN model as it enhances the resolution and quality of the hidden image, revealing every detail. + +🎨 **Easy-to-Use**: Our project provides a user-friendly interface and simple scripts to perform hiding, encryption, decryption, and image enhancement with just a few lines of code. + +## Project Architecture + +The project architecture consists of the following components: + +1. **Prepare Network**: A CNN-based network that prepares the secret image for hiding by extracting essential features and encoding it. + +2. **Hide Network**: Another CNN-based network that embeds the prepared secret image within the cover image, producing the steg image. + +3. **Chaos Encryption**: Choose between AES encryption, Blowfish encryption to secure your steg image. + +4. **Chaos Decryption**: Decrypt the encrypted steg image using the corresponding decryption algorithm to retrieve the steg image. + +5. **Reveal Network**: A CNN-based network that extracts the secret image from the steg image by decoding the hidden information. + +6. **ESRGAN**: Our Enhanced Super Resolution Generative Adversarial Network (ESRGAN) model enhances the quality and resolution of the extracted secret image. + +## Getting Started + +To get started with our project, follow these steps: + +1. **Clone the Repository**: `git clone https://github.com/Asirwad/InvisiCipher.git` + +2. **Install Dependencies**: Install the required dependencies by running `pip install -r requirements.txt`. + +3. **Prepare Your Dataset**: Organize your cover and secret images dataset and place them in the appropriate directories. + +4. **Customize Configuration**: Modify the configuration files to set the desired parameters for the models and encryption algorithms. + +5. **Train the Models**: Run the training script to train the CNN models and ESRGAN: `python train.py`. + +6. **Explore the Scripts**: Utilize the provided scripts to hide, encrypt, reveal, and enhance images based on your specific requirements. + +## Welcome screen + +

+ Welcome +

+ +## Image hide + +

+ Image hide +

+ +## Image reveal + +

+ Image reveal +

+ +## Super resolution + +

+ Super resolution +

+ +## Contributing + +We welcome contributions from the open source community. If you find any issues or have suggestions for improvements, please feel free to open an issue or submit a pull request. + +## Acknowledgements + +We would like to acknowledge the following resources and libraries used in this project: + +- TensorFlow TensorFlow: [↗️](https://www.tensorflow.org/) +- PyTorch PyTorch: [↗️](https://pytorch.org/) +- PyQt PyQt: [↗️](https://www.qt.io/qt-for-python) + +## Contact + +For any questions or inquiries, please contact us at [asirwadsali@gmail.com](mailto:asirwadsali@gmail.com). diff --git a/app.py b/app.py new file mode 100644 index 0000000000000000000000000000000000000000..70bbe2f633cad8b74fc25bdd98d8cb8a8341f912 --- /dev/null +++ b/app.py @@ -0,0 +1,197 @@ +""" +StegNet β€” Gradio web interface. + +Entry point for HuggingFace Spaces (or any Gradio-compatible host). +Set the HF_API_KEY environment variable (Spaces secret) to enable +the "Generate Image" tab. + +Run locally: + python app.py +""" + +import os +import sys + +# Make sure the package root is on the path when run directly +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) + +import gradio as gr + +from app.models.DEEP_STEGO.hide_image import hide_image +from app.models.DEEP_STEGO.reveal_image import reveal_image +from app.models.ESRGAN.upscale_image import upscale_image +from app.models.encryption import aes, blowfish +from app.models.StableDiffusionAPI.StableDiffusionV2 import generate + + +# --------------------------------------------------------------------------- +# Handler functions +# --------------------------------------------------------------------------- + +def hide_fn(cover, secret): + if cover is None or secret is None: + return None, "Please upload both a cover image and a secret image." + try: + output_path = hide_image(cover, secret) + return output_path, "Secret image hidden successfully!" + except Exception as e: + return None, f"Error: {e}" + + +def reveal_fn(steg): + if steg is None: + return None, "Please upload a steg image." + try: + output_path = reveal_image(steg) + return output_path, "Secret image revealed successfully!" + except Exception as e: + return None, f"Error: {e}" + + +def encrypt_fn(image, key, algo): + if image is None: + return None, "Please upload an image." + if not key: + return None, "Please enter a secret key." + try: + if algo == "AES": + aes.encrypt(image, key) + else: + blowfish.encrypt(image, key) + enc_path = image + ".enc" + return enc_path, f"Image encrypted with {algo}. Download the file below." + except Exception as e: + return None, f"Error: {e}" + + +def decrypt_fn(enc_file, key, algo): + if enc_file is None: + return None, "Please upload an encrypted .enc file." + if not key: + return None, "Please enter the secret key." + try: + if algo == "AES": + code, filename = aes.decrypt(enc_file, key) + else: + code, filename = blowfish.decrypt(enc_file, key) + if code == -1: + return None, "Decryption failed β€” wrong key." + return filename, "Image decrypted successfully!" + except Exception as e: + return None, f"Error: {e}" + + +def upscale_fn(image): + if image is None: + return None, "Please upload a low-resolution image." + try: + output_path = upscale_image(image) + return output_path, "Image upscaled 4Γ— successfully!" + except Exception as e: + return None, f"Error: {e}" + + +def generate_fn(prompt): + if not prompt or not prompt.strip(): + return None, "Please enter a text prompt." + if not os.environ.get("HF_API_KEY"): + return None, "HF_API_KEY is not set. Add it as a Space secret to enable image generation." + try: + img = generate(prompt.strip()) + return img, "Image generated successfully!" + except Exception as e: + return None, f"Error: {e}" + + +# --------------------------------------------------------------------------- +# Gradio UI +# --------------------------------------------------------------------------- + +DESCRIPTION = """ +# StegNet +### AI-Based Secure Image Steganography Platform + +Hide secret images inside cover images using deep learning, encrypt the result, +reveal hidden images, enhance resolution with ESRGAN, or generate new images +with Stable Diffusion β€” all in one place. +""" + +with gr.Blocks(title="StegNet", theme=gr.themes.Soft()) as demo: + gr.Markdown(DESCRIPTION) + + # ── Tab 1: Hide Image ────────────────────────────────────────────────── + with gr.Tab("πŸ”’ Hide Image"): + gr.Markdown("Upload a **cover image** and a **secret image**. The model embeds the secret inside the cover.") + with gr.Row(): + cover_input = gr.Image(type="filepath", label="Cover Image") + secret_input = gr.Image(type="filepath", label="Secret Image") + hide_btn = gr.Button("Hide Secret", variant="primary") + with gr.Row(): + steg_output = gr.Image(label="Steg Image (download me)") + hide_status = gr.Textbox(label="Status", interactive=False, lines=2) + hide_btn.click(hide_fn, inputs=[cover_input, secret_input], outputs=[steg_output, hide_status]) + + # ── Tab 2: Reveal Image ──────────────────────────────────────────────── + with gr.Tab("πŸ” Reveal Image"): + gr.Markdown("Upload a **steg image** to extract the hidden secret image.") + steg_input = gr.Image(type="filepath", label="Steg Image") + reveal_btn = gr.Button("Reveal Secret", variant="primary") + with gr.Row(): + revealed_output = gr.Image(label="Revealed Secret Image") + reveal_status = gr.Textbox(label="Status", interactive=False, lines=2) + reveal_btn.click(reveal_fn, inputs=[steg_input], outputs=[revealed_output, reveal_status]) + + # ── Tab 3: Encrypt Image ─────────────────────────────────────────────── + with gr.Tab("πŸ›‘οΈ Encrypt Image"): + gr.Markdown("Encrypt any image file (e.g. your steg image) with AES or Blowfish.") + enc_image_input = gr.Image(type="filepath", label="Image to Encrypt") + with gr.Row(): + enc_key_input = gr.Textbox(label="Secret Key", type="password", placeholder="Enter a strong key…") + enc_algo = gr.Radio(["AES", "Blowfish"], value="AES", label="Algorithm") + enc_btn = gr.Button("Encrypt", variant="primary") + with gr.Row(): + enc_file_output = gr.File(label="Encrypted File (.enc) β€” Download") + enc_status = gr.Textbox(label="Status", interactive=False, lines=2) + enc_btn.click(encrypt_fn, inputs=[enc_image_input, enc_key_input, enc_algo], outputs=[enc_file_output, enc_status]) + + # ── Tab 4: Decrypt Image ─────────────────────────────────────────────── + with gr.Tab("πŸ”“ Decrypt Image"): + gr.Markdown("Upload an encrypted **.enc** file and the correct key to recover the image.") + dec_file_input = gr.File(label="Encrypted File (.enc)", type="filepath") + with gr.Row(): + dec_key_input = gr.Textbox(label="Secret Key", type="password", placeholder="Enter the key used for encryption…") + dec_algo = gr.Radio(["AES", "Blowfish"], value="AES", label="Algorithm") + dec_btn = gr.Button("Decrypt", variant="primary") + with gr.Row(): + dec_image_output = gr.Image(label="Decrypted Image") + dec_status = gr.Textbox(label="Status", interactive=False, lines=2) + dec_btn.click(decrypt_fn, inputs=[dec_file_input, dec_key_input, dec_algo], outputs=[dec_image_output, dec_status]) + + # ── Tab 5: Super Resolution ──────────────────────────────────────────── + with gr.Tab("✨ Super Resolution"): + gr.Markdown("Upscale any image **4Γ—** using ESRGAN.") + lr_input = gr.Image(type="filepath", label="Low-Resolution Image") + upscale_btn = gr.Button("Upscale 4Γ—", variant="primary") + with gr.Row(): + hr_output = gr.Image(label="High-Resolution Output") + upscale_status = gr.Textbox(label="Status", interactive=False, lines=2) + upscale_btn.click(upscale_fn, inputs=[lr_input], outputs=[hr_output, upscale_status]) + + # ── Tab 6: Generate Image ────────────────────────────────────────────── + with gr.Tab("🎨 Generate Image"): + gr.Markdown( + "Generate an image from a text prompt using Stable Diffusion 2.1. \n" + "*(Requires `HF_API_KEY` set as a Space secret.)*" + ) + prompt_input = gr.Textbox( + label="Text Prompt", + placeholder="A futuristic city at sunset, digital art…", + lines=2, + ) + gen_btn = gr.Button("Generate", variant="primary") + with gr.Row(): + gen_output = gr.Image(label="Generated Image") + gen_status = gr.Textbox(label="Status", interactive=False, lines=2) + gen_btn.click(generate_fn, inputs=[prompt_input], outputs=[gen_output, gen_status]) + +demo.launch() diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/app/main_CLI_v1.py b/app/main_CLI_v1.py new file mode 100644 index 0000000000000000000000000000000000000000..55fd9096a6bd8ca40f0034324c4e69e6451c988f --- /dev/null +++ b/app/main_CLI_v1.py @@ -0,0 +1,75 @@ +from tkinter import filedialog + +from app.models.encryption import blowfish +from app.models.DEEP_STEGO.hide_image import hide_image +from app.models.DEEP_STEGO.reveal_image import reveal_image +from app.models.ESRGAN.upscale_image import upscale_image +from app.models.encryption import aes as aes_chaos + +print("StegNet CLI") + +""" DEEP STEGANO """ +print("Image hiding") +print("input the cover image filename") +cover_filename = filedialog.askopenfilename(title="Select Image", filetypes=( +("PNG files", "*.png"), ("JPEG files", "*.jpg;*.jpeg"), ("All files", "*.*"))) +print("input the secret image filename") +secret_filename = filedialog.askopenfilename(title="Select Image", filetypes=( +("PNG files", "*.png"), ("JPEG files", "*.jpg;*.jpeg"), ("All files", "*.*"))) +hide_image(cover_filename, secret_filename) + +print("image hidden successfully\n\n") + + +print("1. AES") +print("2. Blowfish") +enc_choice = int(input("What type of encryption do you want? :")) +print("Your choice is : ", enc_choice) + +if enc_choice == 1: + # AES Encryption + filename = filedialog.askopenfilename(title="Select Image", filetypes=( + ("PNG files", "*.png"), ("JPEG files", "*.jpg;*.jpeg"), ("All files", "*.*"))) + key = input("Enter your secret key : ") + aes_chaos.encrypt(filename, key) + + # AES Decryption + print("AES Decryption") + key = input("Enter your secret key : ") + filename = filedialog.askopenfilename(title="Select Image", filetypes=( + ("All files", "*.*"), ("JPEG files", "*.jpg;*.jpeg"), ("PNG files", "*.png"))) + aes_chaos.decrypt(filename, key) + + +elif enc_choice == 2: + print("Blowfish Encryption") + # Blowfish Encryption + key = input("Enter your secret key : ") + filename = filedialog.askopenfilename(title="Select Image", filetypes=( + ("PNG files", "*.png"), ("JPEG files", "*.jpg;*.jpeg"), ("All files", "*.*"))) + blowfish.encrypt(filename, key) + print("Encrypted output saved to output_encrypted.png") + + # Blowfish Decryption + filename = filedialog.askopenfilename(title="Select Image", filetypes=( + ("PNG files", "*.png"), ("JPEG files", "*.jpg;*.jpeg"), ("All files", "*.*"))) + key = input("Enter your secret key : ") + blowfish.decrypt(filename, key) + +else: + print('Invalid choice') + +print("input the steg image filename") +steg_filename = filedialog.askopenfilename(title="Select Image", filetypes=( + ("PNG files", "*.png"), ("JPEG files", "*.jpg;*.jpeg"), ("All files", "*.*"))) +reveal_image(steg_filename) + +""" UP-SCALING """ +print("UP-SCALING") +print("input the low res image filename") +low_res_filename = filedialog.askopenfilename(title="Select Image", filetypes=( + ("PNG files", "*.png"), ("JPEG files", "*.jpg;*.jpeg"), ("All files", "*.*"))) +upscale_image(low_res_filename) + + + diff --git a/app/models/DEEP_STEGO/Utils/customLossWeight.py b/app/models/DEEP_STEGO/Utils/customLossWeight.py new file mode 100644 index 0000000000000000000000000000000000000000..b345ba3066a630a8e2a1234ebc798d051e06d841 --- /dev/null +++ b/app/models/DEEP_STEGO/Utils/customLossWeight.py @@ -0,0 +1,14 @@ +from tensorflow.keras.losses import mean_squared_error + + +# Loss functions +def custom_loss_1(secret, secret_pred): + # Compute L2 loss(MSE) for secret image + secret_mse = mean_squared_error(secret, secret_pred) + return secret_mse + + +def custom_loss_2(cover, cover_predict): + # Compute L2 loss(MSE) for cover image + cover_mse = mean_squared_error(cover, cover_predict) + return cover_mse diff --git a/app/models/DEEP_STEGO/Utils/enhance.py b/app/models/DEEP_STEGO/Utils/enhance.py new file mode 100644 index 0000000000000000000000000000000000000000..fccbd5562f780870d849dc7687441bfc65dc86bb --- /dev/null +++ b/app/models/DEEP_STEGO/Utils/enhance.py @@ -0,0 +1,70 @@ +import numpy as np +import argparse +import sys +import math +from PIL import ImageFilter, Image +import cv2 + +''' +Enhance video by applying denoise and sharpen filters +''' + +# Construct argument parser +parser = argparse.ArgumentParser(description='Use block shuffle') +parser.add_argument('--denoise', action='store_true', default=False) +parser.add_argument('--sharpen', action='store_true', default=False) +parser.add_argument("--input_video", required=True, help="path to input video") +args = vars(parser.parse_args()) + +# Start video enhancement +print('\nEnhancing video ...\n') + + +# Update progress bar +def update_progress(current_frame, total_frames): + progress = math.ceil((current_frame / total_frames) * 100) + sys.stdout.write('\rProgress: [{0}] {1}%'.format('>' * math.ceil(progress / 10), progress)) + + +# Open the input video +vid_cap = cv2.VideoCapture(args['input_video']) + +# Total input video frames +num_frames = int(vid_cap.get(cv2.CAP_PROP_FRAME_COUNT)) +print("Total frames in input video:", num_frames) + +# Initialize the video writer +enhanced_video = cv2.VideoWriter('results/enhanced_secret_300.avi', cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), 15, + (300, 300)) + +# Initialize the frame buffer +frames = [] + +# Load the frames to buffer +while vid_cap.isOpened(): + success, image = vid_cap.read() + if success: + frames.append(image) + else: + break + +# Set up the start frame index +start_frame = 5 + +# Enhance and save video frame-by-frame +for i in range(start_frame, len(frames) - (start_frame + 1)): + output = frames[i] + if args["denoise"]: + output = cv2.fastNlMeansDenoisingColoredMulti(frames, i, 11) + if args["sharpen"]: + output = np.array(Image.fromarray(output).filter(ImageFilter.DETAIL)) + enhanced_video.write(output) + update_progress(i, num_frames - (start_frame + 1)) + +# Finish video enhancement +print('\n\nSuccessfully enhanced video !!!\n') + +''' +Sample run:- +python enhance.py --input_video results/secret_outvid_300.avi --denoise --sharpen +''' diff --git a/app/models/DEEP_STEGO/Utils/eval.py b/app/models/DEEP_STEGO/Utils/eval.py new file mode 100644 index 0000000000000000000000000000000000000000..563b0c17d141517b6da7ee7b48b01ff2485d05d8 --- /dev/null +++ b/app/models/DEEP_STEGO/Utils/eval.py @@ -0,0 +1,135 @@ +import numpy as np +import random +import glob +import sys +import os +from PIL import Image +import matplotlib.pyplot as plt +from tensorflow.keras.losses import mean_squared_error +from tensorflow.keras.preprocessing.image import ImageDataGenerator +from tensorflow.keras.models import load_model +from pathlib import Path + +''' +Evaluates the trained model on a new dataset +Uses Mean Square Error as evaluation metric +''' + +# Path for evaluation dataset +EVAL_PATH = Path(sys.argv[1]).resolve() +BATCH_SIZE = 1 +TEST_NUM = len(glob.glob(str(EVAL_PATH))) + + +# Normalize input for evaluation +def normalize_batch(imgs): + return (imgs - np.array([0.485, 0.456, 0.406])) / np.array([0.229, 0.224, 0.225]) + + +# Denormalize output for prediction +def denormalize_batch(imgs, should_clip=True): + imgs = (imgs * np.array([0.229, 0.224, 0.225])) + np.array([0.485, 0.456, 0.406]) + + if should_clip: + imgs = np.clip(imgs, 0, 1) + return imgs + + +# Create a data generator for evaluation +test_imgen = ImageDataGenerator(rescale=1. / 255) + + +# Compute L2 loss(MSE) for secret image +def custom_loss_1(secret, secret_pred): + secret_mse = mean_squared_error(secret, secret_pred) + return secret_mse + + +# Compute L2 loss(MSE) for cover image +def custom_loss_2(cover, cover_pred): + cover_mse = mean_squared_error(cover, cover_pred) + return cover_mse + + +# Load the trained model +model = load_model(sys.argv[2], custom_objects={'custom_loss_1': custom_loss_1, 'custom_loss_2': custom_loss_2}) + + +# Custom data generator +def generate_generator_multiple(generator, direc): + genX1 = generator.flow_from_directory(direc, target_size=(224, 224), batch_size=12, shuffle=True, seed=3, + class_mode=None) + genX2 = generator.flow_from_directory(direc, target_size=(224, 224), batch_size=12, shuffle=True, seed=8, + class_mode=None) + + while True: + X1i = normalize_batch(genX1.next()) + X2i = normalize_batch(genX2.next()) + + yield ({'secret': X1i, 'cover': X2i}, + {'hide_conv_f': X2i, 'revl_conv_f': X1i}) # Yield both images and their mutual label + + +# Load data using generator +testgenerator = generate_generator_multiple(test_imgen, direc=str(EVAL_PATH.parent)) + +# Evaluates the model using data generator +score = model.evaluate(testgenerator, steps=TEST_NUM / BATCH_SIZE, verbose=0) + +# Print mean square error +print('Mean square error:', score[0]) + +''' +Test the model on a random pair of images (test) +Plots the input and output for verification +''' + + +# Perform prediction for single input +def predict(source, cover): + # Normalize inputs + secret = np.array(source / 255.0) + cover = np.array(cover / 255.0) + + # Predict output + coverout, secretout = model.predict( + [normalize_batch(np.reshape(secret, (1, 224, 224, 3))), normalize_batch(np.reshape(cover, (1, 224, 224, 3)))]) + + # Postprocess output cover image + coverout = denormalize_batch(coverout) + coverout = np.squeeze(coverout) * 255.0 + coverout = np.uint8(coverout) + + # Postprocess output secret image + secretout = denormalize_batch(secretout) + secretout = np.squeeze(secretout) * 255.0 + secretout = np.uint8(secretout) + + # Plot output images + fig_out, ax_out = plt.subplots(1, 2, figsize=(10, 10)) + fig_out.suptitle('Outputs') + ax_out[0].title.set_text("Secret output") + ax_out[0].imshow(secretout) + ax_out[1].title.set_text("Cover output") + ax_out[1].imshow(coverout) + print("Prediction Completed!") + + +# Load random test image pairs +sec, cov = random.sample(os.listdir(str(EVAL_PATH)), k=2) + +source = np.array(Image.open(str(EVAL_PATH) + '/' + sec)) +cover = np.array(Image.open(str(EVAL_PATH) + '/' + cov)) + +# Plot input images +fig_in, ax_in = plt.subplots(1, 2, figsize=(10, 10)) +fig_in.suptitle('Inputs') +ax_in[0].title.set_text("Secret input") +ax_in[0].imshow(source) +ax_in[1].title.set_text("Cover input") +ax_in[1].imshow(cover) + +# Perform prediction +predict(source, cover) + +# Sample run: python eval.py dataset/eval_data checkpoints/steg_model-06-0.03.hdf5 diff --git a/app/models/DEEP_STEGO/Utils/preprocessing.py b/app/models/DEEP_STEGO/Utils/preprocessing.py new file mode 100644 index 0000000000000000000000000000000000000000..336d4e15d07e2ef1bcc9f33aecf9cbb1e15abee4 --- /dev/null +++ b/app/models/DEEP_STEGO/Utils/preprocessing.py @@ -0,0 +1,18 @@ +import numpy as np + + +# Preprocessing functions +def normalize_batch(images): + """Performs channel-wise z-score normalization""" + + return (images - np.array([0.485, 0.456, 0.406])) / np.array([0.229, 0.224, 0.225]) + + +def denormalize_batch(images, should_clip=True): + """Denormalize the images for prediction""" + + images = (images * np.array([0.229, 0.224, 0.225])) + np.array([0.485, 0.456, 0.406]) + + if should_clip: + images = np.clip(images, 0, 1) + return images diff --git a/app/models/DEEP_STEGO/Utils/progressbarCL_animation.py b/app/models/DEEP_STEGO/Utils/progressbarCL_animation.py new file mode 100644 index 0000000000000000000000000000000000000000..f15b8cbceddba8d210526cb0cdac6ea2a77b83b2 --- /dev/null +++ b/app/models/DEEP_STEGO/Utils/progressbarCL_animation.py @@ -0,0 +1,7 @@ +import math +import sys + + +def update_progress(current_frame, total_frames): + progress = math.ceil((current_frame/total_frames)*100) + sys.stdout.write('\rProgress: [{0}] {1}%'.format('>'*math.ceil(progress/10), progress)) \ No newline at end of file diff --git a/app/models/DEEP_STEGO/Utils/test.py b/app/models/DEEP_STEGO/Utils/test.py new file mode 100644 index 0000000000000000000000000000000000000000..8d731e7aa53ffc012474261c9dae22a2321cda1b --- /dev/null +++ b/app/models/DEEP_STEGO/Utils/test.py @@ -0,0 +1,80 @@ +import numpy as np +import sys +from tensorflow.keras.models import Model +from tensorflow.keras.utils import plot_model +from tensorflow.keras.models import load_model +from PIL import Image +import matplotlib.pyplot as plt +from random import randint +import imageio +from skimage.util.shape import view_as_blocks + +''' +Test the model on sample images (unseen) +Plot the input and output images +''' + +# Load test images +test_images = np.load(sys.argv[1]) + +# Load model +model = load_model(sys.argv[2], compile=False) + + +# Normalize inputs +def normalize_batch(imgs): + """ Performs channel-wise z-score normalization """ + + return (imgs - np.array([0.485, 0.456, 0.406])) / np.array([0.229, 0.224, 0.225]) + + +# Denormalize outputs +def denormalize_batch(imgs, should_clip=True): + imgs = (imgs * np.array([0.229, 0.224, 0.225])) + np.array([0.485, 0.456, 0.406]) + + if should_clip: + imgs = np.clip(imgs, 0, 1) + return imgs + + +# Load images as batch (batch size -4) +secretin = test_images[np.random.choice(len(test_images), size=4, replace=False)] +coverin = test_images[np.random.choice(len(test_images), size=4, replace=False)] + +# Perform batch prediction +coverout, secretout = model.predict([normalize_batch(secretin), normalize_batch(coverin)]) + +# Postprocess cover output +coverout = denormalize_batch(coverout) +coverout = np.squeeze(coverout) * 255.0 +coverout = np.uint8(coverout) + +# Postprocess secret output +secretout = denormalize_batch(secretout) +secretout = np.squeeze(secretout) * 255.0 +secretout = np.uint8(secretout) + +# Convert images to UINT8 format (0-255) +coverin = np.uint8(np.squeeze(coverin * 255.0)) +secretin = np.uint8(np.squeeze(secretin * 255.0)) + + +# Plot the images +def plot(im, title): + fig = plt.figure(figsize=(20, 20)) + + for i in range(4): + sub = fig.add_subplot(1, 4, i + 1) + sub.title.set_text(title + " " + str(i + 1)) + sub.imshow(im[i, :, :, :]) + + +# Plot secret input and output +plot(secretin, "Secret Input") +plot(secretout, "Secret Output") + +# Plot cover input and output +plot(coverin, "Cover Input") +plot(coverout, "Cover Output") + +# Sample run: python test.py test/testdata.npy checkpoints/steg_model-06-0.03.hdf5 diff --git a/app/models/DEEP_STEGO/checkpoints/steg_model-06-0.03.hdf5 b/app/models/DEEP_STEGO/checkpoints/steg_model-06-0.03.hdf5 new file mode 100644 index 0000000000000000000000000000000000000000..d5fc3dec71daa287538444b9fd918d410520ec10 --- /dev/null +++ b/app/models/DEEP_STEGO/checkpoints/steg_model-06-0.03.hdf5 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2567ad658864875aba9f3c51fde8e2b032d4964b1382298e2d36c62708adceb +size 32115520 diff --git a/app/models/DEEP_STEGO/hide_image.py b/app/models/DEEP_STEGO/hide_image.py new file mode 100644 index 0000000000000000000000000000000000000000..88f7fc2f233415f8955b117946e2d80f7de3decc --- /dev/null +++ b/app/models/DEEP_STEGO/hide_image.py @@ -0,0 +1,46 @@ +import os +import tempfile +import numpy as np +from tensorflow.keras.models import load_model +from PIL import Image +import imageio +from app.models.DEEP_STEGO.Utils.preprocessing import normalize_batch, denormalize_batch + +_MODEL_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'models', 'hide.h5') +_model = None + + +def _get_model(): + global _model + if _model is None: + _model = load_model(_MODEL_PATH) + return _model + + +def hide_image(cover_image_filepath, secret_image_filepath): + model = _get_model() + + secret_image_in = Image.open(secret_image_filepath).convert('RGB') + cover_image_in = Image.open(cover_image_filepath).convert('RGB') + + if secret_image_in.size != (224, 224): + secret_image_in = secret_image_in.resize((224, 224)) + if cover_image_in.size != (224, 224): + cover_image_in = cover_image_in.resize((224, 224)) + + secret_image_in = np.array(secret_image_in).reshape(1, 224, 224, 3) / 255.0 + cover_image_in = np.array(cover_image_in).reshape(1, 224, 224, 3) / 255.0 + + steg_image_out = model.predict([normalize_batch(secret_image_in), normalize_batch(cover_image_in)]) + + steg_image_out = denormalize_batch(steg_image_out) + steg_image_out = np.squeeze(steg_image_out) * 255.0 + steg_image_out = np.uint8(steg_image_out) + + _, output_path = tempfile.mkstemp(suffix='.png') + imageio.imsave(output_path, steg_image_out) + print("Saved steg image to", output_path) + + return output_path + + diff --git a/app/models/DEEP_STEGO/models/hide.h5 b/app/models/DEEP_STEGO/models/hide.h5 new file mode 100644 index 0000000000000000000000000000000000000000..b5f21493ebbd6c494afd935e8a55ffc2c27d5931 --- /dev/null +++ b/app/models/DEEP_STEGO/models/hide.h5 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d134911e755c063b31d1f2f76678a2b690c5952536bb7c01981cdf6d68e3724b +size 7692752 diff --git a/app/models/DEEP_STEGO/models/hide.h5.png b/app/models/DEEP_STEGO/models/hide.h5.png new file mode 100644 index 0000000000000000000000000000000000000000..503c78da0e6475f5bb417bdfe7c46007af6d878f --- /dev/null +++ b/app/models/DEEP_STEGO/models/hide.h5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6a735df67b3ed400e1f06afe00c720854009be16485bd10e097f0e3f3454907 +size 296389 diff --git a/app/models/DEEP_STEGO/models/hide.png b/app/models/DEEP_STEGO/models/hide.png new file mode 100644 index 0000000000000000000000000000000000000000..62094b99cc3f1e53b3cd3bba764b1f5b144ffddc --- /dev/null +++ b/app/models/DEEP_STEGO/models/hide.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:baa31d7b892d31277236c656e697efe4e5bd611b7b52bd77c3c34d8e2aacc8ee +size 90657 diff --git a/app/models/DEEP_STEGO/models/model_double.png b/app/models/DEEP_STEGO/models/model_double.png new file mode 100644 index 0000000000000000000000000000000000000000..4b274b80e603e6e565ed17f8c0f6b7a96088e69d --- /dev/null +++ b/app/models/DEEP_STEGO/models/model_double.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d8e68c06aa466bf2eff36cb94748a818d7dfaf995ff8ded38c1d33e88be91b7 +size 137882 diff --git a/app/models/DEEP_STEGO/models/reveal.h5 b/app/models/DEEP_STEGO/models/reveal.h5 new file mode 100644 index 0000000000000000000000000000000000000000..c573ac71040ff5003b703b28312f749a35346f67 --- /dev/null +++ b/app/models/DEEP_STEGO/models/reveal.h5 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f60e937b2957601be10e58df12aaa27b51763449a7883baaf50613500c2dfb32 +size 3102992 diff --git a/app/models/DEEP_STEGO/models/reveal.h5.png b/app/models/DEEP_STEGO/models/reveal.h5.png new file mode 100644 index 0000000000000000000000000000000000000000..0d44aa05fadcba1105bc4e79f5309b2e3dd4fb3c --- /dev/null +++ b/app/models/DEEP_STEGO/models/reveal.h5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acd1faad8493abec5bf2542e4c923c4c701813102fbf1efada5cfd7c4092575e +size 146762 diff --git a/app/models/DEEP_STEGO/models/reveal.png b/app/models/DEEP_STEGO/models/reveal.png new file mode 100644 index 0000000000000000000000000000000000000000..fbfb0f8695111eb4e6716ab3b48612349a52a888 --- /dev/null +++ b/app/models/DEEP_STEGO/models/reveal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56c54e864c5edeebd013aa055f98b5a9b862c984070e76990257d01faf4ce6b7 +size 49726 diff --git a/app/models/DEEP_STEGO/results/input.png b/app/models/DEEP_STEGO/results/input.png new file mode 100644 index 0000000000000000000000000000000000000000..e0ad652d3ce04760d8574d05be667d3b0f2c1a7c --- /dev/null +++ b/app/models/DEEP_STEGO/results/input.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2fdb45cf2a205da6f29d70c751ce6199962aaec0ba1c8dace1dadde4006d57f +size 188547 diff --git a/app/models/DEEP_STEGO/results/output.png b/app/models/DEEP_STEGO/results/output.png new file mode 100644 index 0000000000000000000000000000000000000000..b2e87f30ec2cee566436e9ea7e3921823f97d0a6 --- /dev/null +++ b/app/models/DEEP_STEGO/results/output.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b65181d36680559b4b972988e9eb3f360552578e754be2e13f42f173c26376df +size 203882 diff --git a/app/models/DEEP_STEGO/reveal_image.py b/app/models/DEEP_STEGO/reveal_image.py new file mode 100644 index 0000000000000000000000000000000000000000..ef30edcf747d46828c7875067d900196f70f0f08 --- /dev/null +++ b/app/models/DEEP_STEGO/reveal_image.py @@ -0,0 +1,45 @@ +import os +import tempfile +import numpy as np +from tensorflow.keras.models import load_model +from PIL import Image +import imageio +from app.models.DEEP_STEGO.Utils.preprocessing import normalize_batch, denormalize_batch + +_MODEL_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'models', 'reveal.h5') +_model = None + + +def _get_model(): + global _model + if _model is None: + _model = load_model(_MODEL_PATH, compile=False) + return _model + + +def reveal_image(stego_image_filepath): + model = _get_model() + + stego_image = Image.open(stego_image_filepath).convert('RGB') + + if stego_image.size != (224, 224): + stego_image = stego_image.resize((224, 224)) + + stego_image = np.array(stego_image).reshape(1, 224, 224, 3) / 255.0 + + secret_image_out = model.predict([normalize_batch(stego_image)]) + + secret_image_out = denormalize_batch(secret_image_out) + secret_image_out = np.squeeze(secret_image_out) * 255.0 + secret_image_out = np.uint8(secret_image_out) + + _, output_path = tempfile.mkstemp(suffix='.png') + imageio.imsave(output_path, secret_image_out) + print("Saved revealed image to", output_path) + + return output_path + + + + + diff --git a/app/models/DEEP_STEGO/test/cover.png b/app/models/DEEP_STEGO/test/cover.png new file mode 100644 index 0000000000000000000000000000000000000000..6bcaa94ed724b34a588e2482b373f32240b9a080 --- /dev/null +++ b/app/models/DEEP_STEGO/test/cover.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e61384130327a4fdcd0c5e32ebc663a3fd447723758c8d521cd6a7bf48ada1a +size 78411 diff --git a/app/models/DEEP_STEGO/test/images/100098.jpg b/app/models/DEEP_STEGO/test/images/100098.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2b1dceec59b63a517c57f236c8c05a8525565e0d --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/100098.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cc3ebc05afee168371c68cd61801bc4b7a6c978dea7ec8361b6e661f56196bc +size 30046 diff --git a/app/models/DEEP_STEGO/test/images/101027.jpg b/app/models/DEEP_STEGO/test/images/101027.jpg new file mode 100644 index 0000000000000000000000000000000000000000..31da49c6781e6ec841f8e071c1ff6553555e149d --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/101027.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02071459ecc3928b59e21a2bd9df94cdde3bb41104b4e5623cc0727189dcd562 +size 23251 diff --git a/app/models/DEEP_STEGO/test/images/103006.jpg b/app/models/DEEP_STEGO/test/images/103006.jpg new file mode 100644 index 0000000000000000000000000000000000000000..91285d439bbe889df51ddb5c587c3293d1c53252 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/103006.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1eecbd3b2fcd55086a6bff68815985d6138358ce70613962f87eee25060acac6 +size 26221 diff --git a/app/models/DEEP_STEGO/test/images/103029.jpg b/app/models/DEEP_STEGO/test/images/103029.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6f18ec6e35e7b35e13b298fc54c918ba28e31de0 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/103029.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2582b16c2d10eff539ba50ba5bd5eb7ff80a110ae55b0dfc682ef73748e74d8c +size 15906 diff --git a/app/models/DEEP_STEGO/test/images/104010.jpg b/app/models/DEEP_STEGO/test/images/104010.jpg new file mode 100644 index 0000000000000000000000000000000000000000..92a182ade7a57274b62f30951f726379804163b9 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/104010.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a243cafa4dbedbea5c2bde392e05b7c557a957b84751e87b6742ee93ff5c7f6 +size 25299 diff --git a/app/models/DEEP_STEGO/test/images/105027.jpg b/app/models/DEEP_STEGO/test/images/105027.jpg new file mode 100644 index 0000000000000000000000000000000000000000..12c9e784721064f7eaf009a62544b1b2ce4ef4e9 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/105027.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fd0e01544e30b1467c58d3c11badb72baa4eab6d250856dd0e42a11fd4866f7 +size 19945 diff --git a/app/models/DEEP_STEGO/test/images/106005.jpg b/app/models/DEEP_STEGO/test/images/106005.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8eb9e98079373c8b604a9427ba46655f983f2ce0 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/106005.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5ee139c1bdf32d613d9cf5d0b4a066e9fbc983222e2d172859f0cdd96b78db2 +size 14294 diff --git a/app/models/DEEP_STEGO/test/images/106024.jpg b/app/models/DEEP_STEGO/test/images/106024.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9fa06634f9be7d0a3e2e0b857474e12cfae9f5c9 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/106024.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b86b343843d811f5ea8e19df32eea9b551a27fb1e1b5a0b146c030721f2966e7 +size 13668 diff --git a/app/models/DEEP_STEGO/test/images/106025.jpg b/app/models/DEEP_STEGO/test/images/106025.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e332c083ad6c69c4bca5ca20ec54b0bf9ab92185 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/106025.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8406b68383086a77a40f7474f2e8f743b724a96f50357b322182dd86965d8c3 +size 10444 diff --git a/app/models/DEEP_STEGO/test/images/106047.jpg b/app/models/DEEP_STEGO/test/images/106047.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fe4fa3aeafa069e060bebb98b8245e878c50b09c --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/106047.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b116cad8437cace1d892d3797e90a250c84fff53285945d3eeb8d8beb6f9b31 +size 17114 diff --git a/app/models/DEEP_STEGO/test/images/107072.jpg b/app/models/DEEP_STEGO/test/images/107072.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ef5cca39be4be3a2e5fb05d980e041ffad32ce25 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/107072.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88d330d4cd64dab5bc2a05f7092aae3d5359ff17566c7fc52f22537b4d46d315 +size 24969 diff --git a/app/models/DEEP_STEGO/test/images/108004.jpg b/app/models/DEEP_STEGO/test/images/108004.jpg new file mode 100644 index 0000000000000000000000000000000000000000..43dca9167e08eb44a6b1ac2cf38ad3c841335660 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/108004.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a3c2a8cfaeded0657eaf509a35275b8831466ec1483e821dc7a3689a65e3c4b +size 27778 diff --git a/app/models/DEEP_STEGO/test/images/108041.jpg b/app/models/DEEP_STEGO/test/images/108041.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b48a9965e1368dc50e34e17c4fb2bfa32628aa38 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/108041.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1a8bb4a8f189e00c7ba0c3333747ab00177f9c4da12e38eff7d44136e1b0fbd +size 21045 diff --git a/app/models/DEEP_STEGO/test/images/108069.jpg b/app/models/DEEP_STEGO/test/images/108069.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fb3ec0bf8fe8b5026ddc7e522953f5111cc933c1 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/108069.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64105352e2f31f253464ac00646c43e4cfc8519a20459b1bc202e4c6e8c3ffdc +size 26745 diff --git a/app/models/DEEP_STEGO/test/images/108070.jpg b/app/models/DEEP_STEGO/test/images/108070.jpg new file mode 100644 index 0000000000000000000000000000000000000000..402a15568fee72f1302d397d9dcf6dbcede28037 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/108070.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15b38de0141ebdfb3e24cb3f3090509d0deca82c63bfe9c97fbf493a41aba7a7 +size 27541 diff --git a/app/models/DEEP_STEGO/test/images/112056.jpg b/app/models/DEEP_STEGO/test/images/112056.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1f46089a6cb95a92395a63ead67fedd4b8abe235 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/112056.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f78f2e76baca8129938b7c8d9c71b8aace2f4c4d600a9d969bfcd025af519fc +size 13806 diff --git a/app/models/DEEP_STEGO/test/images/112082.jpg b/app/models/DEEP_STEGO/test/images/112082.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1967a23227c17cb7caf1066c7ece1e101225a2db --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/112082.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d44830f2108ba022bb4aeb93369e7970c4704718107277546072b579c1a425a6 +size 24346 diff --git a/app/models/DEEP_STEGO/test/images/113016.jpg b/app/models/DEEP_STEGO/test/images/113016.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a6bd1ebc6aefde23bedd880d8a7329445fad2445 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/113016.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d06addf6d5fefc012d6b08d2bd92f962bf2dab91a5317d7ceaee49d466d1c367 +size 27505 diff --git a/app/models/DEEP_STEGO/test/images/113044.jpg b/app/models/DEEP_STEGO/test/images/113044.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aa14c875ce9d934d0de91e8cfc3eefa4c00fd7f0 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/113044.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:590f8063a1177764f49390c2baca8e023b3846e11bcbe14e488813379852d503 +size 27368 diff --git a/app/models/DEEP_STEGO/test/images/12003.jpg b/app/models/DEEP_STEGO/test/images/12003.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7ff31136f53ef4627036e92f35612b1cc1543ff2 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/12003.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2899a821588a3313434d3c4d85320d419534f151414c5d039754fb279208d65 +size 26594 diff --git a/app/models/DEEP_STEGO/test/images/124084.jpg b/app/models/DEEP_STEGO/test/images/124084.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4449e7300b1e57da31f90529d14c50e51028c269 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/124084.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a291fc736acc5bc64544dfca7d9728c810eeacc03c26acd0153f9389bfb785af +size 21270 diff --git a/app/models/DEEP_STEGO/test/images/126007.jpg b/app/models/DEEP_STEGO/test/images/126007.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d03fe4e5d8cea7e1e9e2534676741e74b01067c5 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/126007.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77da911c10894c83e0687d73a8f15a1a0a8baf96762454cd3cf5693e087c99ad +size 17814 diff --git a/app/models/DEEP_STEGO/test/images/130014.jpg b/app/models/DEEP_STEGO/test/images/130014.jpg new file mode 100644 index 0000000000000000000000000000000000000000..75db848b93f54a390351a96eb332fb429e76bd4c --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/130014.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d216637fc4bbaaecaf2120e4e295f7938049fd41140b9b8556520d50a5aa6630 +size 19388 diff --git a/app/models/DEEP_STEGO/test/images/130026.jpg b/app/models/DEEP_STEGO/test/images/130026.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4451592efba0691147df2db9b796d9e9d4b06947 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/130026.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da1ef567d4418d823d5dd0c0400a58a8323a948c0c5f9c63303af48224c17a13 +size 23574 diff --git a/app/models/DEEP_STEGO/test/images/134008.jpg b/app/models/DEEP_STEGO/test/images/134008.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9ecd9ede56e694c7234c98fddf266a967dab21eb --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/134008.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5669969f9328a20804ad0b25a1e5a49f70527125218c4c49c9d89eef620cf81 +size 18222 diff --git a/app/models/DEEP_STEGO/test/images/135037.jpg b/app/models/DEEP_STEGO/test/images/135037.jpg new file mode 100644 index 0000000000000000000000000000000000000000..34f00e3c20c19f23e78e46366cf71c3a53c40009 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/135037.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16871bd37fdf02ca9dd8005407a13bf2a6a8d9e7682f24054bbc811c7153120d +size 15018 diff --git a/app/models/DEEP_STEGO/test/images/135069.jpg b/app/models/DEEP_STEGO/test/images/135069.jpg new file mode 100644 index 0000000000000000000000000000000000000000..98e7ea45a5671b441598bfe13c78e01db311fa3b --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/135069.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:052120f086be82c4f5579c9caa6fea27e1d13c21a7a793500caef7f23ec01f49 +size 6125 diff --git a/app/models/DEEP_STEGO/test/images/143090.jpg b/app/models/DEEP_STEGO/test/images/143090.jpg new file mode 100644 index 0000000000000000000000000000000000000000..512d07f4e114341690baf56562db1abb4a3d651b --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/143090.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:427d400dc69abe6bb864a51cb397b14ce481540dcfd626d4ee794c9b3e0c7e2f +size 14502 diff --git a/app/models/DEEP_STEGO/test/images/15062.jpg b/app/models/DEEP_STEGO/test/images/15062.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d8b0d77baac03ead6f3cdbc25bd3c04fa5ccb744 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/15062.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b6cacf768b5194b3908a5eafd0033b463bf12a67f32430558829705100e5a55 +size 24210 diff --git a/app/models/DEEP_STEGO/test/images/157032.jpg b/app/models/DEEP_STEGO/test/images/157032.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6ffc412d1c78e4749d9c74b7e938b46aa6d5bc46 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/157032.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:845e7c641895595208081c586cfe31ec3b9cd688a7378e608848a68c0b6c3f48 +size 15637 diff --git a/app/models/DEEP_STEGO/test/images/159091.jpg b/app/models/DEEP_STEGO/test/images/159091.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6565870f1406309280611515e06a2dc0eb011ce8 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/159091.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c92068f0e94974dc2c4298d9a778320f23575bcdab4ebc9a308ff23bfce62b54 +size 23895 diff --git a/app/models/DEEP_STEGO/test/images/160068.jpg b/app/models/DEEP_STEGO/test/images/160068.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d866dc7c782ee72230d568c2ffd24d2f592a8e74 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/160068.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:575a13c899498201e5969160604feafb953ea3a728cf62a33a87be325d7d26f4 +size 17625 diff --git a/app/models/DEEP_STEGO/test/images/164046.jpg b/app/models/DEEP_STEGO/test/images/164046.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5cdb91329798ebbd2790889f736f31b07ad2787e --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/164046.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d98199fa5c75d26ac72360eea3d9d252995cb4559b34626bc0467bb1bad63187 +size 17902 diff --git a/app/models/DEEP_STEGO/test/images/168084.jpg b/app/models/DEEP_STEGO/test/images/168084.jpg new file mode 100644 index 0000000000000000000000000000000000000000..303ef6bd1a401cbdf1ecd2694a188fad5ce54b1a --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/168084.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54fc0552995b505e8855ebc2e14dee569b1f509d021ba9fa236f6b2ecc52dca8 +size 16018 diff --git a/app/models/DEEP_STEGO/test/images/173036.jpg b/app/models/DEEP_STEGO/test/images/173036.jpg new file mode 100644 index 0000000000000000000000000000000000000000..176e7ecd7cf93e30c7c527f74b80f605ff623846 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/173036.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48eede8ace56dd91c947b7152b7cd3080588e50fefaf1c34221e1f314a5a77db +size 20184 diff --git a/app/models/DEEP_STEGO/test/images/181021.jpg b/app/models/DEEP_STEGO/test/images/181021.jpg new file mode 100644 index 0000000000000000000000000000000000000000..99b812773f601373ee359b21c345ed7c8ac66aa8 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/181021.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eecd738d8109a273524a89dd9c0213f31f8b883a2cde77c396311235fdf3ff7a +size 19501 diff --git a/app/models/DEEP_STEGO/test/images/183087.jpg b/app/models/DEEP_STEGO/test/images/183087.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4cf25f9b773ee34239868b7e710e10998c17581c --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/183087.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86d2b71fa5dbe78571e3bfc271712c37e3a92cc66770e65c23058438cc4bd652 +size 19719 diff --git a/app/models/DEEP_STEGO/test/images/187029.jpg b/app/models/DEEP_STEGO/test/images/187029.jpg new file mode 100644 index 0000000000000000000000000000000000000000..87fda7fbc82d984f5feae634b8e44678b1514f3d --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/187029.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3fcbd8d6d9304365430b151ef8ab01dff2220bffb13400bce6c664f7e45216b9 +size 17888 diff --git a/app/models/DEEP_STEGO/test/images/187083.jpg b/app/models/DEEP_STEGO/test/images/187083.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f8394de79a9393a513e204b699d430d8a24ca2b2 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/187083.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f81b8ea5805c6023de0bc701aa4e4c49f719579fe746113687cc4edc71b2811b +size 17591 diff --git a/app/models/DEEP_STEGO/test/images/189011.jpg b/app/models/DEEP_STEGO/test/images/189011.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0ebd6ce0800ef3cf719aba45e052273dfaf9db8c --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/189011.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d352feafcb7abb4c795367b51e86f0def217cab167f166b3b1fedf6dbc35b1f8 +size 17791 diff --git a/app/models/DEEP_STEGO/test/images/189080.jpg b/app/models/DEEP_STEGO/test/images/189080.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fe57f2326b94543c5ad1c7f7ea419bcb6148137c --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/189080.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:399a62224b4357ec8db0b54fcd36cdf8d796f0f6fb057ba71bf8069f374389e5 +size 14773 diff --git a/app/models/DEEP_STEGO/test/images/207056.jpg b/app/models/DEEP_STEGO/test/images/207056.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d163a1be92b072134bab1751fb29fa5a8e8d4560 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/207056.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4d59d15778089be055caec39445396e560710570021a50d7c599f3e2c2b3267 +size 19529 diff --git a/app/models/DEEP_STEGO/test/images/208078.jpg b/app/models/DEEP_STEGO/test/images/208078.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ae91af1a02852f0461e49ccc19d73e49e7325cad --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/208078.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54fe5dbfc3297eb308b6eefe1738d9e756eae56ac7179153e87ef6be491ed5b1 +size 25212 diff --git a/app/models/DEEP_STEGO/test/images/227092.jpg b/app/models/DEEP_STEGO/test/images/227092.jpg new file mode 100644 index 0000000000000000000000000000000000000000..09aadd9a842100eca2cc25af9c077ec6b11d6a3c --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/227092.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39107fb4c6fb0bd8bad5ad740dfff0f92f85c930b39cec00e4716c9000cbccd2 +size 12446 diff --git a/app/models/DEEP_STEGO/test/images/228076.jpg b/app/models/DEEP_STEGO/test/images/228076.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f91dbda7fd704da3834b3f0f35546ac2675becd3 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/228076.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52167a4f51cba42066f248d77df8de203e29c474240cf806cb92b83d33e98b38 +size 18100 diff --git a/app/models/DEEP_STEGO/test/images/23084.jpg b/app/models/DEEP_STEGO/test/images/23084.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b02f06f009b10e39817ece6aaed0fab6cf7f04c9 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/23084.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c69710bb9d04c7c543808fc19932024a32eab36ffae15817003852e7fa6501cf +size 22690 diff --git a/app/models/DEEP_STEGO/test/images/232076.jpg b/app/models/DEEP_STEGO/test/images/232076.jpg new file mode 100644 index 0000000000000000000000000000000000000000..06b657364bff6d37fd30f1e1335fc667818d32ba --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/232076.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4508cea02b5e6702261fd646d499a97dd368c3b00174f7f389f459f154b3b0af +size 20534 diff --git a/app/models/DEEP_STEGO/test/images/238011.jpg b/app/models/DEEP_STEGO/test/images/238011.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f9c219dbae831e0fd796ff2468e7240209be163c --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/238011.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d527ec87c7fc612cbc9bb8c58d11c4272885e86efffedbf2abbca6959390e8c +size 9964 diff --git a/app/models/DEEP_STEGO/test/images/246009.jpg b/app/models/DEEP_STEGO/test/images/246009.jpg new file mode 100644 index 0000000000000000000000000000000000000000..87c7fc4bc104c5d4419142e28ebe05bd329939fe --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/246009.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5bbdb8e4164d1bc1e2b068908bf267988ac0b5f66e95d8d5303c90902fa12378 +size 19130 diff --git a/app/models/DEEP_STEGO/test/images/247003.jpg b/app/models/DEEP_STEGO/test/images/247003.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5361ed5ed94818b10ffab0b08781d5aca24bd465 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/247003.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d31588a12434ef304c614e9baa409013cd4b8c90ed965c6c46ef5205cb7f3bd +size 20704 diff --git a/app/models/DEEP_STEGO/test/images/247085.jpg b/app/models/DEEP_STEGO/test/images/247085.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4134bb2d5d2b965ac542171da0aa02e32ca3c728 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/247085.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6bde693c88223bc0defd802c4ea70ac10d9f68b398f5acc2baac1b0e9ec4ae2 +size 19510 diff --git a/app/models/DEEP_STEGO/test/images/253092.jpg b/app/models/DEEP_STEGO/test/images/253092.jpg new file mode 100644 index 0000000000000000000000000000000000000000..76fd731d7d03bebc7e84fea9d4b93f2bea34aa7c --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/253092.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca172ebf54892df7545d296cacfe63086a4d52623efe27e480bcef73e396f558 +size 20608 diff --git a/app/models/DEEP_STEGO/test/images/26031.jpg b/app/models/DEEP_STEGO/test/images/26031.jpg new file mode 100644 index 0000000000000000000000000000000000000000..91c4fa93f818ceba4c5aa44e045c5ac9c88f0ed9 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/26031.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1713f34bbdcbeccda58c7f513f221318e8d6207fa4f453b83e45ead15835ecfb +size 27357 diff --git a/app/models/DEEP_STEGO/test/images/285022.jpg b/app/models/DEEP_STEGO/test/images/285022.jpg new file mode 100644 index 0000000000000000000000000000000000000000..78c7fe0c4c25594fc4f339162d4eb47aa9343df8 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/285022.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf1b87943b851b6ed1b67ce53ce24ecb6b6b1d45481772384a5f058a0391abdb +size 14463 diff --git a/app/models/DEEP_STEGO/test/images/29030.jpg b/app/models/DEEP_STEGO/test/images/29030.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3b751092a080819a183af512e64d5d99d0f3351d --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/29030.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30c15a3a79d2498997071fe49167a925c4bbbfe0625f644e8cca48ac5485178d +size 18977 diff --git a/app/models/DEEP_STEGO/test/images/291000.jpg b/app/models/DEEP_STEGO/test/images/291000.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c88449f1815d7d0a7db7f50e4fe9cfeb78e3291d --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/291000.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b548d96c30616181bdb959d7df762877f40b63d929ec0c26eb370f9451408aef +size 32623 diff --git a/app/models/DEEP_STEGO/test/images/296059.jpg b/app/models/DEEP_STEGO/test/images/296059.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a670991bd1a7812e4a48dbf0771b8894ff2c151c --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/296059.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a40d22b340bfc7b64f3bbbd63d2eeb9f835fb22d58db220c851046ec1a8d1a84 +size 17251 diff --git a/app/models/DEEP_STEGO/test/images/299086.jpg b/app/models/DEEP_STEGO/test/images/299086.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bf7db0439280b540512a7ea541b880970b9a8806 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/299086.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:659e89c93a6c7cead896b4244c1b3f8c7c0ae3eaf952835b12ee4bd4408fe917 +size 16207 diff --git a/app/models/DEEP_STEGO/test/images/299091.jpg b/app/models/DEEP_STEGO/test/images/299091.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8a45077ceb9d4300bc2aaf6214ec20a01a7d3681 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/299091.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5b3572b560f983c7f247cbd99e48f51bffb215bf47fd50cc1196b7db05804bc +size 13022 diff --git a/app/models/DEEP_STEGO/test/images/304034.jpg b/app/models/DEEP_STEGO/test/images/304034.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3f9b1c2f096bdc5accc20ef308edb47bd55d44e1 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/304034.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e896cf1171b65e0799f1a311d674142e7dbd7c6cdf4251850c73d82c627a92e4 +size 27893 diff --git a/app/models/DEEP_STEGO/test/images/304074.jpg b/app/models/DEEP_STEGO/test/images/304074.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d4ac3928942abdda8e01f48aae4cc4bce6ed6d8c --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/304074.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4fa0a17e39b4d8da31f420ea90832c73948ac53ffecf2d59e8414a46058087b +size 24825 diff --git a/app/models/DEEP_STEGO/test/images/3063.jpg b/app/models/DEEP_STEGO/test/images/3063.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ac3a7afe2b634156266769abd6854c267a87f628 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/3063.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5402215fb0e0b9aa99d1a42628f63721e25a453eeeeb1bb79a2ba784c0d90848 +size 16272 diff --git a/app/models/DEEP_STEGO/test/images/309004.jpg b/app/models/DEEP_STEGO/test/images/309004.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e9db3fa1a208a8faa52e79a89596362c88d96e05 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/309004.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc5311ee2f57eb27b4a8eb2adc74cb54ae43342533b59ef4826dc6bd4160bd72 +size 29322 diff --git a/app/models/DEEP_STEGO/test/images/3096.jpg b/app/models/DEEP_STEGO/test/images/3096.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1ebef40420f14164f0e22cbf208980a44e36efd3 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/3096.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:969b7108260ba65bba7c65be5e535278628426f6d31a2ec4205f7b76f2e25cf6 +size 8726 diff --git a/app/models/DEEP_STEGO/test/images/310007.jpg b/app/models/DEEP_STEGO/test/images/310007.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a002971a0f3c18e287f7b160300676ffe5c53f00 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/310007.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8ec7fd07ac865b7aca06e054c2cbe6d1282ff57498569d2972e1f1374e7c7e7 +size 18136 diff --git a/app/models/DEEP_STEGO/test/images/323016.jpg b/app/models/DEEP_STEGO/test/images/323016.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4cc400f3c22ea07efe77309d0492491bc4664b4c --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/323016.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b6db66edd3ca7196aa35aaa816c924ad01d9cc9f513532a828534310c37bc63 +size 21063 diff --git a/app/models/DEEP_STEGO/test/images/35010.jpg b/app/models/DEEP_STEGO/test/images/35010.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9ddc4c4939b56af23b48945495f12b21a898df40 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/35010.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbfdee398dabd884d28fb95ee7fc31d9f65d994555727a9637e7f29ae74f52bd +size 26341 diff --git a/app/models/DEEP_STEGO/test/images/35058.jpg b/app/models/DEEP_STEGO/test/images/35058.jpg new file mode 100644 index 0000000000000000000000000000000000000000..60287e900da676bf8e1c305edb48a8a8f7aed6f9 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/35058.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:293235234cd5d1ba7df1cb35879d2f2d1095277ef0824218803f7d95ca340b84 +size 14216 diff --git a/app/models/DEEP_STEGO/test/images/35070.jpg b/app/models/DEEP_STEGO/test/images/35070.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1546fb27ebed3b7834d63e71df569b38d719e71e --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/35070.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0707df8095fe316ce754bbb52c37f10605bf0e24e3742f3a14ba04672f301f5b +size 15529 diff --git a/app/models/DEEP_STEGO/test/images/353013.jpg b/app/models/DEEP_STEGO/test/images/353013.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1bacc677c0e2fe06bd4a14ade580edfe3dd6c07f --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/353013.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2240bfe3fb413610a5b0d08b08a315bc1b743bcd5cb5e67ebe8dc2b64a33e29a +size 22290 diff --git a/app/models/DEEP_STEGO/test/images/368037.jpg b/app/models/DEEP_STEGO/test/images/368037.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f2ea32d23065772c8d52ae7b3577715615d07f58 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/368037.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2859a1aee0577e84ba42d855a6ed0d26d66a8237bf08eedf68803b11c813091 +size 21493 diff --git a/app/models/DEEP_STEGO/test/images/41006.jpg b/app/models/DEEP_STEGO/test/images/41006.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b01103acced548ed1a3c66d38b2350b889eb5055 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/41006.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:376b2d59b409d176838f27924a2e85627690d98787e312a0031545c84a3422e0 +size 17203 diff --git a/app/models/DEEP_STEGO/test/images/41025.jpg b/app/models/DEEP_STEGO/test/images/41025.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9cb64db28201f9e0ea26f17783590890a64395d2 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/41025.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0bea338e60708016a7970a8a3b7e25088c357e03f7b70a6b58cdbc2343b4e77 +size 24527 diff --git a/app/models/DEEP_STEGO/test/images/41029.jpg b/app/models/DEEP_STEGO/test/images/41029.jpg new file mode 100644 index 0000000000000000000000000000000000000000..873bf91703816cb5b7d117341178caa503223f0f --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/41029.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd70a35db9fb0788cf1e78333ad7a45e2e19e7014e6d6c737f4541b63d31e4e4 +size 18455 diff --git a/app/models/DEEP_STEGO/test/images/41033.jpg b/app/models/DEEP_STEGO/test/images/41033.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e07f85ca3b0e12da7c01defcafaa0a94b7fd9997 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/41033.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:924f77f60ca01ab03f9aa54870f3c4e34f18507ff382911990b0cf7c9b7a5586 +size 18096 diff --git a/app/models/DEEP_STEGO/test/images/41069.jpg b/app/models/DEEP_STEGO/test/images/41069.jpg new file mode 100644 index 0000000000000000000000000000000000000000..41912965d9361972571d041074d7217a6b5b046e --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/41069.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d647d7216c300f3d2765589021492ad239536ecf65360771b33691d6bb785ca +size 25829 diff --git a/app/models/DEEP_STEGO/test/images/41085.jpg b/app/models/DEEP_STEGO/test/images/41085.jpg new file mode 100644 index 0000000000000000000000000000000000000000..24d05e9d6ef1cea4bd64406101d49dae5f5abc51 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/41085.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cea0b1df1f8358cdf81f18b062c8478abe7dfec336215b0e4fefb8ffb162b70b +size 22065 diff --git a/app/models/DEEP_STEGO/test/images/41096.jpg b/app/models/DEEP_STEGO/test/images/41096.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a2452b061385fec4e8edc98513675174dd4fdbc7 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/41096.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56f62932acc40ebd3237a812aaa898d56b97fa5eafb786d7747b9e6679a1cb01 +size 20869 diff --git a/app/models/DEEP_STEGO/test/images/42044.jpg b/app/models/DEEP_STEGO/test/images/42044.jpg new file mode 100644 index 0000000000000000000000000000000000000000..96d778ea0d4445eec9f8dd3dd84801eac2f6665d --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/42044.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6e7ad407f7a35f5ab5be40d662df80667ed6b96ccb87c85abae1109189111a7 +size 13834 diff --git a/app/models/DEEP_STEGO/test/images/42049.jpg b/app/models/DEEP_STEGO/test/images/42049.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d5b37fde192549b3efcae262c173898bf5d7a9b3 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/42049.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b7ea149bd46158785db5c22345590e5534a6e67f2e196b2fa00eea303493392 +size 13257 diff --git a/app/models/DEEP_STEGO/test/images/42078.jpg b/app/models/DEEP_STEGO/test/images/42078.jpg new file mode 100644 index 0000000000000000000000000000000000000000..44b72b6ff06390ca393746a4de568af5efcde9b5 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/42078.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:186fe7dd7518841e68751e18cbaa7a45b9a136aee4488e1dd2812dcf4205be99 +size 12637 diff --git a/app/models/DEEP_STEGO/test/images/43033.jpg b/app/models/DEEP_STEGO/test/images/43033.jpg new file mode 100644 index 0000000000000000000000000000000000000000..44cb2423574037239730dc1c22826e71f4d47066 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/43033.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5e5d64881405fa3605beeaddea3d8d51f4948732e34ca2301d6324d7fe4f452 +size 18882 diff --git a/app/models/DEEP_STEGO/test/images/43051.jpg b/app/models/DEEP_STEGO/test/images/43051.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c533170ebcabbf82d8f671f7a75639dc17c40e52 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/43051.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7e51fe3bc65d16951430d289455a40faaf6db0e8acf4e03a14f3f3e1008865a +size 12195 diff --git a/app/models/DEEP_STEGO/test/images/43074.jpg b/app/models/DEEP_STEGO/test/images/43074.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5dd88a936380acad3dab1e0cce967c898f8f6dab --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/43074.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb671ee664db276fca118cbdd1a7eec8b9294c74a3ca284d41c1132a2d9a37bd +size 16261 diff --git a/app/models/DEEP_STEGO/test/images/46076.jpg b/app/models/DEEP_STEGO/test/images/46076.jpg new file mode 100644 index 0000000000000000000000000000000000000000..757a35beca12cea8c3d04f129e54091567017f57 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/46076.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e877b9c3120e3a0e0b7f046a6f756e532e5a7a3adfd6eb3e6001370b1a95a9e4 +size 15679 diff --git a/app/models/DEEP_STEGO/test/images/48017.jpg b/app/models/DEEP_STEGO/test/images/48017.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6274d6c13686a4d328b97251c92ce32d1f8d0b81 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/48017.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f902bba86ca22d1638a8d644f8307c12eaa80aa13b36833ad4110a2245103bb +size 25850 diff --git a/app/models/DEEP_STEGO/test/images/51084.jpg b/app/models/DEEP_STEGO/test/images/51084.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6f1c0d8c67847dd21db685c773f02c6a4613b470 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/51084.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03642cd8a94b9bb42acecec87c765c9dbc825bf9c53e021e4c013fed992961ed +size 23210 diff --git a/app/models/DEEP_STEGO/test/images/6046.jpg b/app/models/DEEP_STEGO/test/images/6046.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cabb69b6ee75a68ef9ac63a340e3f48ff02bf0cc --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/6046.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:128d2ff4dabe9a70dab197558b7963bb894ad838913acf32484c0ad9a9dc7c2b +size 22917 diff --git a/app/models/DEEP_STEGO/test/images/61060.jpg b/app/models/DEEP_STEGO/test/images/61060.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b6db51efc296cf12fda8449400406f4a011549f4 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/61060.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a8b1f8b4712c662f8de2308218053627a111e658e2b5e897b39d21ae38c72c4 +size 22193 diff --git a/app/models/DEEP_STEGO/test/images/64061.jpg b/app/models/DEEP_STEGO/test/images/64061.jpg new file mode 100644 index 0000000000000000000000000000000000000000..57e209a2bba117552ddbb761ccdf26ebef3ffbbf --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/64061.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fa1c7c0ba7353cf7b10a0bb30be2df4ab6b1255824c3345a2aaa8644d2c4a74 +size 15721 diff --git a/app/models/DEEP_STEGO/test/images/69020.jpg b/app/models/DEEP_STEGO/test/images/69020.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ac03e4f6134f77b855836b902feb8d4a809fd973 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/69020.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c170ef79ce061bb697ef29ecb97688c9c2e34fbbb9735210fbd9e2ee32b16d95 +size 24054 diff --git a/app/models/DEEP_STEGO/test/images/69022.jpg b/app/models/DEEP_STEGO/test/images/69022.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a16e6480bb450dd0bf126f5dedb7eba7d4cf34e1 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/69022.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d0dc8df4e30b7d89a729f8695e70e87d544292768b428464233573176b65e34 +size 19877 diff --git a/app/models/DEEP_STEGO/test/images/69040.jpg b/app/models/DEEP_STEGO/test/images/69040.jpg new file mode 100644 index 0000000000000000000000000000000000000000..875d38a07841ea08eeade3a607b6adc336f380ad --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/69040.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b310348572313b800d644b21af9f66fffc85416a0971644e31fae641ba9dd591 +size 24479 diff --git a/app/models/DEEP_STEGO/test/images/70011.jpg b/app/models/DEEP_STEGO/test/images/70011.jpg new file mode 100644 index 0000000000000000000000000000000000000000..033ed9e2843ffd0e501090554ae189cd2de1b7f1 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/70011.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ab420c7881a667737ede23cd48d1b83e8c12afe6d03782fd3b51b13226a87b5 +size 15984 diff --git a/app/models/DEEP_STEGO/test/images/80090.jpg b/app/models/DEEP_STEGO/test/images/80090.jpg new file mode 100644 index 0000000000000000000000000000000000000000..17b487c0662aaa8a5ec21ee929eb51ded588d784 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/80090.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:283f7abdc2cb37ef23b562ce28920819da9f7e88da4df23b28423eab424f3e34 +size 20154 diff --git a/app/models/DEEP_STEGO/test/images/80099.jpg b/app/models/DEEP_STEGO/test/images/80099.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7ad4e492c4b6e5425bc5467f5efa374d6f41fdd3 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/80099.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5402acdc28811bfac2e870d797fb782251cd65972357b5ecada3cea188e0bf2e +size 12822 diff --git a/app/models/DEEP_STEGO/test/images/8068.jpg b/app/models/DEEP_STEGO/test/images/8068.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f633138db41f76d7d79d918c0cdc59a530591d1d --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/8068.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ec93a5fb268ee48d82fb88e9d4c5384d25e228b57475b55cefd83581580a243 +size 16497 diff --git a/app/models/DEEP_STEGO/test/images/81095.jpg b/app/models/DEEP_STEGO/test/images/81095.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b1437932edb45da45b285cb0ad5deb695dca3630 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/81095.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7424b3ea8a951100b627b5ffd7505e92bbaddef6c37de2f80a75b7dc57e82898 +size 19486 diff --git a/app/models/DEEP_STEGO/test/images/87015.jpg b/app/models/DEEP_STEGO/test/images/87015.jpg new file mode 100644 index 0000000000000000000000000000000000000000..34c06e75aeb65d1ff070799b40ef40606e9403a1 --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/87015.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80685f01f556abc8a0847a464d188782b137116a1994a38cf72262fc60d2adf8 +size 25353 diff --git a/app/models/DEEP_STEGO/test/images/87046.jpg b/app/models/DEEP_STEGO/test/images/87046.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0330c6cc849c70bd2465ecbddcd443db809adbaa --- /dev/null +++ b/app/models/DEEP_STEGO/test/images/87046.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d05629f33b793a5fa1a36fb93e6d8db577796e7d6c9c410e13fbfa1643f3cbf +size 23169 diff --git a/app/models/DEEP_STEGO/test/secret.png b/app/models/DEEP_STEGO/test/secret.png new file mode 100644 index 0000000000000000000000000000000000000000..fac46612cdc73ae1450c0787a52a2373f783a1ab --- /dev/null +++ b/app/models/DEEP_STEGO/test/secret.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f667d60c44a17ba924cc9d3e8858d84546f392b516be5fafb752be2ba16daf4 +size 65116 diff --git a/app/models/DEEP_STEGO/test/testdata.npy b/app/models/DEEP_STEGO/test/testdata.npy new file mode 100644 index 0000000000000000000000000000000000000000..2e3d33639903450b076ace39c55000af4e91282d --- /dev/null +++ b/app/models/DEEP_STEGO/test/testdata.npy @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b90cea3233dca3cb326af3d24b21d5a8328182a36f068a9c9a32dcc72bc7737 +size 60211296 diff --git a/app/models/DEEP_STEGO/train.py b/app/models/DEEP_STEGO/train.py new file mode 100644 index 0000000000000000000000000000000000000000..4b182be4bdb5e3184eac13d3f5f917963a0f6b4b --- /dev/null +++ b/app/models/DEEP_STEGO/train.py @@ -0,0 +1,284 @@ +import os +import glob +import numpy as np +import tensorflow as tf +from tensorflow.keras.models import Model +from tensorflow.keras.layers import Dense, Input, concatenate, Conv2D, GaussianNoise +from tensorflow.keras.preprocessing.image import ImageDataGenerator +from tensorflow.keras.optimizers import Adam +import tensorflow.keras.backend as K +from tensorflow.keras.utils import plot_model +from tensorflow.keras.callbacks import TensorBoard, ModelCheckpoint, Callback, ReduceLROnPlateau +from tensorflow.keras.models import load_model +from tensorflow.keras.losses import mean_squared_error +# from tensorflow.keras.utils import multi_gpu_model +from PIL import Image +import matplotlib.pyplot as plt +from random import randint +import imageio +from io import StringIO, BytesIO +from app.models.DEEP_STEGO.Utils.preprocessing import normalize_batch, denormalize_batch +from app.models.DEEP_STEGO.Utils.customLossWeight import custom_loss_1, custom_loss_2 + +tf.compat.v1.disable_v2_behavior() + +# %matplotlib inline + +# Configure file paths +TRAIN = "dataset/train_data" +VALIDATION = "dataset/val_data" +TRAIN_NUM = len(glob.glob(TRAIN + "/*/*")) +VAL_NUM = len(glob.glob(VALIDATION + "/*/*")) +TEST_DATA = "test/testdata.npy" + +CHECKPOINT = "checkpoints/steg_model-{epoch:02d}-{val_loss:.2f}.hdf5" +PRETRAINED = 'checkpoints/steg_model-04-0.03.hdf5' + +# Configure batch size +BATCH_SIZE = 12 + +# Load test data as numpy arrays +test_images = np.load(TEST_DATA) + +# Sample test data +test_secret = test_images[0].reshape((1, 224, 224, 3)) +test_cover = test_images[1].reshape((1, 224, 224, 3)) + + +# Image data generator +input_image_gen = ImageDataGenerator(rescale=1. / 255) +test_image_gen = ImageDataGenerator(rescale=1. / 255) + + +# Custom generator for loading training images from directory +def generate_generator_multiple(generator, direct): + gen_X1 = generator.flow_from_directory(direct, target_size=(224, 224), batch_size=BATCH_SIZE, shuffle=True, seed=3, class_mode=None) + gen_X2 = generator.flow_from_directory(direct, target_size=(224, 224), batch_size=BATCH_SIZE, shuffle=True, seed=8, class_mode=None) + + while True: + X1i = normalize_batch(gen_X1.next()) + X2i = normalize_batch(gen_X2.next()) + + yield ({'secret': X1i, 'cover': X2i}, + {'hide_conv_f': X2i, 'revl_conv_f': X1i}) # Yield both images and their mutual label + + +# Train data generator +input_generator = generate_generator_multiple(generator=input_image_gen, direc=TRAIN) + +# Validation data generator +test_generator = generate_generator_multiple(test_image_gen, direc=VALIDATION) + + +# Custom loss dictionary +losses = { + "hide_conv_f": custom_loss_2, + "revl_conv_f": custom_loss_1, +} + +# Loss weights +lossWeights = {"hide_conv_f": 1.0, "revl_conv_f": 0.75} + + +# Model architecture +def steg_model(pretrain=False): + if pretrain: + pretrained_model = load_model(PRETRAINED, custom_objects={'custom_loss_1': custom_loss_1, 'custom_loss_2': custom_loss_2}) + return pretrained_model + + # Inputs + secret = Input(shape=(224, 224, 3), name='secret') + cover = Input(shape=(224, 224, 3), name='cover') + + # Prepare network - patches [3*3,4*4,5*5] + prepare_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='prep_conv3x3_1')(secret) + prepare_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='prep_conv3x3_2')(prepare_conv_3x3) + prepare_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='prep_conv3x3_3')(prepare_conv_3x3) + prepare_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='prep_conv3x3_4')(prepare_conv_3x3) + + prepare_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='prep_conv4x4_1')(secret) + prepare_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='prep_conv4x4_2')(prepare_conv_4x4) + prepare_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='prep_conv4x4_3')(prepare_conv_4x4) + prepare_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='prep_conv4x4_4')(prepare_conv_4x4) + + prepare_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='prep_conv5x5_1')(secret) + prepare_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='prep_conv5x5_2')(prepare_conv_5x5) + prepare_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='prep_conv5x5_3')(prepare_conv_5x5) + prepare_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='prep_conv5x5_4')(prepare_conv_5x5) + + prepare_concat_1 = concatenate([prepare_conv_3x3, prepare_conv_4x4, prepare_conv_5x5], axis=3, name="prep_concat_1") + + prepare_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='prep_conv5x5_f')(prepare_concat_1) + prepare_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='prep_conv4x4_f')(prepare_concat_1) + prepare_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='prep_conv3x3_f')(prepare_concat_1) + + prepare_prepare_concat_f1 = concatenate([prepare_conv_5x5, prepare_conv_4x4, prepare_conv_3x3], axis=3, name="prep_concat_2") + + # Hiding network - patches [3*3,4*4,5*5] + hide_concat_h = concatenate([cover, prepare_prepare_concat_f1], axis=3, name="hide_concat_1") + + hide_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='hide_conv3x3_1')(hide_concat_h) + hide_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='hide_conv3x3_2')(hide_conv_3x3) + hide_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='hide_conv3x3_3')(hide_conv_3x3) + hide_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='hide_conv3x3_4')(hide_conv_3x3) + + hide_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='hide_conv4x4_1')(hide_concat_h) + hide_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='hide_conv4x4_2')(hide_conv_4x4) + hide_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='hide_conv4x4_3')(hide_conv_4x4) + hide_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='hide_conv4x4_4')(hide_conv_4x4) + + hide_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='hide_conv5x5_1')(hide_concat_h) + hide_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='hide_conv5x5_2')(hide_conv_5x5) + hide_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='hide_conv5x5_3')(hide_conv_5x5) + hide_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='hide_conv5x5_4')(hide_conv_5x5) + + hide_concat_1 = concatenate([hide_conv_3x3, hide_conv_4x4, hide_conv_5x5], axis=3, name="hide_concat_2") + + hide_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='hide_conv5x5_f')(hide_concat_1) + hide_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='hide_conv4x4_f')(hide_concat_1) + hide_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='hide_conv3x3_f')(hide_concat_1) + + hide_concat_f1 = concatenate([hide_conv_5x5, hide_conv_4x4, hide_conv_3x3], axis=3, name="hide_concat_3") + + cover_predict = Conv2D(3, kernel_size=1, padding="same", name='hide_conv_f')(hide_concat_f1) + + # Noise layer + noise_ip = GaussianNoise(0.1)(cover_predict) + + # Reveal network - patches [3*3,4*4,5*5] + reveal_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='revl_conv3x3_1')(noise_ip) + reveal_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='revl_conv3x3_2')(reveal_conv_3x3) + reveal_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='revl_conv3x3_3')(reveal_conv_3x3) + reveal_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='revl_conv3x3_4')(reveal_conv_3x3) + + reveal_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='revl_conv4x4_1')(noise_ip) + reveal_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='revl_conv4x4_2')(reveal_conv_4x4) + reveal_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='revl_conv4x4_3')(reveal_conv_4x4) + reveal_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='revl_conv4x4_4')(reveal_conv_4x4) + + reveal_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='revl_conv5x5_1')(noise_ip) + reveal_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='revl_conv5x5_2')(reveal_conv_5x5) + reveal_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='revl_conv5x5_3')(reveal_conv_5x5) + reveal_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='revl_conv5x5_4')(reveal_conv_5x5) + + reveal_concat_1 = concatenate([reveal_conv_3x3, reveal_conv_4x4, reveal_conv_5x5], axis=3, name="revl_concat_1") + + reveal_conv_5x5 = Conv2D(50, kernel_size=5, padding="same", activation='relu', name='revl_conv5x5_f')(reveal_concat_1) + reveal_conv_4x4 = Conv2D(50, kernel_size=4, padding="same", activation='relu', name='revl_conv4x4_f')(reveal_concat_1) + reveal_conv_3x3 = Conv2D(50, kernel_size=3, padding="same", activation='relu', name='revl_conv3x3_f')(reveal_concat_1) + + reveal_concat_f1 = concatenate([reveal_conv_5x5, reveal_conv_4x4, reveal_conv_3x3], axis=3, name="revl_concat_2") + + secret_predict = Conv2D(3, kernel_size=1, padding="same", name='revl_conv_f')(reveal_concat_f1) + + model = Model(inputs=[secret, cover], outputs=[cover_predict, secret_predict]) + + # Multi GPU training (Uncomment the following line) + # model = multi_gpu_model(model, gpus=2) + + # Compile model + model.compile(optimizer='adam', loss=losses, loss_weights=lossWeights) + + return model + + +# Model object +model = steg_model(pretrain=False) + +# Summarize layers +print(model.summary()) + +# Plot graph +# plot_model(model, to_file='steg_model.png') + +# Tensorboard +tensorboard = TensorBoard(log_dir='./logs', histogram_freq=0, + write_graph=True, write_images=True) + +# TF file writer for images +im_writer = tf.summary.FileWriter('./logs/im') + + +# TF image logger +def log_images(tag, images, step): + """Logs a list of images.""" + + im_summaries = [] + for nr, img in enumerate(images): + # Write the image to a string + s = BytesIO() + plt.imsave(s, img, format='png') + + # Create an Image object + img_sum = tf.Summary.Image(encoded_image_string=s.getvalue(), + height=img.shape[0], + width=img.shape[1]) + # Create a Summary value + im_summaries.append(tf.Summary.Value(tag='%s/%d' % (tag, nr), + image=img_sum)) + + # Create and write Summary + summary = tf.Summary(value=im_summaries) + im_writer.add_summary(summary, step) + + +# Custom keras image callback +class TensorBoardImage(Callback): + def __init__(self, tag): + super().__init__() + self.tag = tag + + def on_epoch_end(self, epoch, logs={}): + # Load random test images + secret_in = test_images[np.random.choice(len(test_images), size=4, replace=False)] + cover_in = test_images[np.random.choice(len(test_images), size=4, replace=False)] + + # Predict on batch + cover_out, secret_out = model.predict([normalize_batch(secret_in), normalize_batch(cover_in)]) + + # Post process output cover image + cover_out = denormalize_batch(cover_out) + cover_out = np.squeeze(cover_out) * 255.0 + cover_out = np.uint8(cover_out) + + # Post process output secret image + secret_out = denormalize_batch(secret_out) + secret_out = np.squeeze(secret_out) * 255.0 + secret_out = np.uint8(secret_out) + + # Convert images to UINT8 format (0-255) + cover_in = np.uint8(np.squeeze(cover_in * 255.0)) + secret_in = np.uint8(np.squeeze(secret_in * 255.0)) + + # Log image summary + log_images("cover_in", cover_in, epoch) + log_images("secret_in", secret_in, epoch) + log_images("cover_out", cover_out, epoch) + log_images("secret_out", secret_out, epoch) + + return + + +# Custom image logger +image_summary = TensorBoardImage('Image Example') + +# Checkpoint path +filepath = CHECKPOINT + +# Callback functions +checkpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_weights_only=False, save_best_only=True, + mode='min') +reduce_lr = ReduceLROnPlateau(factor=0.5, patience=3, min_lr=0.000001, verbose=1) +callbacks_list = [checkpoint, tensorboard, image_summary, reduce_lr] + +# Train the model +model.fit_generator(input_generator, epochs=100, + steps_per_epoch=TRAIN_NUM // BATCH_SIZE, + validation_data=test_generator, + validation_steps=VAL_NUM // BATCH_SIZE, + use_multiprocessing=True, + callbacks=callbacks_list) + +''' +Sample run: python train.py +''' diff --git a/app/models/ESRGAN/LR/baboon.png b/app/models/ESRGAN/LR/baboon.png new file mode 100644 index 0000000000000000000000000000000000000000..d2d9369cc3b7c7128cd0f98185505adb370ab331 --- /dev/null +++ b/app/models/ESRGAN/LR/baboon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6befc47b72361c1299a24ce79843c929ed692c70c8aaae7d0409ea6afce09a2 +size 33918 diff --git a/app/models/ESRGAN/LR/comic.png b/app/models/ESRGAN/LR/comic.png new file mode 100644 index 0000000000000000000000000000000000000000..3f32e6f223c8c9a0177bb13d17f96abb87eac25e --- /dev/null +++ b/app/models/ESRGAN/LR/comic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ba58778eae8d74032fba76c1ff16f86574920162817c7cba6ff6e50a471a456 +size 14141 diff --git a/app/models/ESRGAN/RRDBNet_arch.py b/app/models/ESRGAN/RRDBNet_arch.py new file mode 100644 index 0000000000000000000000000000000000000000..1631edd0e7451fdc60b460c62f13c008d6aa2541 --- /dev/null +++ b/app/models/ESRGAN/RRDBNet_arch.py @@ -0,0 +1,78 @@ +import functools +import torch +import torch.nn as nn +import torch.nn.functional as F + + +def make_layer(block, n_layers): + layers = [] + for _ in range(n_layers): + layers.append(block()) + return nn.Sequential(*layers) + + +class ResidualDenseBlock_5C(nn.Module): + def __init__(self, nf=64, gc=32, bias=True): + super(ResidualDenseBlock_5C, self).__init__() + # gc: growth channel, i.e. intermediate channels + self.conv1 = nn.Conv2d(nf, gc, 3, 1, 1, bias=bias) + self.conv2 = nn.Conv2d(nf + gc, gc, 3, 1, 1, bias=bias) + self.conv3 = nn.Conv2d(nf + 2 * gc, gc, 3, 1, 1, bias=bias) + self.conv4 = nn.Conv2d(nf + 3 * gc, gc, 3, 1, 1, bias=bias) + self.conv5 = nn.Conv2d(nf + 4 * gc, nf, 3, 1, 1, bias=bias) + self.lrelu = nn.LeakyReLU(negative_slope=0.2, inplace=True) + + # initialization + # mutil.initialize_weights([self.conv1, self.conv2, self.conv3, self.conv4, self.conv5], 0.1) + + def forward(self, x): + x1 = self.lrelu(self.conv1(x)) + x2 = self.lrelu(self.conv2(torch.cat((x, x1), 1))) + x3 = self.lrelu(self.conv3(torch.cat((x, x1, x2), 1))) + x4 = self.lrelu(self.conv4(torch.cat((x, x1, x2, x3), 1))) + x5 = self.conv5(torch.cat((x, x1, x2, x3, x4), 1)) + return x5 * 0.2 + x + + +class RRDB(nn.Module): + """Residual in Residual Dense Block""" + + def __init__(self, nf, gc=32): + super(RRDB, self).__init__() + self.RDB1 = ResidualDenseBlock_5C(nf, gc) + self.RDB2 = ResidualDenseBlock_5C(nf, gc) + self.RDB3 = ResidualDenseBlock_5C(nf, gc) + + def forward(self, x): + out = self.RDB1(x) + out = self.RDB2(out) + out = self.RDB3(out) + return out * 0.2 + x + + +class RRDBNet(nn.Module): + def __init__(self, in_nc, out_nc, nf, nb, gc=32): + super(RRDBNet, self).__init__() + RRDB_block_f = functools.partial(RRDB, nf=nf, gc=gc) + + self.conv_first = nn.Conv2d(in_nc, nf, 3, 1, 1, bias=True) + self.RRDB_trunk = make_layer(RRDB_block_f, nb) + self.trunk_conv = nn.Conv2d(nf, nf, 3, 1, 1, bias=True) + #### upsampling + self.upconv1 = nn.Conv2d(nf, nf, 3, 1, 1, bias=True) + self.upconv2 = nn.Conv2d(nf, nf, 3, 1, 1, bias=True) + self.HRconv = nn.Conv2d(nf, nf, 3, 1, 1, bias=True) + self.conv_last = nn.Conv2d(nf, out_nc, 3, 1, 1, bias=True) + + self.lrelu = nn.LeakyReLU(negative_slope=0.2, inplace=True) + + def forward(self, x): + fea = self.conv_first(x) + trunk = self.trunk_conv(self.RRDB_trunk(fea)) + fea = fea + trunk + + fea = self.lrelu(self.upconv1(F.interpolate(fea, scale_factor=2, mode='nearest'))) + fea = self.lrelu(self.upconv2(F.interpolate(fea, scale_factor=2, mode='nearest'))) + out = self.conv_last(self.lrelu(self.HRconv(fea))) + + return out \ No newline at end of file diff --git a/app/models/ESRGAN/model.py b/app/models/ESRGAN/model.py new file mode 100644 index 0000000000000000000000000000000000000000..0d6a0c47783ea7be7516a1dcc832208dce5c0906 --- /dev/null +++ b/app/models/ESRGAN/model.py @@ -0,0 +1,154 @@ +import torch +from torch import nn + + +class ConvBlock(nn.Module): + def __init__(self, in_channels, out_channels, use_act, **kwargs): + super().__init__() + self.cnn = nn.Conv2d( + in_channels, + out_channels, + **kwargs, + bias=True, + ) + self.act = nn.LeakyReLU(0.2, inplace=True) if use_act else nn.Identity() + + def forward(self, x): + return self.act(self.cnn(x)) + + +class UpsampleBlock(nn.Module): + def __init__(self, in_c, scale_factor=2): + super().__init__() + self.upsample = nn.Upsample(scale_factor=scale_factor, mode="nearest") + self.conv = nn.Conv2d(in_c, in_c, 3, 1, 1, bias=True) + self.act = nn.LeakyReLU(0.2, inplace=True) + + def forward(self, x): + return self.act(self.conv(self.upsample(x))) + + +class DenseResidualBlock(nn.Module): + def __init__(self, in_channels, channels=32, residual_beta=0.2): + super().__init__() + self.residual_beta = residual_beta + self.blocks = nn.ModuleList() + + for i in range(5): + self.blocks.append( + ConvBlock( + in_channels + channels * i, + channels if i <= 3 else in_channels, + kernel_size=3, + stride=1, + padding=1, + use_act=True if i <= 3 else False, + ) + ) + + def forward(self, x): + new_inputs = x + for block in self.blocks: + out = block(new_inputs) + new_inputs = torch.cat([new_inputs, out], dim=1) + return self.residual_beta * out + x + + +class RRDB(nn.Module): + def __init__(self, in_channels, residual_beta=0.2): + super().__init__() + self.residual_beta = residual_beta + self.rrdb = nn.Sequential(*[DenseResidualBlock(in_channels) for _ in range(3)]) + + def forward(self, x): + return self.rrdb(x) * self.residual_beta + x + + +class Generator(nn.Module): + def __init__(self, in_channels=3, num_channels=64, num_blocks=23): + super().__init__() + self.initial = nn.Conv2d( + in_channels, + num_channels, + kernel_size=3, + stride=1, + padding=1, + bias=True, + ) + self.residuals = nn.Sequential(*[RRDB(num_channels) for _ in range(num_blocks)]) + self.conv = nn.Conv2d(num_channels, num_channels, kernel_size=3, stride=1, padding=1) + self.upsamples = nn.Sequential( + UpsampleBlock(num_channels), UpsampleBlock(num_channels), + ) + self.final = nn.Sequential( + nn.Conv2d(num_channels, num_channels, 3, 1, 1, bias=True), + nn.LeakyReLU(0.2, inplace=True), + nn.Conv2d(num_channels, in_channels, 3, 1, 1, bias=True), + ) + + def forward(self, x): + initial = self.initial(x) + x = self.conv(self.residuals(initial)) + initial + x = self.upsamples(x) + return self.final(x) + + +class Discriminator(nn.Module): + def __init__(self, in_channels=3, features=[64, 64, 128, 128, 256, 256, 512, 512]): + super().__init__() + blocks = [] + for idx, feature in enumerate(features): + blocks.append( + ConvBlock( + in_channels, + feature, + kernel_size=3, + stride=1 + idx % 2, + padding=1, + use_act=True, + ), + ) + in_channels = feature + + self.blocks = nn.Sequential(*blocks) + self.classifier = nn.Sequential( + nn.AdaptiveAvgPool2d((6, 6)), + nn.Flatten(), + nn.Linear(512 * 6 * 6, 1024), + nn.LeakyReLU(0.2, inplace=True), + nn.Linear(1024, 1), + ) + + def forward(self, x): + x = self.blocks(x) + return self.classifier(x) + + +def initialize_weights(model, scale=0.1): + for m in model.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight.data) + m.weight.data *= scale + + elif isinstance(m, nn.Linear): + nn.init.kaiming_normal_(m.weight.data) + m.weight.data *= scale + + +def test(): + gen = Generator() + disc = Discriminator() + low_res = 24 + x = torch.randn((5, 3, low_res, low_res)) + gen_out = gen(x) + disc_out = disc(gen_out) + + print(gen_out.shape) + print(disc_out.shape) + + +test() + + + + diff --git a/app/models/ESRGAN/models/RRDB_ESRGAN_x4.pth b/app/models/ESRGAN/models/RRDB_ESRGAN_x4.pth new file mode 100644 index 0000000000000000000000000000000000000000..101716c6c861c6059e5820332256f3d57d97d117 --- /dev/null +++ b/app/models/ESRGAN/models/RRDB_ESRGAN_x4.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65fece06e1ccb48853242aa972bdf00ad07a7dd8938d2dcbdf4221b59f6372ce +size 66929193 diff --git a/app/models/ESRGAN/net_intrep.py b/app/models/ESRGAN/net_intrep.py new file mode 100644 index 0000000000000000000000000000000000000000..e224868b2684493de4429fa9f95ffbabf1a9185f --- /dev/null +++ b/app/models/ESRGAN/net_intrep.py @@ -0,0 +1,21 @@ +import sys +import torch +from collections import OrderedDict + +alpha = float(sys.argv[1]) + +net_PSNR_path = './models/RRDB_PSNR_x4.pth' +net_ESRGAN_path = 'models/RRDB_ESRGAN_x4.pth' +net_interp_path = './models/interp_{:02d}.pth'.format(int(alpha*10)) + +net_PSNR = torch.load(net_PSNR_path) +net_ESRGAN = torch.load(net_ESRGAN_path) +net_interp = OrderedDict() + +print('Interpolating with alpha = ', alpha) + +for k, v_PSNR in net_PSNR.items(): + v_ESRGAN = net_ESRGAN[k] + net_interp[k] = (1 - alpha) * v_PSNR + alpha * v_ESRGAN + +torch.save(net_interp, net_interp_path) \ No newline at end of file diff --git a/app/models/ESRGAN/results/Places365_test_00000001_rlt.png b/app/models/ESRGAN/results/Places365_test_00000001_rlt.png new file mode 100644 index 0000000000000000000000000000000000000000..7ac59920ca13039e73a92e305caefbc6c131ac5d --- /dev/null +++ b/app/models/ESRGAN/results/Places365_test_00000001_rlt.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c07e2a53e9dc781bf9a5bd402ea5b26c44d8e3e9542c33183bc9e75b0bbb2196 +size 1340371 diff --git a/app/models/ESRGAN/results/baboon_rlt.png b/app/models/ESRGAN/results/baboon_rlt.png new file mode 100644 index 0000000000000000000000000000000000000000..21fcbcfb7b3d5b434684d28f123a3b4dd9e7a3e5 --- /dev/null +++ b/app/models/ESRGAN/results/baboon_rlt.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53d8be9a49312ea03ec41e6cd293f76f32ebbce1e5cf47ed7f2c17c63bc34424 +size 568509 diff --git a/app/models/ESRGAN/results/comic_rlt.png b/app/models/ESRGAN/results/comic_rlt.png new file mode 100644 index 0000000000000000000000000000000000000000..9ce546568517228e1fb8f22028581ca0566d1140 --- /dev/null +++ b/app/models/ESRGAN/results/comic_rlt.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4740906e686e5a263516120b6c309223e4e4b4ba9cae95f0aa6aa8acf267ffe4 +size 214725 diff --git a/app/models/ESRGAN/results/enhanced_video.mp4 b/app/models/ESRGAN/results/enhanced_video.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/app/models/ESRGAN/results/secret_out_rlt.png b/app/models/ESRGAN/results/secret_out_rlt.png new file mode 100644 index 0000000000000000000000000000000000000000..f4ab19b04e3354cd0049e2a59bad2feb7e2a8173 --- /dev/null +++ b/app/models/ESRGAN/results/secret_out_rlt.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2da0f7023bdbebbc6df417d9048dc2035aac4a9a319fb0de933dd40bff6b0ce +size 1333650 diff --git a/app/models/ESRGAN/test.py b/app/models/ESRGAN/test.py new file mode 100644 index 0000000000000000000000000000000000000000..bdd5d30b1ae1c1d75bb098b30c74187ea0383fab --- /dev/null +++ b/app/models/ESRGAN/test.py @@ -0,0 +1,37 @@ +import os.path as osp +import glob +import cv2 +import numpy as np +import torch +import RRDBNet_arch as arch + +model_path = 'models/RRDB_ESRGAN_x4.pth' # models/RRDB_ESRGAN_x4.pth OR models/RRDB_PSNR_x4.pth +device = torch.device('cuda') # if you want to run on CPU, change 'cuda' -> cpu +# device = torch.device('cpu') + +test_img_folder = 'LR/*' + +model = arch.RRDBNet(3, 3, 64, 23, gc=32) +model.load_state_dict(torch.load(model_path), strict=True) +model.eval() +model = model.to(device) + +print('Model path {:s}. \nTesting...'.format(model_path)) + +idx = 0 +for path in glob.glob(test_img_folder): + idx += 1 + base = osp.splitext(osp.basename(path))[0] + print(idx, base) + # read images + img = cv2.imread(path, cv2.IMREAD_COLOR) + img = img * 1.0 / 255 + img = torch.from_numpy(np.transpose(img[:, :, [2, 1, 0]], (2, 0, 1))).float() + img_LR = img.unsqueeze(0) + img_LR = img_LR.to(device) + + with torch.no_grad(): + output = model(img_LR).data.squeeze().float().cpu().clamp_(0, 1).numpy() + output = np.transpose(output[[2, 1, 0], :, :], (1, 2, 0)) + output = (output * 255.0).round() + cv2.imwrite('results/{:s}_rlt.png'.format(base), output) \ No newline at end of file diff --git a/app/models/ESRGAN/transer_RRDB_models.py b/app/models/ESRGAN/transer_RRDB_models.py new file mode 100644 index 0000000000000000000000000000000000000000..d77394507de1519578ae1139d99f9e3e3113c63e --- /dev/null +++ b/app/models/ESRGAN/transer_RRDB_models.py @@ -0,0 +1,55 @@ +import os +import torch +import RRDBNet_arch as arch + +pretrained_net = torch.load('models/RRDB_ESRGAN_x4.pth') +save_path = 'models/RRDB_ESRGAN_x4.pth' + +crt_model = arch.RRDBNet(3, 3, 64, 23, gc=32) +crt_net = crt_model.state_dict() + +load_net_clean = {} +for k, v in pretrained_net.items(): + if k.startswith('module.'): + load_net_clean[k[7:]] = v + else: + load_net_clean[k] = v +pretrained_net = load_net_clean + +print('###################################\n') +tbd = [] +for k, v in crt_net.items(): + tbd.append(k) + +# directly copy +for k, v in crt_net.items(): + if k in pretrained_net and pretrained_net[k].size() == v.size(): + crt_net[k] = pretrained_net[k] + tbd.remove(k) + +crt_net['conv_first.weight'] = pretrained_net['model.0.weight'] +crt_net['conv_first.bias'] = pretrained_net['model.0.bias'] + +for k in tbd.copy(): + if 'RDB' in k: + ori_k = k.replace('RRDB_trunk.', 'model.1.sub.') + if '.weight' in k: + ori_k = ori_k.replace('.weight', '.0.weight') + elif '.bias' in k: + ori_k = ori_k.replace('.bias', '.0.bias') + crt_net[k] = pretrained_net[ori_k] + tbd.remove(k) + +crt_net['trunk_conv.weight'] = pretrained_net['model.1.sub.23.weight'] +crt_net['trunk_conv.bias'] = pretrained_net['model.1.sub.23.bias'] +crt_net['upconv1.weight'] = pretrained_net['model.3.weight'] +crt_net['upconv1.bias'] = pretrained_net['model.3.bias'] +crt_net['upconv2.weight'] = pretrained_net['model.6.weight'] +crt_net['upconv2.bias'] = pretrained_net['model.6.bias'] +crt_net['HRconv.weight'] = pretrained_net['model.8.weight'] +crt_net['HRconv.bias'] = pretrained_net['model.8.bias'] +crt_net['conv_last.weight'] = pretrained_net['model.10.weight'] +crt_net['conv_last.bias'] = pretrained_net['model.10.bias'] + +torch.save(crt_net, save_path) +print('Saving to ', save_path) \ No newline at end of file diff --git a/app/models/ESRGAN/upscale_image.py b/app/models/ESRGAN/upscale_image.py new file mode 100644 index 0000000000000000000000000000000000000000..400dbda775e85eaf629b6138fd82913500d4dcae --- /dev/null +++ b/app/models/ESRGAN/upscale_image.py @@ -0,0 +1,45 @@ +import cv2 +import numpy as np +import torch +import os +import tempfile +from app.models.ESRGAN import RRDBNet_arch as arch + +_MODEL_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'models', 'RRDB_ESRGAN_x4.pth') +_device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') +_model = None + + +def _get_model(): + global _model + if _model is None: + _model = arch.RRDBNet(3, 3, 64, 23, gc=32) + _model.load_state_dict(torch.load(_MODEL_PATH, map_location=_device), strict=True) + _model.eval() + _model = _model.to(_device) + return _model + + +def upscale_image(image_filepath): + model = _get_model() + + print('Up-scaling with device: {}...'.format(_device)) + + image = cv2.imread(image_filepath, cv2.IMREAD_COLOR) + image = image * 1.0 / 255 + image = torch.from_numpy(np.transpose(image[:, :, [2, 1, 0]], (2, 0, 1))).float() + image_low_res = image.unsqueeze(0).to(_device) + + with torch.no_grad(): + image_high_res = model(image_low_res).data.squeeze().float().cpu().clamp_(0, 1).numpy() + image_high_res = np.transpose(image_high_res[[2, 1, 0], :, :], (1, 2, 0)) + image_high_res = (image_high_res * 255.0).round() + + _, output_filepath = tempfile.mkstemp(suffix='.png') + cv2.imwrite(output_filepath, image_high_res) + print("image saved as:", output_filepath) + + return output_filepath + + + diff --git a/app/models/StableDiffusionAPI/.gitignore b/app/models/StableDiffusionAPI/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbff2f62d4b99fd0d7693ada5074e3455b48456d --- /dev/null +++ b/app/models/StableDiffusionAPI/.gitignore @@ -0,0 +1 @@ +Key.json \ No newline at end of file diff --git a/app/models/StableDiffusionAPI/StableDiffusionV2.py b/app/models/StableDiffusionAPI/StableDiffusionV2.py new file mode 100644 index 0000000000000000000000000000000000000000..fdbfdef0c79131bbe88703c045b077fb11ab246e --- /dev/null +++ b/app/models/StableDiffusionAPI/StableDiffusionV2.py @@ -0,0 +1,26 @@ +import os +import requests +import io +from PIL import Image + +API_URL = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-2-1" + + +def generate(text_prompt): + api_key = os.environ.get("HF_API_KEY", "") + if not api_key: + raise ValueError("HF_API_KEY environment variable is not set.") + response = requests.post( + API_URL, + headers={"Authorization": f"Bearer {api_key}"}, + json={"inputs": text_prompt}, + ) + response.raise_for_status() + return Image.open(io.BytesIO(response.content)) + + +""" +text = input("Your sentence here:") +image = generate(text) +image.show() +""" \ No newline at end of file diff --git a/app/models/StackGAN/.gitignore b/app/models/StackGAN/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c7d5fb025eb82c71b90bba861908987f4ad5a111 --- /dev/null +++ b/app/models/StackGAN/.gitignore @@ -0,0 +1,5 @@ +bedroom_3stages_color/ +birds_3stages/ +cat_3stages_color/ +church_outdoor_3stages_color/ +dog_3stages_color/ \ No newline at end of file diff --git a/app/models/encryption/aes.py b/app/models/encryption/aes.py new file mode 100644 index 0000000000000000000000000000000000000000..575c32619a4756d16b65452343c132b6108c1e46 --- /dev/null +++ b/app/models/encryption/aes.py @@ -0,0 +1,64 @@ +from base64 import b64encode, b64decode +import hashlib +from Crypto.Cipher import AES +from Crypto.Random import get_random_bytes +from Crypto.Util.Padding import pad, unpad + + +def encrypt(image_path, key): + # Load the image and convert it into bytes + with open(image_path, 'rb') as f: + image_data = f.read() + + # Encode the image data as a base64 string + image_data = b64encode(image_data) + + # Create a SHA-256 hash of the key + key = hashlib.sha256(key.encode()).digest() + + # Generate a random initialization vector + iv = get_random_bytes(AES.block_size) + + # Create an AES Cipher object + cipher = AES.new(key, AES.MODE_CBC, iv) + + # Encrypt the image data + encrypted_image_data = cipher.encrypt(pad(image_data, AES.block_size)) + + # Save the encrypted image data to a new file + with open(image_path + '.enc', 'wb') as f: + f.write(iv + encrypted_image_data) + + +def decrypt(encrypted_image_path, key): + # Load the encrypted image data + with open(encrypted_image_path, 'rb') as f: + encrypted_image_data = f.read() + + # Create a SHA-256 hash of the key + key = hashlib.sha256(key.encode()).digest() + + # Extract the initialization vector from the encrypted image data + iv = encrypted_image_data[:AES.block_size] + encrypted_image_data = encrypted_image_data[AES.block_size:] + + # Create an AES Cipher object + cipher = AES.new(key, AES.MODE_CBC, iv) + + try: + # Decrypt the encrypted image data + decrypted_image_data = unpad(cipher.decrypt(encrypted_image_data), AES.block_size) + + # Decode the decrypted image data from a base64 string + decrypted_image_data = b64decode(decrypted_image_data) + + # Save the decrypted image data to a new file + filename = encrypted_image_path.replace('.enc', '').replace('.png', '').replace('.jpg', '') + '.dec' + '.png' + with open(filename, 'wb') as f: + f.write(decrypted_image_data) + + except ValueError: + print("Wrong Key ):") + return -1, None + return 0, filename + diff --git a/app/models/encryption/blowfish.py b/app/models/encryption/blowfish.py new file mode 100644 index 0000000000000000000000000000000000000000..a846e58b5a3e9fb0ab91d95749f81c78ac500f26 --- /dev/null +++ b/app/models/encryption/blowfish.py @@ -0,0 +1,63 @@ +from base64 import b64encode, b64decode +import hashlib +from Crypto.Cipher import Blowfish +from Crypto.Random import get_random_bytes +from Crypto.Util.Padding import pad, unpad + + +def encrypt(image_path, key): + # Load the image and convert it into bytes + with open(image_path, 'rb') as f: + image_data = f.read() + + # Encode the image data as a base64 string + image_data = b64encode(image_data) + + # Create a SHA-256 hash of the key + key = hashlib.sha256(key.encode()).digest() + + # Generate a random initialization vector + iv = get_random_bytes(Blowfish.block_size) + + # Create a Blowfish Cipher object + cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv) + + # Encrypt the image data + encrypted_image_data = cipher.encrypt(pad(image_data, Blowfish.block_size)) + + # Save the encrypted image data to a new file + with open(image_path + '.enc', 'wb') as f: + f.write(iv + encrypted_image_data) + + +def decrypt(encrypted_image_path, key): + # Load the encrypted image data + with open(encrypted_image_path, 'rb') as f: + encrypted_image_data = f.read() + + # Create a SHA-256 hash of the key + key = hashlib.sha256(key.encode()).digest() + + # Extract the initialization vector from the encrypted image data + iv = encrypted_image_data[:Blowfish.block_size] + encrypted_image_data = encrypted_image_data[Blowfish.block_size:] + + # Create a Blowfish Cipher object + cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv) + + try: + # Decrypt the encrypted image data + decrypted_image_data = unpad(cipher.decrypt(encrypted_image_data), Blowfish.block_size) + + # Decode the decrypted image data from a base64 string + decrypted_image_data = b64decode(decrypted_image_data) + + # Save the decrypted image data to a new file + filename = encrypted_image_path.replace('.enc', '').replace('.png', '').replace('.jpg', '') + '.dec' + '.png' + with open(filename, 'wb') as f: + f.write(decrypted_image_data) + + except ValueError: + print("Wrong key") + return -1, None + return 0, filename diff --git a/app/ui/__init__.py b/app/ui/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/app/ui/assets/components_backgrounds/main_window_bg.png b/app/ui/assets/components_backgrounds/main_window_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..e3972f914f40cb9570452fe6221f8dbc28112986 --- /dev/null +++ b/app/ui/assets/components_backgrounds/main_window_bg.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd5ac25b8bbcf4e4eaef89bcf50db2eeaac7a2913082204a4f49596b31f01269 +size 456914 diff --git a/app/ui/assets/components_backgrounds/main_window_welcome_bg.png b/app/ui/assets/components_backgrounds/main_window_welcome_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..6c049ab62b905bf0a31ebafb540cda62877a7be7 --- /dev/null +++ b/app/ui/assets/components_backgrounds/main_window_welcome_bg.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cd17175e4a74b09636ee57f61a2532554848010a3aacc38977e8f86b32f484c +size 12922455 diff --git a/app/ui/assets/components_backgrounds/sidebar_bg.jpg b/app/ui/assets/components_backgrounds/sidebar_bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..358aaea2c22d3c523e40e180f1b96ac31d5c219c --- /dev/null +++ b/app/ui/assets/components_backgrounds/sidebar_bg.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6403005e61bdf9efaf501f6d9dd9f8c55376ef880374f022001cded8c005331a +size 75389 diff --git a/app/ui/assets/components_backgrounds/sidebar_bg2.jpg b/app/ui/assets/components_backgrounds/sidebar_bg2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b2fca42ae8f74bda7063a51bf4189c9dbe9a7f62 --- /dev/null +++ b/app/ui/assets/components_backgrounds/sidebar_bg2.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3aa5c0723f7306b50bfc23fa0777eb504b4b58b1b50e7ef3897424f63cdded9 +size 130544 diff --git a/app/ui/assets/components_backgrounds/sidebar_bg3.jpg b/app/ui/assets/components_backgrounds/sidebar_bg3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6c43f1c4c6392d700c98516259a13837d7a7a3df --- /dev/null +++ b/app/ui/assets/components_backgrounds/sidebar_bg3.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b826e013b2c9aea983530201fbab00e536fc06d23bd79dddf49fa87ce4d6ed0 +size 71646 diff --git a/app/ui/assets/dummy_images/cover_image_dummy.png b/app/ui/assets/dummy_images/cover_image_dummy.png new file mode 100644 index 0000000000000000000000000000000000000000..cfc3f6012ab8e1dec0965c665b6cf10e8833b599 --- /dev/null +++ b/app/ui/assets/dummy_images/cover_image_dummy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ffb405eed6f85c77606f1df4af78b253e9cb07e0ee794f32b6624acbdcd05bc7 +size 41157 diff --git a/app/ui/assets/dummy_images/image_dummy.png b/app/ui/assets/dummy_images/image_dummy.png new file mode 100644 index 0000000000000000000000000000000000000000..5f865d77a5de7d51c41fb61b70a44999afd4675d --- /dev/null +++ b/app/ui/assets/dummy_images/image_dummy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0614e9ddbe17338a5341bc6812c9d7ddc482f244f1bc26396af3aad359dc84a +size 38068 diff --git a/app/ui/assets/dummy_images/imagegen_dummy.png b/app/ui/assets/dummy_images/imagegen_dummy.png new file mode 100644 index 0000000000000000000000000000000000000000..e8f59743484911d1003323ccbac8b3c1df79a188 --- /dev/null +++ b/app/ui/assets/dummy_images/imagegen_dummy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86703d7d9f27a9c61a4236f203067750aaa5752b2ae98b0a08d109943b68028c +size 94975 diff --git a/app/ui/assets/dummy_images/locked_image_dummy.png b/app/ui/assets/dummy_images/locked_image_dummy.png new file mode 100644 index 0000000000000000000000000000000000000000..f9d6143efc4c7ac57eb2dd827cbcc2baa6702417 --- /dev/null +++ b/app/ui/assets/dummy_images/locked_image_dummy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05a587b6e865af69ccc9ec3e49f79c8aa955f9997a06857d03340fdafb91913f +size 24364 diff --git a/app/ui/assets/dummy_images/lr_image_dummy.png b/app/ui/assets/dummy_images/lr_image_dummy.png new file mode 100644 index 0000000000000000000000000000000000000000..baa73b5390ef87e238ad2e830f309400c9be9658 --- /dev/null +++ b/app/ui/assets/dummy_images/lr_image_dummy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0de9ec68761117d5bba3efdc939f945f0b7174e7f404fe06513ffee6ecd40684 +size 88971 diff --git a/app/ui/assets/dummy_images/secret_image_dummy.png b/app/ui/assets/dummy_images/secret_image_dummy.png new file mode 100644 index 0000000000000000000000000000000000000000..ab43a4a53cbe8ead851daa6461dcb534c937958e --- /dev/null +++ b/app/ui/assets/dummy_images/secret_image_dummy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f9b78fe35277ff8b15f3279e4e56fcb2b48ad5e1f019381eedaceca19c99095 +size 41605 diff --git a/app/ui/assets/dummy_images/steg_image_dummy.png b/app/ui/assets/dummy_images/steg_image_dummy.png new file mode 100644 index 0000000000000000000000000000000000000000..f82d32158142fb63e9fb530d07ac13b1ac252a84 --- /dev/null +++ b/app/ui/assets/dummy_images/steg_image_dummy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c47f893859a36b27874fdda14032b176728dcfa3d6657f961b2acc885e725b5 +size 41032 diff --git a/app/ui/assets/json/lucky.json b/app/ui/assets/json/lucky.json new file mode 100644 index 0000000000000000000000000000000000000000..5f2d5becd646deecaf8983c0036ac7fbc85cc66a --- /dev/null +++ b/app/ui/assets/json/lucky.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ee8b1b4eeaa74a91f163b528d4ad7412bfaa17dc893a4462f763be59edb0238 +size 9880 diff --git a/app/ui/assets/readme_assets/hide.png b/app/ui/assets/readme_assets/hide.png new file mode 100644 index 0000000000000000000000000000000000000000..c63a164b03edf8cdab0a234c0a8238a0aea1063b --- /dev/null +++ b/app/ui/assets/readme_assets/hide.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6cc585ff6ff1ef52a474cdb2de8bd9f26d8887eb69e30a291f08a8be9c235b7 +size 766591 diff --git a/app/ui/assets/readme_assets/main_window.png b/app/ui/assets/readme_assets/main_window.png new file mode 100644 index 0000000000000000000000000000000000000000..743fe8a82f6662b7f49b94f8c5ca21a9802aa4cc --- /dev/null +++ b/app/ui/assets/readme_assets/main_window.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c2804954d144ef191f9c8a097f4fff43b47fd7bbe1692b8b69dfc8d7c522fae +size 550340 diff --git a/app/ui/assets/readme_assets/reveal.png b/app/ui/assets/readme_assets/reveal.png new file mode 100644 index 0000000000000000000000000000000000000000..022dd61a2edef5228d46e5f6f56178bc435df1e1 --- /dev/null +++ b/app/ui/assets/readme_assets/reveal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c41104a6abdde578202f35622f55629485528daf2ec6a0c511e0262ca6fe68d +size 689652 diff --git a/app/ui/assets/readme_assets/superres.png b/app/ui/assets/readme_assets/superres.png new file mode 100644 index 0000000000000000000000000000000000000000..41087f24c3ae4343b78e3471c17752a00a175d31 --- /dev/null +++ b/app/ui/assets/readme_assets/superres.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2156f72e7c7f6cc0657c5d361b0073880a165ade6872ccbfebabfd7b574b6cf +size 860873 diff --git a/app/ui/components/backgroundwidget.py b/app/ui/components/backgroundwidget.py new file mode 100644 index 0000000000000000000000000000000000000000..93deea6bd8acb2efb17a59b2ddee3147a82d9bb0 --- /dev/null +++ b/app/ui/components/backgroundwidget.py @@ -0,0 +1,21 @@ +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QPixmap, QPainter, QPaintEvent +from PyQt5.QtWidgets import QWidget + + +class BackgroundWidget(QWidget): + def __init__(self, parent=None): + super().__init__(parent) + self.background_image = None + + def set_background_image(self, image_path): + self.background_image = QPixmap(image_path) + self.update() + + def paintEvent(self, event: QPaintEvent): + painter = QPainter(self) + if self.background_image: + pixmap = self.background_image.scaled(self.size(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation) + x_offset = (pixmap.width() - self.width()) // 2 + y_offset = (pixmap.height() - self.height()) // 2 + painter.drawPixmap(-x_offset, -y_offset, pixmap) diff --git a/app/ui/components/customtextbox.py b/app/ui/components/customtextbox.py new file mode 100644 index 0000000000000000000000000000000000000000..4bea755f963d85b0f6b68bb25eae7cd90dc7870c --- /dev/null +++ b/app/ui/components/customtextbox.py @@ -0,0 +1,80 @@ +from PyQt5.QtWidgets import QLineEdit +from PyQt5.QtGui import QPainter, QPalette + + +class CustomTextBox(QLineEdit): + def __init__(self, parent=None): + super().__init__(parent) + self.setStyleSheet( + ''' + QLineEdit { + background-color: transparent; + border:2px solid; + border-radius: 5px; + border-color: #ffffff; + font-size: 18px; + color: #ffffff; + font-weight: bold; + height: 40px; + width: 10px; + } + ''' + ) + + def paintEvent(self, event): + painter = QPainter(self) + painter.setRenderHint(QPainter.Antialiasing) + + border_color = self.palette().color(QPalette.Text) + border_color.setAlpha(50) + painter.setPen(border_color) + + painter.drawRoundedRect( + 0, + 0, + self.width(), + self.height(), + 5, + 5 + ) + + super().paintEvent(event) + + +class CustomTextBoxForImageGen(QLineEdit): + def __init__(self, parent=None): + super().__init__(parent) + self.setStyleSheet( + ''' + QLineEdit { + background-color: transparent; + border:1.2px solid; + border-radius: 5px; + border-color: #fae69e; + font-size: 18px; + color: #ffffff; + padding: 8px 16px; + font-weight: semi-bold; + height: 40px; + } + ''' + ) + + def paintEvent(self, event): + painter = QPainter(self) + painter.setRenderHint(QPainter.Antialiasing) + + border_color = self.palette().color(QPalette.Text) + border_color.setAlpha(50) + painter.setPen(border_color) + + painter.drawRoundedRect( + 0, + 0, + self.width(), + self.height(), + 5, + 5 + ) + + super().paintEvent(event) \ No newline at end of file diff --git a/app/ui/icon.ico b/app/ui/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..dc7b6683933b638793ed3295ecb70b892751522c --- /dev/null +++ b/app/ui/icon.ico @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:807d1cb4207d2e729578df18900257e33444dc080cecaf88fc99015b18de15a3 +size 15406 diff --git a/app/ui/logo.png b/app/ui/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..94fd20fdda56eaaf4aefe6e52c13233e9b0e22a3 --- /dev/null +++ b/app/ui/logo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72cdcbd4a785316ef39700d9bca7c059ad6d9f25cabe505b3cd7396929d32319 +size 787358 diff --git a/app/ui/main.py b/app/ui/main.py new file mode 100644 index 0000000000000000000000000000000000000000..a5aadf7c309df45b3cf3759259a177b37241f0e4 --- /dev/null +++ b/app/ui/main.py @@ -0,0 +1,906 @@ +import os +import os +import sys + +import cv2 +import numpy as np +import torch +from PyQt5.QtCore import QFile, QTextStream +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QIcon, QPixmap, QFont +from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, \ + QMessageBox, QFileDialog, QDialog, QRadioButton, QButtonGroup + +from app.models.DEEP_STEGO.hide_image import hide_image +from app.models.DEEP_STEGO.reveal_image import reveal_image +from app.models.ESRGAN import RRDBNet_arch as arch +from app.models.StableDiffusionAPI import StableDiffusionV2 +from app.models.encryption import aes, blowfish +from app.ui.components.backgroundwidget import BackgroundWidget +from app.ui.components.customtextbox import CustomTextBox, CustomTextBoxForImageGen + + +class MainAppWindow(QMainWindow): + def __init__(self): + super().__init__() + # vars + self.download_genimage_button = None + self.gen_image_label = None + self.text_desc_box = None + self.main_content = None + self.blowfish_radio_dec = None + self.aes_radio_dec = None + self.key_text_box_of_dec = None + self.enc_filepath = None + self.dec_display_label = None + self.download_dec_button = None + self.dec_img_text_label = None + self.enc_img_text_label = None + self.key_text_box = None + self.blowfish_radio = None + self.aes_radio = None + self.image_tobe_enc_filepath = None + self.download_enc_button = None + self.enc_display_label = None + self.container_image_filepath = None + self.secret_out_display_label = None + self.container_display_label = None + self.download_revealed_secret_image_button = None + self.download_steg_button = None + self.secret_image_filepath = None + self.cover_image_filepath = None + self.steg_display_label = None + self.secret_display_label = None + self.cover_display_label = None + self.low_res_image_text_label = None + self.image_label = None + self.low_res_image_filepath = None + self.download_HR_button = None + + # Set window properties + self.setWindowTitle("InvisiCipher") + self.setGeometry(200, 200, 1400, 800) + self.setWindowIcon(QIcon("icon.ico")) + self.setStyleSheet("background-color: #2b2b2b;") + self.setFixedSize(self.size()) + # self.setWindowFlags(Qt.FramelessWindowHint) + + # Set up the main window layout + main_layout = QHBoxLayout() + + # Create the side navigation bar + side_navigation = BackgroundWidget() + side_navigation.set_background_image("assets/components_backgrounds/sidebar_bg.jpg") + side_navigation.setObjectName("side_navigation") + side_navigation.setFixedWidth(200) + side_layout = QVBoxLayout() + + # label for logo + logo_label = QLabel() + logo_pixmap = QPixmap("logo.png").scaled(50, 50, Qt.KeepAspectRatio) + logo_label.setPixmap(logo_pixmap) + logo_label.setAlignment(Qt.AlignCenter) + + # label for logo name + name_label = QLabel() + name_label.setText("

InvisiCipher










") + name_label.setStyleSheet("color: #ffffff;") + name_label.setAlignment(Qt.AlignCenter) + + # Create buttons for each option + encryption_button = QPushButton("Encryption") + decryption_button = QPushButton("Decryption") + image_hiding_button = QPushButton("Image Hide") + image_reveal_button = QPushButton("Image Reveal") + super_resolution_button = QPushButton("Super Resolution") + imagegen_button = QPushButton("Generate image") + + # Connect button signals to their corresponding slots + encryption_button.clicked.connect(self.show_encryption_page) + decryption_button.clicked.connect(self.show_decryption_page) + image_hiding_button.clicked.connect(self.show_image_hiding_page) + image_reveal_button.clicked.connect(self.show_reveal_page) + super_resolution_button.clicked.connect(self.show_super_resolution_page) + imagegen_button.clicked.connect(self.show_imagegen_page) + + # Add buttons to the side navigation layout + side_layout.addWidget(logo_label) + side_layout.addWidget(name_label) + side_layout.addWidget(image_hiding_button) + side_layout.addWidget(encryption_button) + side_layout.addWidget(decryption_button) + side_layout.addWidget(image_reveal_button) + side_layout.addWidget(super_resolution_button) + side_layout.addWidget(imagegen_button) + + # Add a logout button + logout_button = QPushButton("Exit") + logout_button.setObjectName("logout_button") + logout_button.clicked.connect(self.logout) + side_layout.addStretch() + side_layout.addWidget(logout_button) + + # Set the layout for the side navigation widget + side_navigation.setLayout(side_layout) + + # Create the main content area + self.main_content = BackgroundWidget() + self.main_content.setObjectName("main_content") + self.main_content.set_background_image("assets/components_backgrounds/main_window_welcome_bg.png") + self.main_layout = QVBoxLayout() + self.main_content.setLayout(self.main_layout) + + # Add the side navigation and main content to the main window layout + main_layout.addWidget(side_navigation) + main_layout.addWidget(self.main_content) + + # Set the main window layout + central_widget = QWidget() + central_widget.setLayout(main_layout) + self.setCentralWidget(central_widget) + + def show_encryption_page(self): + self.main_content.set_background_image("assets/components_backgrounds/main_window_bg.png") + self.image_tobe_enc_filepath = None + self.key_text_box = None + self.enc_img_text_label = None + # Clear the main window layout + self.clear_main_layout() + + # Add content to the super resolution page + title_label = QLabel("

Image Encryption

") + title_label.setStyleSheet("font-size: 24px; color: #ffffff;") + title_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(title_label) + + # label layout + label_layout = QHBoxLayout() + + method_text_label = QLabel("Select encryption method:") + method_text_label.setAlignment(Qt.AlignVCenter) + method_text_label.setStyleSheet("font-size: 16px; color: #c6c6c6; margin-bottom: 10px; font-weight: bold;") + label_layout.addWidget(method_text_label) + + self.enc_img_text_label = QLabel("Select Image to be Encrypted:") + self.enc_img_text_label.setAlignment(Qt.AlignCenter) + self.enc_img_text_label.setStyleSheet("font-size: 16px; color: #c6c6c6; margin-bottom: 10px; font-weight: bold;") + label_layout.addWidget(self.enc_img_text_label) + + label_layout_widget = QWidget() + label_layout_widget.setLayout(label_layout) + self.main_layout.addWidget(label_layout_widget) + + # Image display layout + image_display_layout = QHBoxLayout() + + radio_layout = QVBoxLayout() + radio_layout.setAlignment(Qt.AlignLeft) + self.aes_radio = QRadioButton("AES Encryption") + self.aes_radio.setToolTip("Widely adopted symmetric-key block cipher with strong security and flexibility") + + self.blowfish_radio = QRadioButton("Blowfish Encryption") + self.blowfish_radio.setToolTip("Fast, efficient symmetric-key block cipher with versatile key lengths") + + encryption_group = QButtonGroup() + encryption_group.addButton(self.aes_radio) + encryption_group.addButton(self.blowfish_radio) + radio_layout.addWidget(self.blowfish_radio) + radio_layout.addWidget(self.aes_radio) + + key_text_label = QLabel("


Enter the secret key") + key_text_label.setStyleSheet("font-size: 18px; color: #ffffff; font-weight: bold;") + radio_layout.addWidget(key_text_label) + + self.key_text_box = CustomTextBox() + self.key_text_box.setFixedWidth(300) + radio_layout.addWidget(self.key_text_box) + + radio_layout_widget = QWidget() + radio_layout_widget.setLayout(radio_layout) + image_display_layout.addWidget(radio_layout_widget) + + self.enc_display_label = QLabel() + # self.enc_display_label.setAlignment(Qt.AlignCenter) + pixmap = QPixmap("assets/dummy_images/image_dummy.png") + self.enc_display_label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + image_display_layout.addWidget(self.enc_display_label) + + image_display_layout_widget = QWidget() + image_display_layout_widget.setLayout(image_display_layout) + self.main_layout.addWidget(image_display_layout_widget) + + # button layout + button_layout = QHBoxLayout() + clear_button = QPushButton("Clear") + clear_button.clicked.connect(lambda: self.show_encryption_page()) + button_layout.addWidget(clear_button) + + browse_enc_button = QPushButton("Browse image") + browse_enc_button.clicked.connect(lambda: self.select_enc_image(self.enc_display_label)) + button_layout.addWidget(browse_enc_button) + + encrypt_button = QPushButton("Encrypt") + encrypt_button.clicked.connect(lambda: self.perform_encryption(self.image_tobe_enc_filepath)) + button_layout.addWidget(encrypt_button) + + self.download_enc_button = QPushButton("DownloadπŸ”½") + self.download_enc_button.setEnabled(False) + self.download_enc_button.clicked.connect(lambda: self.download_image()) + button_layout.addWidget(self.download_enc_button) + + button_layout_widget = QWidget() + button_layout_widget.setLayout(button_layout) + self.main_layout.addWidget(button_layout_widget) + + def show_decryption_page(self): + self.main_content.set_background_image("assets/components_backgrounds/main_window_bg.png") + self.key_text_box_of_dec = None + # Clear the main window layout + self.clear_main_layout() + + # Add content to the super resolution page + title_label = QLabel("

Image Decryption

") + title_label.setStyleSheet("font-size: 24px; color: #ffffff;") + title_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(title_label) + + # label layout + label_layout = QHBoxLayout() + + method_text_label = QLabel("Select Decryption method:") + method_text_label.setAlignment(Qt.AlignVCenter) + method_text_label.setStyleSheet("font-size: 16px; color: #c6c6c6; margin-bottom: 10px; font-weight: bold;") + label_layout.addWidget(method_text_label) + + self.dec_img_text_label = QLabel("Select the file to be decrypted:") + self.dec_img_text_label.setAlignment(Qt.AlignCenter) + self.dec_img_text_label.setStyleSheet("font-size: 16px; color: #c6c6c6; margin-bottom: 10px; font-weight: bold;") + label_layout.addWidget(self.dec_img_text_label) + + label_layout_widget = QWidget() + label_layout_widget.setLayout(label_layout) + self.main_layout.addWidget(label_layout_widget) + + # Image display layout + image_display_layout = QHBoxLayout() + + radio_layout = QVBoxLayout() + radio_layout.setAlignment(Qt.AlignLeft) + self.aes_radio_dec = QRadioButton("AES Decryption") + self.aes_radio_dec.setToolTip("Widely adopted symmetric-key block cipher with strong security and flexibility") + + self.blowfish_radio_dec = QRadioButton("Blowfish Decryption") + self.blowfish_radio_dec.setToolTip("Fast, efficient symmetric-key block cipher with versatile key lengths") + + encryption_group = QButtonGroup() + encryption_group.addButton(self.aes_radio_dec) + encryption_group.addButton(self.blowfish_radio_dec) + radio_layout.addWidget(self.blowfish_radio_dec) + radio_layout.addWidget(self.aes_radio_dec) + + key_text_label = QLabel("


Enter the secret key") + key_text_label.setStyleSheet("font-size: 18px; color: #ffffff; font-weight: bold;") + radio_layout.addWidget(key_text_label) + + self.key_text_box_of_dec = CustomTextBox() + self.key_text_box_of_dec.setFixedWidth(300) + radio_layout.addWidget(self.key_text_box_of_dec) + + radio_layout_widget = QWidget() + radio_layout_widget.setLayout(radio_layout) + image_display_layout.addWidget(radio_layout_widget) + + self.dec_display_label = QLabel() + self.dec_display_label.setAlignment(Qt.AlignLeft) + pixmap = QPixmap("assets/dummy_images/image_dummy.png") + self.dec_display_label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + image_display_layout.addWidget(self.dec_display_label) + + image_display_layout_widget = QWidget() + image_display_layout_widget.setLayout(image_display_layout) + self.main_layout.addWidget(image_display_layout_widget) + + # button layout + button_layout = QHBoxLayout() + clear_button = QPushButton("Clear") + clear_button.clicked.connect(lambda: self.show_decryption_page()) + button_layout.addWidget(clear_button) + + browse_enc_button = QPushButton("Browse encrypted file") + browse_enc_button.clicked.connect(lambda: self.select_dec_image(self.dec_display_label)) + button_layout.addWidget(browse_enc_button) + + decrypt_button = QPushButton("Decrypt") + decrypt_button.clicked.connect(lambda: self.perform_decryption(self.enc_filepath)) + button_layout.addWidget(decrypt_button) + + self.download_dec_button = QPushButton("DownloadπŸ”½") + self.download_dec_button.setEnabled(False) + self.download_dec_button.clicked.connect(lambda: self.download_image()) + button_layout.addWidget(self.download_dec_button) + + button_layout_widget = QWidget() + button_layout_widget.setLayout(button_layout) + self.main_layout.addWidget(button_layout_widget) + + def show_image_hiding_page(self): + self.main_content.set_background_image("assets/components_backgrounds/main_window_bg.png") + self.secret_image_filepath = None + self.cover_image_filepath = None + # Clear the main window layout + self.clear_main_layout() + + # Add content to the super resolution page + title_label = QLabel("

STEGO CNN : Steganography Hide

") + title_label.setStyleSheet("font-size: 24px; color: #ffffff;") + title_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(title_label) + + # STEGO CNN model path label + model_path_label = QLabel("
Model Path: InvisiCipher/app/models/DEEP_STEGO/models/hide.h5
") + model_path_label.setStyleSheet("font-size: 16px; color: #c6c6c6;") + model_path_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(model_path_label) + + # GPU Info + gpu_info_label = QLabel("") + gpu_info_label.setStyleSheet("font-size: 13px; color: #fae69e;") + gpu_info_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(gpu_info_label) + + # label layout + label_layout = QHBoxLayout() + cover_text_label = QLabel("Select cover image:") + cover_text_label.setAlignment(Qt.AlignCenter) + cover_text_label.setStyleSheet("font-size: 16px; color: #c6c6c6; margin-bottom: 10px; font-weight: bold;") + label_layout.addWidget(cover_text_label) + + secret_text_label = QLabel("Select secret image:") + secret_text_label.setAlignment(Qt.AlignCenter) + secret_text_label.setStyleSheet("font-size: 16px; color: #c6c6c6; margin-bottom: 10px; font-weight: bold;") + label_layout.addWidget(secret_text_label) + + steg_text_label = QLabel("Generated steg image:") + steg_text_label.setAlignment(Qt.AlignCenter) + steg_text_label.setStyleSheet("font-size: 16px; color: #00ff00; margin-bottom: 10px; font-weight: bold;") + label_layout.addWidget(steg_text_label) + + label_layout_widget = QWidget() + label_layout_widget.setLayout(label_layout) + self.main_layout.addWidget(label_layout_widget) + + # Image display layout + image_display_layout = QHBoxLayout() + self.cover_display_label = QLabel() + self.cover_display_label.setAlignment(Qt.AlignCenter) + pixmap = QPixmap("assets/dummy_images/cover_image_dummy.png") + self.cover_display_label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + image_display_layout.addWidget(self.cover_display_label) + + self.secret_display_label = QLabel() + self.secret_display_label.setAlignment(Qt.AlignCenter) + pixmap = QPixmap("assets/dummy_images/secret_image_dummy.png") + self.secret_display_label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + image_display_layout.addWidget(self.secret_display_label) + + self.steg_display_label = QLabel() + self.steg_display_label.setAlignment(Qt.AlignCenter) + pixmap = QPixmap("assets/dummy_images/steg_image_dummy.png") + self.steg_display_label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + image_display_layout.addWidget(self.steg_display_label) + + image_display_layout_widget = QWidget() + image_display_layout_widget.setLayout(image_display_layout) + self.main_layout.addWidget(image_display_layout_widget) + + # button layout + button_layout = QHBoxLayout() + clear_button = QPushButton("Clear") + clear_button.clicked.connect(lambda: self.show_image_hiding_page()) + button_layout.addWidget(clear_button) + + browse_cover_button = QPushButton("Browse cover image") + browse_cover_button.clicked.connect(lambda: self.select_cover_image(self.cover_display_label)) + button_layout.addWidget(browse_cover_button) + + browse_secret_button = QPushButton("Browse secret image") + browse_secret_button.clicked.connect(lambda: self.select_secret_image(self.secret_display_label)) + button_layout.addWidget(browse_secret_button) + + hide_button = QPushButton("Hide") + hide_button.clicked.connect(lambda: self.perform_hide(self.cover_image_filepath, self.secret_image_filepath)) + button_layout.addWidget(hide_button) + + self.download_steg_button = QPushButton("Download steg imageπŸ”½") + self.download_steg_button.setEnabled(False) + self.download_steg_button.clicked.connect(lambda: self.download_image()) + button_layout.addWidget(self.download_steg_button) + + button_layout_widget = QWidget() + button_layout_widget.setLayout(button_layout) + self.main_layout.addWidget(button_layout_widget) + + def show_reveal_page(self): + self.main_content.set_background_image("assets/components_backgrounds/main_window_bg.png") + self.clear_main_layout() + + # Add content to the super resolution page + title_label = QLabel("

STEGO CNN : Steganography Reveal

") + title_label.setStyleSheet("font-size: 24px; color: #ffffff;") + title_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(title_label) + + # STEGO CNN model path label + model_path_label = QLabel("
Model Path: InvisiCipher/app/models/DEEP_STEGO/models/reveal.h5
") + model_path_label.setStyleSheet("font-size: 16px; color: #c6c6c6;") + model_path_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(model_path_label) + + # GPU Info + gpu_info_label = QLabel("") + gpu_info_label.setStyleSheet("font-size: 13px; color: #fae69e;") + gpu_info_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(gpu_info_label) + + # image text layout + image_text_layout = QHBoxLayout() + container_text_label = QLabel("Select steg image:") + container_text_label.setAlignment(Qt.AlignCenter) + container_text_label.setStyleSheet("font-size: 16px; color: #c6c6c6; margin-bottom: 10px; font-weight: bold;") + image_text_layout.addWidget(container_text_label) + + secret_out_text_label = QLabel("Revealed secret image:") + secret_out_text_label.setAlignment(Qt.AlignCenter) + secret_out_text_label.setStyleSheet("font-size: 16px; color: #00ff00; margin-bottom: 10px; font-weight: bold;") + image_text_layout.addWidget(secret_out_text_label) + + image_text_layout_widget = QWidget() + image_text_layout_widget.setLayout(image_text_layout) + self.main_layout.addWidget(image_text_layout_widget) + + # Image display layout + image_layout = QHBoxLayout() + self.container_display_label = QLabel() + self.container_display_label.setAlignment(Qt.AlignCenter) + pixmap = QPixmap("assets/dummy_images/steg_image_dummy.png") + self.container_display_label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + image_layout.addWidget(self.container_display_label) + + self.secret_out_display_label = QLabel() + self.secret_out_display_label.setAlignment(Qt.AlignCenter) + pixmap = QPixmap("assets/dummy_images/secret_image_dummy.png") + self.secret_out_display_label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + image_layout.addWidget(self.secret_out_display_label) + + image_layout_widget = QWidget() + image_layout_widget.setLayout(image_layout) + self.main_layout.addWidget(image_layout_widget) + + # button layout + button_layout = QHBoxLayout() + clear_button = QPushButton("Clear") + clear_button.clicked.connect(lambda: self.show_reveal_page()) + button_layout.addWidget(clear_button) + + browse_cover_button = QPushButton("Browse steg image") + browse_cover_button.clicked.connect(lambda: self.select_container_image(self.container_display_label)) + button_layout.addWidget(browse_cover_button) + + reveal_button = QPushButton("Reveal") + reveal_button.clicked.connect(lambda: self.perform_reveal(self.container_image_filepath)) + button_layout.addWidget(reveal_button) + + self.download_revealed_secret_image_button = QPushButton("DownloadπŸ”½") + self.download_revealed_secret_image_button.setEnabled(False) + self.download_revealed_secret_image_button.clicked.connect(lambda: self.download_image()) + button_layout.addWidget(self.download_revealed_secret_image_button) + + button_layout_widget = QWidget() + button_layout_widget.setLayout(button_layout) + self.main_layout.addWidget(button_layout_widget) + + def show_super_resolution_page(self): + self.main_content.set_background_image("assets/components_backgrounds/main_window_bg.png") + self.low_res_image_filepath = None + # Clear the main window layout + self.clear_main_layout() + + # Add content to the super resolution page + title_label = QLabel("

Enhanced Super Resolution using ESRGAN

") + title_label.setAlignment(Qt.AlignTop) + title_label.setStyleSheet("font-size: 24px; color: #ffffff; margin-bottom: 20px;") + self.main_layout.addWidget(title_label) + + # ESRGAN model path label + model_path_label = QLabel("
Model Path: InvisiCipher/app/models/ESRGAN/models/RRDB_ESRGAN_x4.pth
") + model_path_label.setStyleSheet("font-size: 16px; color: #c6c6c6; margin-bottom: 20px;") + model_path_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(model_path_label) + + # GPU Info + gpu_info_label = QLabel( + "") + gpu_info_label.setStyleSheet("font-size: 13px; color: #fae69e;") + gpu_info_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(gpu_info_label) + + # Low resolution image selection + low_res_label = QLabel("Select Low Resolution Image:") + low_res_label.setAlignment(Qt.AlignCenter) + low_res_label.setStyleSheet("font-size: 16px; color: #c6c6c6; margin-bottom: 10px; font-weight: bold;") + self.main_layout.addWidget(low_res_label) + + # image display + image_label = QLabel() + image_label.setAlignment(Qt.AlignCenter) + pixmap = QPixmap("assets/dummy_images/lr_image_dummy.png") + image_label.setPixmap(pixmap.scaled(384, 384, Qt.KeepAspectRatio)) + self.main_layout.addWidget(image_label) + + # defining button layout + button_layout = QHBoxLayout() + + # Browse button + clear_button = QPushButton("Clear") + clear_button.clicked.connect(lambda: self.show_super_resolution_page()) + button_layout.addWidget(clear_button) + + browse_button = QPushButton("Browse") + browse_button.clicked.connect(lambda: self.select_low_resolution_image(image_label)) + button_layout.addWidget(browse_button) + + # Up-scale button + upscale_button = QPushButton("UP-SCALE") + upscale_button.clicked.connect(lambda: self.upscaleImage(image_label)) + button_layout.addWidget(upscale_button) + + # Download button + download_button = QPushButton("DownloadπŸ”½") + download_button.setObjectName("download_button") + download_button.setEnabled(False) + download_button.clicked.connect(self.download_image) + button_layout.addWidget(download_button) + + # add the button layout to the main layout + button_widget = QWidget() + button_widget.setLayout(button_layout) + self.main_layout.addWidget(button_widget) + + # Set the image labels as attributes + self.low_res_image_text_label = low_res_label + self.image_label = image_label + self.download_HR_button = download_button + + def show_imagegen_page(self): + self.main_content.set_background_image("assets/components_backgrounds/main_window_bg.png") + self.clear_main_layout() + + # Add content to the super resolution page + title_label = QLabel("

StackGAN : Image generation using GenAI

") + title_label.setStyleSheet("font-size: 24px; color: #ffffff;") + title_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(title_label) + + # StackGAN model path label + model_path_label = QLabel("
Model Path: InvisiCipher/app/models/StackGAN/models/
") + model_path_label.setStyleSheet("font-size: 16px; color: #c6c6c6; margin-bottom: 20px;") + model_path_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(model_path_label) + + # GPU Info + gpu_info_label = QLabel( + "") + gpu_info_label.setStyleSheet("font-size: 13px; color: #fae69e;") + gpu_info_label.setAlignment(Qt.AlignTop) + self.main_layout.addWidget(gpu_info_label) + + # image display + self.gen_image_label = QLabel() + self.gen_image_label.setAlignment(Qt.AlignCenter) + pixmap = QPixmap("assets/dummy_images/imagegen_dummy.png") + self.gen_image_label.setPixmap(pixmap.scaled(384, 384, Qt.KeepAspectRatio)) + self.main_layout.addWidget(self.gen_image_label) + + # Text description enter prompt + image_desc_label = QLabel("Your image description hereπŸ‘‡πŸ»") + image_desc_label.setAlignment(Qt.AlignCenter) + image_desc_label.setStyleSheet("font-size: 16px; color: #c6c6c6; font-weight: semi-bold;") + self.main_layout.addWidget(image_desc_label) + + # defining layout for textbox and i'm feeling lucky + textbox_layout = QHBoxLayout() + + # Create a QlineEdit widget + self.text_desc_box = CustomTextBoxForImageGen() + self.text_desc_box.setPlaceholderText("Type here....") + textbox_layout.addWidget(self.text_desc_box) + + # i'm feeling lucky button + lucky_button = QPushButton("I'm feeling lucky") + lucky_button.setObjectName("luckyButton") + lucky_button.setToolTip("Selects a random text prompt") + lucky_button.clicked.connect(lambda: self.show_random_text(self.text_desc_box)) + textbox_layout.addWidget(lucky_button) + + # add the textbox layout to the main layout + textbox_widget = QWidget() + textbox_widget.setLayout(textbox_layout) + self.main_layout.addWidget(textbox_widget) + + # defining button layout + button_layout = QHBoxLayout() + + # clear button + clear_button = QPushButton("Clear") + clear_button.clicked.connect(lambda: self.show_imagegen_page()) + button_layout.addWidget(clear_button) + + # generate button + generate_button = QPushButton("Generate✨") + generate_button.setObjectName("gen_button") + generate_button.clicked.connect(lambda: self.generateImage(self.gen_image_label)) + button_layout.addWidget(generate_button) + + # Download button + download_button = QPushButton("DownloadπŸ”½") + download_button.setObjectName("download_button") + download_button.setEnabled(False) + download_button.clicked.connect(self.download_image) + button_layout.addWidget(download_button) + self.download_genimage_button = download_button + + # add the button layout to the main layout + button_widget = QWidget() + button_widget.setLayout(button_layout) + self.main_layout.addWidget(button_widget) + + def generateImage(self, label): + print("Image gen") + gen_image_path = 'C:/Users/asirw/PycharmProjects/InvisiCipher/app/generated_image.png' + if self.text_desc_box.text() == "": + QMessageBox.information(self, "Generation Error", "Please enter a description") + return + try: + image = StableDiffusionV2.generate(text_prompt=self.text_desc_box.text()) + image.save(gen_image_path) + pixmap = QPixmap(gen_image_path) + label.setPixmap(pixmap.scaled(400, 400, Qt.KeepAspectRatio)) + self.download_genimage_button.setEnabled(True) + except: + QMessageBox.critical(self, "Generating error", "Failed to generate the image") + + def show_random_text(self, textbox): + import json, random + with open("C:/Users/asirw/PycharmProjects/InvisiCipher/app/ui/assets/json/lucky.json", "r") as f: + text = random.choice(json.load(f)) + textbox.setText(text) + def select_low_resolution_image(self, label): + file_dialog = QFileDialog() + low_res_image_filepath, _ = file_dialog.getOpenFileName(self, "Select Low Resolution Image") + if low_res_image_filepath: + self.low_res_image_filepath = low_res_image_filepath + pixmap = QPixmap(low_res_image_filepath) + label.setPixmap(pixmap.scaled(400, 400, Qt.KeepAspectRatio)) + + def upscaleImage(self, label): + if self.low_res_image_filepath is None: + QMessageBox.information(self, "Upscaling Error", "Please select the low-resolution image first.") + return + os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:400" + model_path = 'C:/Users/asirw/PycharmProjects/InvisiCipher/app/models/ESRGAN/models/RRDB_ESRGAN_x4.pth' + device = torch.device('cuda') + + model = arch.RRDBNet(3, 3, 64, 23, gc=32) + model.load_state_dict(torch.load(model_path), strict=True) + model.eval() + model = model.to(device) + + print('Model path {:s}. \nUp-scaling...'.format(model_path)) + + image = cv2.imread(self.low_res_image_filepath, cv2.IMREAD_COLOR) + image = image * 1.0 / 255 + image = torch.from_numpy(np.transpose(image[:, :, [2, 1, 0]], (2, 0, 1))).float() + image_low_res = image.unsqueeze(0) + image_low_res = image_low_res.to(device) + + with torch.no_grad(): + image_high_res = model(image_low_res).data.squeeze().float().cpu().clamp_(0, 1).numpy() + image_high_res = np.transpose(image_high_res[[2, 1, 0], :, :], (1, 2, 0)) + image_high_res = (image_high_res * 255.0).round() + + high_res_image_path = os.path.abspath('upscaled.png') + cv2.imwrite(high_res_image_path, image_high_res) + + # Display the high resolution image + if os.path.exists(high_res_image_path): + print("image saved as: ", high_res_image_path) + pixmap = QPixmap(high_res_image_path).scaled(400, 400, Qt.KeepAspectRatio) + label.setPixmap(pixmap) + self.low_res_image_text_label.setText("High Res Image:") + self.low_res_image_text_label.setStyleSheet( + "font-size: 16px; color: #00ff00; margin-bottom: 10px; font-weight: bold;") + self.download_HR_button.setEnabled(True) + else: + QMessageBox.critical(self, "Upscaling Error", "Failed to upscale the image.") + + def download_image(self): + # Implement the logic to download the high resolution image + QMessageBox.information(self, "Download", "Downloaded the image...") + + def clear_main_layout(self): + # Remove all widgets from the main layout + while self.main_layout.count(): + child = self.main_layout.takeAt(0) + if child.widget(): + child.widget().deleteLater() + + def select_cover_image(self, label): + file_dialog = QFileDialog() + filepath, _ = file_dialog.getOpenFileName(self, "Select cover Image") + if filepath: + self.cover_image_filepath = filepath + pixmap = QPixmap(filepath) + label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + + def select_secret_image(self, label): + file_dialog = QFileDialog() + filepath, _ = file_dialog.getOpenFileName(self, "Select secret Image") + if filepath: + self.secret_image_filepath = filepath + pixmap = QPixmap(filepath) + label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + + def select_container_image(self, label): + file_dialog = QFileDialog() + filepath, _ = file_dialog.getOpenFileName(self, "Select secret Image") + if filepath: + self.container_image_filepath = filepath + pixmap = QPixmap(filepath) + label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + + def select_enc_image(self, label): + file_dialog = QFileDialog() + filepath, _ = file_dialog.getOpenFileName(self, "Select Image") + if filepath: + self.image_tobe_enc_filepath = filepath + pixmap = QPixmap(filepath) + label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + + def select_dec_image(self, label): + file_dialog = QFileDialog() + filepath, _ = file_dialog.getOpenFileName(self, "Select enc file") + if filepath: + self.enc_filepath = filepath + pixmap = QPixmap("assets/dummy_images/locked_image_dummy.png") + label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + + def perform_hide(self, cover_filepath, secret_filepath): + if cover_filepath is None or secret_filepath is None: + QMessageBox.information(self, "Hiding Error", "Please select the images first.") + return + try: + hide_image(cover_filepath, secret_filepath) + steg_image_path = 'C:/Users/asirw/PycharmProjects/InvisiCipher/app/steg_image.png' + pixmap = QPixmap(steg_image_path) + self.steg_display_label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + self.download_steg_button.setEnabled(True) + except: + QMessageBox.critical(self, "Hiding Error", "Failed to hide the image.") + + def perform_reveal(self, filepath): + if filepath is None: + QMessageBox.information(self, "Revealing Error", "Please select the image first.") + return + try: + reveal_image(filepath) + secret_out_filepath = "C:/Users/asirw/PycharmProjects/InvisiCipher/app/secret_out.png" + pixmap = QPixmap(secret_out_filepath) + self.secret_out_display_label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + self.download_revealed_secret_image_button.setEnabled(True) + except: + QMessageBox.critical(self, "Revealing error", "Failed to reveal the image") + + def perform_encryption(self, filepath): + if filepath is None: + QMessageBox.information(self, "Encrypting Error", "Please select the image first.") + return + if not self.aes_radio.isChecked() and not self.blowfish_radio.isChecked(): + QMessageBox.information(self, "Encrypting Error", "Please select an encryption method.") + return + if self.key_text_box.text() == "": + QMessageBox.information(self, "Encrypting Error", "Please enter a secret key") + return + try: + if self.aes_radio.isChecked(): + aes.encrypt(filepath, self.key_text_box.text()) + else: + blowfish.encrypt(filepath, self.key_text_box.text()) + self.download_enc_button.setEnabled(True) + self.enc_img_text_label.setText("Encrypted!") + self.enc_img_text_label.setStyleSheet( + "font-size: 16px; color: #00ff00; margin-bottom: 10px; font-weight: bold;") + pixmap = QPixmap("assets/dummy_images/locked_image_dummy.png") + self.enc_display_label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + self.key_text_box.setText("") + except: + QMessageBox.critical(self, "Encrypting error", "Failed to encryp the image") + + def perform_decryption(self, filepath): + dec_filename = None + if filepath is None: + QMessageBox.information(self, "Decrypting Error", "Please select the image first.") + return + if not self.aes_radio_dec.isChecked() and not self.blowfish_radio_dec.isChecked(): + QMessageBox.information(self, "Decrypting Error", "Please select an decryption method.") + return + if self.key_text_box_of_dec.text() == "": + QMessageBox.information(self, "Decrypting Error", "Please enter a secret key") + return + try: + if self.aes_radio_dec.isChecked(): + result, dec_filename = aes.decrypt(filepath, self.key_text_box_of_dec.text()) + if result == -1: + QMessageBox.critical(self, "Decrypting error", "Wrong Key! ") + return + else: + result, dec_filename = blowfish.decrypt(filepath, self.key_text_box_of_dec.text()) + if result == -1: + QMessageBox.critical(self, "Decrypting error", "Wrong Key! ") + return + self.download_dec_button.setEnabled(True) + self.dec_img_text_label.setText("Decrypted!") + self.dec_img_text_label.setStyleSheet( + "font-size: 16px; color: #00ff00; margin-bottom: 10px; font-weight: bold;") + pixmap = QPixmap(dec_filename) + self.dec_display_label.setPixmap(pixmap.scaled(256, 256, Qt.KeepAspectRatio)) + self.key_text_box_of_dec.setText("") + except: + QMessageBox.critical(self, "Decrypting error", "Failed to decrypt the file") + + def logout(self): + dialog = QDialog(self) + dialog.setWindowTitle("Exit") + dialog.setMinimumSize(450, 100) + + layout = QVBoxLayout(dialog) + msg_box = QMessageBox() + msg_box.setText("

Are you sure you want to Exit?

") + + # Set custom font and size + font = QFont("Arial", 12) # Adjust the font and size as desired + msg_box.setFont(font) + + button_layout = QHBoxLayout() + layout.addWidget(msg_box) + layout.addLayout(button_layout) + + # Remove the standard buttons + msg_box.setStandardButtons(QMessageBox.NoButton) + + yes_button = QPushButton("Yes") + yes_button.setStyleSheet("color: #000000;") + yes_button.clicked.connect(lambda: QApplication.quit()) + + no_button = QPushButton("No") + no_button.setStyleSheet("color: #000000;") + no_button.clicked.connect(dialog.reject) + + button_layout.addWidget(yes_button) + button_layout.addWidget(no_button) + + dialog.exec_() + + def load_stylesheet(self): + stylesheet = QFile("styles/style.qss") + if stylesheet.open(QFile.ReadOnly | QFile.Text): + stream = QTextStream(stylesheet) + self.setStyleSheet(stream.readAll()) + + +# Create the application +QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True) +app = QApplication(sys.argv) +window = MainAppWindow() +window.load_stylesheet() +window.show() +sys.exit(app.exec_()) diff --git a/app/ui/styles/style.qss b/app/ui/styles/style.qss new file mode 100644 index 0000000000000000000000000000000000000000..bef67625b4754a382c6265d44e92c1db8a7cf2a4 --- /dev/null +++ b/app/ui/styles/style.qss @@ -0,0 +1,75 @@ +QMainWindow{ + color: white; + background-color: #202123; +} +QPushButton { + position: relative; + padding: 10px 20px; + border-radius: 7px; + border: 1.5px solid #9342ff; + font-size: 12px; + font-weight: 500; + font-family: Oswald, Arial, sans-serif; + letter-spacing: 1px; + + color: #ffffff; + overflow: hidden; + box-shadow: 0 0 0 0 #000000; +} +QPushButton:hover { + background: #9342ff; + box-shadow: 0 0 30px 5px rgba(0, 142, 236, 0.815); + border: 1.5px solid transparent; +} +QRadioButton{ + font-size: 16px; + color: #fae69e; + font-weight: semi-bold; +} +QToolTip { + font-size: 12px; + font-weight: semi-bold; + color: white; + background-color: #2c0067; + border: 1px solid #8b01ff; +} +#logout_button { + color: #ffffff; + padding: 8px 16px; + border-radius: 4px; + font-size: 14px; +} +#logout_button:hover { + background-color: #e81123; + color: #ffffff; + border: 1.5px solid transparent; +} + +#side_navigation{ + background-color: #202123; + padding: 0px 0px; +} +#main_content { + background-color: #444654; + padding: 0px 0px; + border-radius: 12px; +} +#luckyButton { + position: relative; + padding: 22px 20px; + border-radius: 7px; + border: 1.5px solid #9342ff; + font-size: 12px; + font-weight: 500; + font-family: Oswald, Arial, sans-serif; + letter-spacing: 1px; + + color: #ffffff; + overflow: hidden; + box-shadow: 0 0 0 0 #000000; +} +#luckyButton:hover { + background: #33beff; + box-shadow: 0 0 30px 5px rgba(0, 142, 236, 0.815); + border: 1.5px solid transparent; +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..3cf9a67d2b19fc5c8433b19c18add3ec4dfa2337 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,10 @@ +tensorflow +torch +torchvision +opencv-python-headless +Pillow +pycryptodome +gradio +numpy +imageio +requests