aegishield commited on
Commit
6ea830d
·
1 Parent(s): 950c91f
Files changed (1) hide show
  1. app.py +37 -26
app.py CHANGED
@@ -3,56 +3,67 @@ import numpy as np
3
  import cv2
4
  from PIL import Image
5
 
6
- # Load HED model (must be uploaded in the repo)
7
  HED_NET = cv2.dnn.readNetFromCaffe("deploy.prototxt", "hed_pretrained_bsds.caffemodel")
8
 
9
- # Main extraction logic
10
- def extract_secret_from_stego(stego_image: Image.Image, secret_shape=(128, 128), edge_method="HED", x=2, y=1):
11
- stego_np = np.array(stego_image.convert("RGB"))
12
-
13
- # Edge detection
14
- if edge_method == "HED":
15
- inp = cv2.dnn.blobFromImage(stego_np, scalefactor=1.0, size=(256, 256),
16
  mean=(104.00698793, 116.66876762, 122.67891434),
17
  swapRB=False, crop=False)
18
  HED_NET.setInput(inp)
19
  edges = HED_NET.forward()[0, 0]
20
- edge_mask = cv2.resize(edges, (stego_np.shape[1], stego_np.shape[0])) > np.mean(edges)
21
- elif edge_method == "Canny":
22
- gray = cv2.cvtColor(stego_np, cv2.COLOR_RGB2GRAY)
23
- edge_mask = cv2.Canny(gray, 100, 200) > 0
 
 
24
  else:
25
- raise ValueError("Unsupported edge detection method")
26
 
27
- # Bit extraction
28
- secret_bits_len = np.prod(secret_shape) * 8
29
- height, width, channels = stego_np.shape
30
  extracted_bits = []
31
  bit_index = 0
32
 
33
  for i in range(height):
34
  for j in range(width):
35
  for c in range(channels):
36
- if bit_index >= secret_bits_len:
37
  break
38
  n = x if edge_mask[i, j] else y
39
- value = stego_np[i, j, c] & ((1 << n) - 1)
40
  for b in range(n):
41
  extracted_bits.append((value >> b) & 1)
42
  bit_index += n
43
- if bit_index >= secret_bits_len:
44
  break
45
- if bit_index >= secret_bits_len:
46
  break
47
 
48
- extracted_bits = np.array(extracted_bits[:secret_bits_len], dtype=np.uint8)
49
- recovered_array = np.packbits(extracted_bits).reshape(secret_shape)
50
 
51
- return Image.fromarray(recovered_array.astype(np.uint8), mode='L')
 
 
 
 
52
 
53
  # Gradio interface function
54
  def extract_interface(stego_img, edge_method):
55
- return extract_secret_from_stego(stego_img, secret_shape=(128, 128), edge_method=edge_method)
 
 
 
 
 
 
 
 
 
56
 
57
  # Launch app
58
  gr.Interface(
@@ -63,5 +74,5 @@ gr.Interface(
63
  ],
64
  outputs=gr.Image(label="Extracted Palmprint (128×128 grayscale)"),
65
  title="Palmprint Extractor from Stego Image",
66
- description="Upload a stego image and select the edge detection method used during embedding. This will extract a 128×128 grayscale palmprint."
67
- ).launch()
 
3
  import cv2
4
  from PIL import Image
5
 
6
+ # Load HED model
7
  HED_NET = cv2.dnn.readNetFromCaffe("deploy.prototxt", "hed_pretrained_bsds.caffemodel")
8
 
9
+ # Edge detection
10
+ def detect_edges(image_np, method):
11
+ if method == "HED":
12
+ inp = cv2.dnn.blobFromImage(image_np, scalefactor=1.0, size=(256, 256),
 
 
 
13
  mean=(104.00698793, 116.66876762, 122.67891434),
14
  swapRB=False, crop=False)
15
  HED_NET.setInput(inp)
16
  edges = HED_NET.forward()[0, 0]
17
+ edges = cv2.resize(edges, (image_np.shape[1], image_np.shape[0]))
18
+ return edges > np.mean(edges)
19
+ elif method == "Canny":
20
+ gray = cv2.cvtColor(image_np, cv2.COLOR_RGB2GRAY)
21
+ edges = cv2.Canny(gray, 100, 200)
22
+ return edges > 0
23
  else:
24
+ raise ValueError("Invalid edge method")
25
 
26
+ # LSB extraction
27
+ def extract_lsb(stego_pixels, edge_mask, secret_bits_length, x=2, y=1):
28
+ height, width, channels = stego_pixels.shape
29
  extracted_bits = []
30
  bit_index = 0
31
 
32
  for i in range(height):
33
  for j in range(width):
34
  for c in range(channels):
35
+ if bit_index >= secret_bits_length:
36
  break
37
  n = x if edge_mask[i, j] else y
38
+ value = stego_pixels[i, j, c] & ((1 << n) - 1)
39
  for b in range(n):
40
  extracted_bits.append((value >> b) & 1)
41
  bit_index += n
42
+ if bit_index >= secret_bits_length:
43
  break
44
+ if bit_index >= secret_bits_length:
45
  break
46
 
47
+ return np.array(extracted_bits[:secret_bits_length], dtype=np.uint8)
 
48
 
49
+ # Convert bits to image
50
+ def from_bit_array(bit_array, shape):
51
+ expected_bits = np.prod(shape) * 8
52
+ bit_array = bit_array[:expected_bits]
53
+ return np.packbits(bit_array).reshape(shape)
54
 
55
  # Gradio interface function
56
  def extract_interface(stego_img, edge_method):
57
+ secret_shape = (128, 128) # Must match embedding shape
58
+ stego_np = np.array(stego_img.convert("RGB"))
59
+
60
+ edge_mask = detect_edges(stego_np, edge_method)
61
+ secret_bits_len = np.prod(secret_shape) * 8
62
+
63
+ extracted_bits = extract_lsb(stego_np, edge_mask, secret_bits_len, x=2, y=1)
64
+ recovered = from_bit_array(extracted_bits, secret_shape)
65
+
66
+ return Image.fromarray(recovered.astype(np.uint8), mode='L')
67
 
68
  # Launch app
69
  gr.Interface(
 
74
  ],
75
  outputs=gr.Image(label="Extracted Palmprint (128×128 grayscale)"),
76
  title="Palmprint Extractor from Stego Image",
77
+ description="Upload the stego image and choose the same edge detection method used in embedding. The system will extract a 128×128 grayscale palmprint."
78
+ ).launch()