3morrrrr commited on
Commit
8870779
·
verified ·
1 Parent(s): cfd0c4a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +46 -67
app.py CHANGED
@@ -2,8 +2,6 @@ import gradio as gr
2
  import logging
3
  from roboflow import Roboflow
4
  from PIL import Image, ImageDraw, ImageFont, ImageFilter
5
- import cv2
6
- import numpy as np
7
  import os
8
 
9
  # Configure logging
@@ -22,7 +20,7 @@ PROJECT_NAME = "model_verification_project"
22
  VERSION_NUMBER = 2
23
  FONT_PATH = "./STEVEHANDWRITING-REGULAR.TTF"
24
 
25
- # Function to process image and overlay text with perspective alignment
26
  def process_image(image, text):
27
  try:
28
  # Initialize Roboflow
@@ -39,92 +37,73 @@ def process_image(image, text):
39
  prediction = model.predict(input_image_path, confidence=70, overlap=50).json()
40
  logging.debug(f"Inference result: {prediction}")
41
 
42
- # Convert PIL image to OpenCV format
43
- image_cv = cv2.cvtColor(np.array(image), cv2.COLOR_RGBA2BGRA)
44
 
 
45
  for obj in prediction['predictions']:
46
- # Extract bounding box coordinates
47
- x_center, y_center = int(obj['x']), int(obj['y'])
48
- width, height = int(obj['width']), int(obj['height'])
49
-
50
- # Define the four corners of the detected paper
51
- corners = [
52
- [x_center - width // 2, y_center - height // 2], # Top-left
53
- [x_center + width // 2, y_center - height // 2], # Top-right
54
- [x_center + width // 2, y_center + height // 2], # Bottom-right
55
- [x_center - width // 2, y_center + height // 2], # Bottom-left
56
- ]
57
-
58
- # Approximate a perspective transformation matrix
59
- dst_corners = [
60
- [0, 0], # Top-left in the new perspective
61
- [width, 0], # Top-right
62
- [width, height], # Bottom-right
63
- [0, height], # Bottom-left
64
- ]
65
- matrix = cv2.getPerspectiveTransform(np.float32(corners), np.float32(dst_corners))
66
-
67
- # Warp the detected region
68
- warped = cv2.warpPerspective(image_cv, matrix, (width, height))
69
-
70
- # Draw text on the warped region
71
- pil_warped = Image.fromarray(cv2.cvtColor(warped, cv2.COLOR_BGRA2RGBA))
72
- draw = ImageDraw.Draw(pil_warped)
73
-
74
- # Calculate dynamic font size and adjust for multi-line text
75
- font_size = max(10, int(height * 0.2)) # Adjust size relative to height
76
  try:
77
- font = ImageFont.truetype(FONT_PATH, size=font_size)
78
- logging.debug(f"Font loaded successfully: {FONT_PATH} with size {font_size}")
79
  except Exception as e:
80
  logging.warning(f"Error loading font. Using default. {e}")
81
  font = ImageFont.load_default()
82
 
83
- # Split text into multiple lines to fit within the bounding box
 
 
 
 
 
 
 
 
84
  words = text.split()
85
  lines = []
86
  current_line = ""
 
87
  for word in words:
88
  test_line = f"{current_line} {word}".strip()
89
- bbox = draw.textbbox((0, 0), test_line, font=font)
90
- if bbox[2] - bbox[0] <= width:
91
  current_line = test_line
92
  else:
93
  lines.append(current_line)
94
  current_line = word
 
95
  if current_line:
96
  lines.append(current_line)
97
 
98
  # Draw each line of text within the bounding box
99
- line_height = draw.textbbox((0, 0), "Ag", font=font)[3] - draw.textbbox((0, 0), "Ag", font=font)[1]
100
- start_y = (height - line_height * len(lines)) // 2
 
 
 
 
101
  for i, line in enumerate(lines):
102
- text_width = draw.textbbox((0, 0), line, font=font)[2] - draw.textbbox((0, 0), line, font=font)[0]
103
- text_x = (width - text_width) // 2
104
- text_y = start_y + i * line_height
105
- draw.text((text_x, text_y), line, fill=(0, 0, 0, 255), font=font)
106
-
107
- # Convert back to OpenCV and reapply the perspective transformation
108
- warped_with_text = cv2.cvtColor(np.array(pil_warped), cv2.COLOR_RGBA2BGRA)
109
- matrix_back = cv2.getPerspectiveTransform(np.float32(dst_corners), np.float32(corners))
110
- logging.debug(f"Inverse Transformation Matrix: {matrix_back}")
111
-
112
- transformed_back = cv2.warpPerspective(
113
- warped_with_text, matrix_back,
114
- (image_cv.shape[1], image_cv.shape[0]),
115
- flags=cv2.WARP_INVERSE_MAP,
116
- )
117
-
118
- # Overlay the transformed text onto the original image
119
- mask = transformed_back[:, :, 3] > 0 # Alpha channel as mask
120
- logging.debug(f"Alpha mask shape: {mask.shape}, Non-zero values: {np.count_nonzero(mask)}")
121
-
122
- image_cv[mask] = transformed_back[mask]
123
-
124
- # Convert back to PIL format and save
125
- output_image = Image.fromarray(cv2.cvtColor(image_cv, cv2.COLOR_BGRA2RGBA))
126
  output_image_path = "/tmp/output_image.png"
127
- output_image.save(output_image_path)
128
  return output_image_path
129
 
130
  except Exception as e:
 
2
  import logging
3
  from roboflow import Roboflow
4
  from PIL import Image, ImageDraw, ImageFont, ImageFilter
 
 
5
  import os
6
 
7
  # Configure logging
 
20
  VERSION_NUMBER = 2
21
  FONT_PATH = "./STEVEHANDWRITING-REGULAR.TTF"
22
 
23
+ # Function to process image and overlay text
24
  def process_image(image, text):
25
  try:
26
  # Initialize Roboflow
 
37
  prediction = model.predict(input_image_path, confidence=70, overlap=50).json()
38
  logging.debug(f"Inference result: {prediction}")
39
 
40
+ # Open the image for processing
41
+ pil_image = image.convert("RGBA")
42
 
43
+ # Iterate over detected objects
44
  for obj in prediction['predictions']:
45
+ x1 = int(obj['x'] - obj['width'] / 2)
46
+ y1 = int(obj['y'] - obj['height'] / 2)
47
+ x2 = int(obj['x'] + obj['width'] / 2)
48
+ y2 = int(obj['y'] + obj['height'] / 2)
49
+
50
+ # Calculate bounding box dimensions
51
+ box_width = x2 - x1
52
+ box_height = y2 - y1
53
+
54
+ # Load font
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  try:
56
+ font = ImageFont.truetype(FONT_PATH, size=20) # Set a base font size
 
57
  except Exception as e:
58
  logging.warning(f"Error loading font. Using default. {e}")
59
  font = ImageFont.load_default()
60
 
61
+ # Ensure pil_image is in RGBA mode
62
+ if pil_image.mode != "RGBA":
63
+ pil_image = pil_image.convert("RGBA")
64
+
65
+ # Create a transparent text layer
66
+ text_layer = Image.new("RGBA", pil_image.size, (255, 255, 255, 0))
67
+ text_draw = ImageDraw.Draw(text_layer)
68
+
69
+ # Split text into lines to fit within the bounding box
70
  words = text.split()
71
  lines = []
72
  current_line = ""
73
+
74
  for word in words:
75
  test_line = f"{current_line} {word}".strip()
76
+ bbox = text_draw.textbbox((0, 0), test_line, font=font)
77
+ if bbox[2] - bbox[0] <= box_width: # Check if text fits
78
  current_line = test_line
79
  else:
80
  lines.append(current_line)
81
  current_line = word
82
+
83
  if current_line:
84
  lines.append(current_line)
85
 
86
  # Draw each line of text within the bounding box
87
+ line_height = font.getsize("Hg")[1]
88
+ total_text_height = len(lines) * line_height
89
+
90
+ if total_text_height > box_height:
91
+ logging.warning("Text exceeds bounding box height and may be clipped.")
92
+
93
  for i, line in enumerate(lines):
94
+ text_x = x1 + (box_width - text_draw.textbbox((0, 0), line, font=font)[2]) // 2
95
+ text_y = y1 + (i * line_height)
96
+ text_draw.text((text_x, text_y), line, fill=(0, 0, 0, 180), font=font)
97
+
98
+ # Apply slight blur to the text layer
99
+ blurred_text_layer = text_layer.filter(ImageFilter.GaussianBlur(radius=1.0))
100
+
101
+ # Composite the blurred text onto the original image
102
+ pil_image = Image.alpha_composite(pil_image, blurred_text_layer)
103
+
104
+ # Save and return output image path
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  output_image_path = "/tmp/output_image.png"
106
+ pil_image.convert("RGB").save(output_image_path)
107
  return output_image_path
108
 
109
  except Exception as e: