Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions ai_model/output/flip_pixel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
from PIL import Image
import numpy as np


def flip_random_pixels(image_path, output_path, flip_percentage=0.001):
# Open the image
img = Image.open(image_path)
img = img.convert('RGB') # Ensure it's in RGB format
img = img.convert("RGB") # Ensure it's in RGB format

# Convert image to numpy array for pixel manipulation
img_array = np.array(img)
Expand All @@ -30,4 +31,4 @@ def flip_random_pixels(image_path, output_path, flip_percentage=0.001):

# Save the new image
flipped_img.save(output_path)
print(f"Saved flipped image at {output_path}")
print(f"Saved flipped image at {output_path}")
117 changes: 117 additions & 0 deletions ai_model/output/mitm_attack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import os
import numpy as np
from PIL import Image
import torch
from torchvision import transforms
import torchvision.models as models
from art.attacks.evasion import MomentumIterativeMethod
from art.estimators.classification import PyTorchClassifier
import torch.nn as nn

from res import evaluate_image


def denormalize(tensor, mean, std):
mean = torch.tensor(mean).view(1, -1, 1, 1).to(tensor.device)
std = torch.tensor(std).view(1, -1, 1, 1).to(tensor.device)
tensor = tensor * std + mean
return tensor


def protect_image_mitm(
image_path, output_folder, target_class_idx=1, level_count=5, current_count=0
):
try:
org_id, org_prob = evaluate_image(image_path)
# Load the image without resizing or cropping to retain aspect ratio
image = Image.open(image_path).convert("RGB")
# Preprocess the image without resizing
preprocess = transforms.Compose(
[
transforms.ToTensor(),
transforms.Normalize(
mean=[0.485, 0.456, 0.406], # ResNet50 mean
std=[0.229, 0.224, 0.225], # ResNet50 std
),
]
)
input_tensor = preprocess(image)
input_batch = input_tensor.unsqueeze(0) # Add batch dimension

# Move input to device
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
input_batch = input_batch.to(device)

# Get input shape (channels, height, width)
_, channels, height, width = input_batch.shape

# Load pre-trained ResNet50 model
model_pytorch = models.resnet50(pretrained=True)
model_pytorch.eval()
model_pytorch = model_pytorch.to(device)

# Define loss function
loss_fn = nn.CrossEntropyLoss()

# Create PyTorchClassifier with variable input shape
classifier = PyTorchClassifier(
model=model_pytorch,
loss=loss_fn,
input_shape=(channels, height, width),
nb_classes=1000,
preprocessing=(0, 1),
clip_values=(0, 1),
)

# Create target label (as numpy array)
target_label = np.array([target_class_idx])

# Create the Momentum Iterative Method attack
attack = MomentumIterativeMethod(
estimator=classifier,
eps=0.15, # Total perturbation (adjust as needed)
eps_step=0.01, # Step size per iteration
max_iter=200, # Number of iterations
targeted=True,
)

# Apply adversarial perturbation
adversarial_image = attack.generate(x=input_batch.cpu().numpy(), y=target_label)

# Convert adversarial image back to tensor
adversarial_image_tensor = torch.from_numpy(adversarial_image[0]).to(device)

# Denormalize the image
mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
adversarial_image_tensor = denormalize(
adversarial_image_tensor.unsqueeze(0), mean, std
)
adversarial_image_tensor = torch.clamp(adversarial_image_tensor, 0, 1)
adversarial_image_tensor = adversarial_image_tensor.squeeze(0)

# Move to CPU and convert to PIL Image
adversarial_image_tensor = adversarial_image_tensor.cpu()
adversarial_pil = transforms.ToPILImage()(adversarial_image_tensor)

# Save the adversarial image
# filename = os.path.basename(image_path)
# output_path = os.path.join(output_folder, filename)
adversarial_pil.save(output_folder)
current_id, current_prob = evaluate_image(output_folder)
if current_id != org_id or current_count > level_count:
print("The image is protected")
print(current_id)
print(current_prob)
return current_id, current_prob
else:
print("Current Probability: ", current_id)
print("Current Probability: ", current_prob)
print("Original Probability: ", org_prob)
current_count += 1
return protect_image_mitm(
image_path, output_folder, level_count, current_count
)
except Exception as e:
print(f"Error processing image {image_path}: {e}")
return None
17 changes: 11 additions & 6 deletions ai_model/output/object_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,32 @@
from PIL import Image
import requests
import sys


def detect_object(image_path):
image = image_path

# you can specify the revision tag if you don't want the timm dependency
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50", revision="no_timm")
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50", revision="no_timm")
processor = DetrImageProcessor.from_pretrained(
"facebook/detr-resnet-50", revision="no_timm"
)
model = DetrForObjectDetection.from_pretrained(
"facebook/detr-resnet-50", revision="no_timm"
)

inputs = processor(images=image, return_tensors="pt")
outputs = model(**inputs)

# convert outputs (bounding boxes and class logits) to COCO API
# let's only keep detections with score > 0.9
target_sizes = torch.tensor([image.size[::-1]])
results = processor.post_process_object_detection(outputs, target_sizes=target_sizes, threshold=0.9)[0]
results = processor.post_process_object_detection(
outputs, target_sizes=target_sizes, threshold=0.9
)[0]

if len(results["boxes"]) > 0:
first_box = results["boxes"][0].tolist()
first_box = [round(i, 2) for i in first_box]
return first_box
else:
return None



36 changes: 36 additions & 0 deletions ai_model/output/pixel_flipper/checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import sys
import torch
# model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet18', pretrained=True)
# model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet34', pretrained=True)
# model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet101', pretrained=True)
# model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet152', pretrained=True)

from PIL import Image
from torchvision import transforms

model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet152', pretrained=True)
model.eval()


def evaluate_image(filename):
input_image = filename
preprocess = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
input_tensor = preprocess(input_image)
input_batch = input_tensor.unsqueeze(0) # create a mini-batch as expected by the model

with torch.no_grad():
output = model(input_batch)
probabilities = torch.nn.functional.softmax(output[0], dim=0)

# Read the categories
with open("imagenet_classes.txt", "r") as f:
categories = [s.strip() for s in f.readlines()]
# Show top categories per image
topx_prob, topx_catid = torch.topk(probabilities, 1)
for i in range(topx_prob.size(0)):
return topx_catid, topx_prob
36 changes: 36 additions & 0 deletions ai_model/output/pixel_flipper/convince.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from checker import evaluate_image
from pixel_manipulate import flip_random_pixels
import sys
from PIL import Image
import torch

x = 0
y = 0

original_file = Image.open(sys.argv[1], "r")
prev_file = original_file
next_file = original_file

# Round 1 - find and store initial classification
orig_cat_id, orig_score = evaluate_image(original_file)
with open("imagenet_classes.txt", "r") as f:
categories = [s.strip() for s in f.readlines()]
print(categories[orig_cat_id], orig_score.item())

cur_cat_id = orig_cat_id
prev_score = orig_score
new_score = orig_score

while orig_cat_id == cur_cat_id:
#while new_score > float(orig_score.item()):
next_file = flip_random_pixels(prev_file)
print(x, y)
cur_cat_id, new_score = evaluate_image(next_file)
print("New score: " + str(new_score.item()) + " Old score: " + str(prev_score.item()))
if new_score.item() > prev_score.item():
next_file = prev_file
else:
prev_score = new_score

print("New category: " + categories[cur_cat_id])
next_file.save("Output.jpg")
32 changes: 32 additions & 0 deletions ai_model/output/pixel_flipper/pixel_manipulate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import random
from PIL import Image
import numpy as np


def flip_random_pixels(img, flip_percentage=0.01):
# Open the image
img = img.convert('RGB') # Ensure it's in RGB format

# Convert image to numpy array for pixel manipulation
img_array = np.array(img)

# Get image dimensions
height, width, _ = img_array.shape
num_pixels = height * width

# Determine number of pixels to flip
num_flips = int(num_pixels * flip_percentage)

# Randomly select pixels and flip them
for _ in range(num_flips):
x = random.randint(0, width - 1)
y = random.randint(0, height - 1)

# Flip pixel values by inverting the RGB channels (255 - value)
img_array[y, x] = 255 - img_array[y, x]

# Convert the numpy array back to an image
flipped_img = Image.fromarray(img_array)

# Save the new image
return flipped_img
35 changes: 22 additions & 13 deletions ai_model/output/poison_image.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import os
import numpy as np
from PIL import Image
from art.attacks.evasion import ProjectedGradientDescent, DeepFool, SaliencyMapMethod, UniversalPerturbation, MomentumIterativeMethod
from art.attacks.evasion import (
ProjectedGradientDescent,
DeepFool,
SaliencyMapMethod,
UniversalPerturbation,
MomentumIterativeMethod,
)
from art.estimators.classification import TensorFlowV2Classifier
from res import evaluate_image
import tensorflow as tf


def protect_image(image_path, output_folder, level_count=40, current_count=0):
def protect_image(image_path, output_folder, level_count=5, current_count=0):
# Load and preprocess image
org_id, org_prob = evaluate_image(image_path)
image = Image.open(image_path).convert('RGB')
image = Image.open(image_path).convert("RGB")

# Resize image to 224x224 to match ResNet50's input size
image = image.resize((224, 224))
Expand All @@ -22,21 +28,23 @@ def protect_image(image_path, output_folder, level_count=40, current_count=0):
image_np = np.expand_dims(image_np, axis=0)

# Load pretrained ResNet50 model
model = tf.keras.applications.ResNet50(weights='imagenet', input_shape=(224, 224, 3))
model = tf.keras.applications.ResNet50(
weights="imagenet", input_shape=(224, 224, 3)
)

# Wrap the model for ART (Adversarial Robustness Toolbox)
classifier = TensorFlowV2Classifier(
model=model,
nb_classes=1000,
input_shape=(224, 224, 3),
loss_object=tf.keras.losses.CategoricalCrossentropy()
loss_object=tf.keras.losses.CategoricalCrossentropy(),
)

# Create a stronger PGD attack method
attack = DeepFool(
classifier=classifier,
max_iter=1000, # Increased iterations
epsilon=1e-2 # Increased step size for stronger perturbations
epsilon=1e-2, # Increased step size for stronger perturbations
)

output_path = perform_attack(attack, output_folder, image_np)
Expand All @@ -54,12 +62,13 @@ def protect_image(image_path, output_folder, level_count=40, current_count=0):
current_count += 1
return protect_image(output_path, output_folder, level_count, current_count)

def perform_attack(attack, output_folder,image_np):
adversarial_image = attack.generate(x=image_np)

def perform_attack(attack, output_folder, image_np):
adversarial_image = attack.generate(x=image_np)

# Postprocess and save image
adversarial_image = np.squeeze(adversarial_image) * 255.0
adversarial_image = np.clip(adversarial_image, 0, 255).astype(np.uint8)
adversarial_pil = Image.fromarray(adversarial_image)
adversarial_pil.save(output_folder)
return output_folder
adversarial_image = np.squeeze(adversarial_image) * 255.0
adversarial_image = np.clip(adversarial_image, 0, 255).astype(np.uint8)
adversarial_pil = Image.fromarray(adversarial_image)
adversarial_pil.save(output_folder)
return output_folder
Loading