Spaces:
Sleeping
Sleeping
Update utils.py
Browse files
utils.py
CHANGED
@@ -116,7 +116,8 @@ class WatermarkProcessor:
|
|
116 |
except Exception as e:
|
117 |
return image_path, f"Error in encoding: {str(e)}"
|
118 |
|
119 |
-
|
|
|
120 |
"""Decode watermark using simple LSB steganography"""
|
121 |
try:
|
122 |
# Try PNG metadata method first
|
@@ -127,72 +128,61 @@ class WatermarkProcessor:
|
|
127 |
except:
|
128 |
pass
|
129 |
|
|
|
130 |
image = cv2.imread(image_path)
|
131 |
if image is None:
|
132 |
raise ValueError("Could not read image file")
|
133 |
|
134 |
-
# Extract
|
135 |
-
|
|
|
136 |
for i in range(image.shape[0]):
|
137 |
for j in range(image.shape[1]):
|
138 |
for k in range(3):
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
|
159 |
except Exception as e:
|
160 |
return f"Error in decoding: {str(e)}"
|
161 |
|
162 |
-
def analyze_quality(self, original_path, watermarked_path):
|
163 |
-
"""Analyze watermark quality"""
|
164 |
-
try:
|
165 |
-
original = cv2.imread(original_path)
|
166 |
-
watermarked = cv2.imread(watermarked_path)
|
167 |
-
|
168 |
-
if original is None or watermarked is None:
|
169 |
-
raise ValueError("Could not read image files")
|
170 |
-
|
171 |
-
# Calculate PSNR
|
172 |
-
mse = np.mean((original - watermarked) ** 2)
|
173 |
-
if mse == 0:
|
174 |
-
psnr = float('inf')
|
175 |
-
else:
|
176 |
-
psnr = 20 * np.log10(255.0 / np.sqrt(mse))
|
177 |
-
|
178 |
-
# Calculate histogram similarity
|
179 |
-
hist_original = cv2.calcHist([original], [0], None, [256], [0, 256])
|
180 |
-
hist_watermarked = cv2.calcHist([watermarked], [0], None, [256], [0, 256])
|
181 |
-
hist_correlation = cv2.compareHist(hist_original, hist_watermarked, cv2.HISTCMP_CORREL)
|
182 |
-
|
183 |
-
# Count modified pixels
|
184 |
-
diff = cv2.bitwise_xor(original, watermarked)
|
185 |
-
modified_pixels = np.count_nonzero(diff)
|
186 |
-
|
187 |
-
report = {
|
188 |
-
'psnr': round(psnr, 2),
|
189 |
-
'histogram_similarity': round(hist_correlation, 4),
|
190 |
-
'modified_pixels': modified_pixels,
|
191 |
-
'image_size': original.shape,
|
192 |
-
'quality_score': round((psnr / 50) * 100, 2) if psnr != float('inf') else 100
|
193 |
-
}
|
194 |
-
|
195 |
-
return json.dumps(report, indent=2)
|
196 |
-
|
197 |
-
except Exception as e:
|
198 |
-
return f"Error in quality analysis: {str(e)}"
|
|
|
116 |
except Exception as e:
|
117 |
return image_path, f"Error in encoding: {str(e)}"
|
118 |
|
119 |
+
|
120 |
+
def decode(self, image_path):
|
121 |
"""Decode watermark using simple LSB steganography"""
|
122 |
try:
|
123 |
# Try PNG metadata method first
|
|
|
128 |
except:
|
129 |
pass
|
130 |
|
131 |
+
# Read image
|
132 |
image = cv2.imread(image_path)
|
133 |
if image is None:
|
134 |
raise ValueError("Could not read image file")
|
135 |
|
136 |
+
# Extract LSB data
|
137 |
+
binary_text = ''
|
138 |
+
# Get LSB from each byte of each pixel
|
139 |
for i in range(image.shape[0]):
|
140 |
for j in range(image.shape[1]):
|
141 |
for k in range(3):
|
142 |
+
bit = image[i, j, k] & 1
|
143 |
+
binary_text += str(bit)
|
144 |
+
|
145 |
+
# Convert binary to text
|
146 |
+
text = ''
|
147 |
+
# Process 8 bits at a time
|
148 |
+
for i in range(0, len(binary_text)-8, 8):
|
149 |
+
byte = binary_text[i:i+8]
|
150 |
+
text += chr(int(byte, 2))
|
151 |
+
# Check for end marker
|
152 |
+
if text[-7:] == "###END###":
|
153 |
+
extracted_text = text[:-7]
|
154 |
+
try:
|
155 |
+
# Attempt to parse as JSON
|
156 |
+
data = json.loads(extracted_text)
|
157 |
+
return json.dumps(data, ensure_ascii=False, indent=2)
|
158 |
+
except:
|
159 |
+
# If not valid JSON, return as plain text
|
160 |
+
return extracted_text.strip()
|
161 |
+
|
162 |
+
# If we got here, try to find any valid JSON in the text
|
163 |
+
try:
|
164 |
+
# Convert remaining bits
|
165 |
+
for i in range(0, len(binary_text), 8):
|
166 |
+
if i + 8 <= len(binary_text):
|
167 |
+
byte = binary_text[i:i+8]
|
168 |
+
text += chr(int(byte, 2))
|
169 |
+
|
170 |
+
# Look for JSON markers
|
171 |
+
start = text.find('{')
|
172 |
+
end = text.rfind('}')
|
173 |
+
if start != -1 and end != -1:
|
174 |
+
json_text = text[start:end+1]
|
175 |
+
try:
|
176 |
+
data = json.loads(json_text)
|
177 |
+
return json.dumps(data, ensure_ascii=False, indent=2)
|
178 |
+
except:
|
179 |
+
pass
|
180 |
+
|
181 |
+
except:
|
182 |
+
pass
|
183 |
+
|
184 |
+
return text if text.strip() else "Error: No valid watermark found"
|
185 |
|
186 |
except Exception as e:
|
187 |
return f"Error in decoding: {str(e)}"
|
188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|