broyang commited on
Commit
0232a5d
1 Parent(s): 0a788e8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +205 -8
app.py CHANGED
@@ -1,14 +1,211 @@
1
- import gradio as gr
 
2
  import cv2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
- def process_image(pic):
5
- img_array = cv2.cvtColor(pic, cv2.COLOR_BGR2RGB)
 
 
6
  blurred = cv2.GaussianBlur(img_array, (7, 7), 0)
7
- edges = cv2.Canny(blurred, 90, 120)
8
- structuring_element = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
9
  dilated_edges = cv2.dilate(edges, structuring_element, iterations=1)
10
- dilated_edges = 255 - dilated_edges
11
- return dilated_edges
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
- demo = gr.Interface(process_image, gr.Image(), "image")
 
 
 
 
14
  demo.queue(concurrency_count=10).launch()
 
 
1
+ import sys
2
+ import os
3
  import cv2
4
+ import numpy as np
5
+ import math
6
+ from PIL import Image, ImageDraw, ImageFont, ImageOps
7
+ Image.MAX_IMAGE_PIXELS = None
8
+ import gradio as gr
9
+
10
+ if len(sys.argv) > 1:
11
+ res_path = sys.argv[1]
12
+ else:
13
+ res_path = "C:/3DM/longcrash"
14
+
15
+ def get_exif(image_path):
16
+ try:
17
+ with Image.open(image_path) as img:
18
+ exif_data = img.getexif()
19
+ # print(exif_data)
20
+ if not exif_data:
21
+ return None, None, None
22
+ if "Local Coordinates (m)" in exif_data[34737]:
23
+ return None, None, None
24
+ pixel_scale = exif_data[33550] # Tag ID for PixelScale
25
+ model_tie_point = exif_data[33922] # Tag ID for ModelTiePoint
26
+ pixel_scale_x, pixel_scale_y, _ = pixel_scale
27
+ _, _, _, _, latitude, _ = model_tie_point
28
+ return pixel_scale_x, pixel_scale_y, latitude
29
+ except Exception as e:
30
+ print(f"Error extracting metadata: {e}")
31
+ return None, None, None
32
+
33
+ def pixel_size_in_feet(x_scale_degrees, latitude):
34
+ meters_per_degree_lat = 111320 # Average meters per degree of latitude
35
+ meters_per_degree_lon = meters_per_degree_lat * math.cos(math.radians(latitude))
36
+ pixel_size_x_feet = x_scale_degrees * meters_per_degree_lon * 3.28084
37
+ return pixel_size_x_feet
38
+
39
+ def feet_per_inch(dpi, pixel_size_x_feet):
40
+ # Calculate the number of pixels in 1 inch
41
+ pixels_per_inch = dpi
42
+ # Calculate the number of feet in 1 inch
43
+ feet_per_inch = pixels_per_inch * pixel_size_x_feet
44
+ return feet_per_inch
45
+
46
+ def nearest_number(n):
47
+ numbers = [1, 5, 10, 20, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
48
+ return min(numbers, key=lambda x: abs(x - n))
49
+
50
+ def calculate_dpi(x_scale_degrees, latitude):
51
+ pixel_size_x_feet = pixel_size_in_feet(x_scale_degrees, latitude)
52
+ pixel_size_x_inches = pixel_size_x_feet / 12
53
+ dpi = 1 / pixel_size_x_inches
54
+
55
+ return dpi
56
+
57
+ def add_white_space(img):
58
+ _, height_px = img.size
59
+ bottom_space = int(height_px * 0.2) # Calculate the size of the bottom space
60
+ top_space = int(height_px * 0.1) # Calculate the size of the top space
61
+ new_height_px = int(height_px + bottom_space + top_space)
62
+ img = ImageOps.expand(img, border=(0, top_space, 0, bottom_space), fill='white')
63
+ return img, new_height_px
64
+
65
+ def add_white_space_right(img):
66
+ width_px, height_px = img.size
67
+ right_space = int(width_px * 0.3) # Calculate the size of the right space
68
+ left_space = int(width_px * 0.1) # Calculate the size of the left space
69
+ new_width_px = int(width_px + right_space)
70
+ img = ImageOps.expand(img, border=(0, 0, right_space, 0), fill='white')
71
+ return img
72
+
73
+ def draw_scale_bar(right_img, exif_data, compass, line_img, paste_x_position, paste_y_position):
74
+ pixel_scale_x = exif_data[0]
75
+ pixel_scale_y = exif_data[1]
76
+ latitude = exif_data[2]
77
+ if pixel_scale_x is None or pixel_scale_y is None or latitude is None:
78
+ return
79
+ # Calculate pixel size in feet
80
+ pixel_size_x = pixel_size_in_feet(pixel_scale_x, latitude)
81
+ image_width_feet = round(line_img.width * pixel_size_x)
82
+ scale_max = nearest_number(image_width_feet / 5)
83
+ # Calculate scale bar dimensions
84
+ scale_bar_width_px = int(line_img.width * (scale_max / image_width_feet))
85
+ scale_bar_height_px = int(scale_bar_width_px * 0.08)
86
+ # x_position = int(right_img.width * 0.90 - scale_bar_width_px) # Adjusted for 5% from the right
87
+ x_position = paste_x_position
88
+ y_position = int(right_img.height - (right_img.height - paste_y_position - scale_bar_height_px) * 2) # Adjusted for new height
89
+ font_size = int(scale_bar_width_px * 0.1)
90
+ # Draw scale bar
91
+ draw = ImageDraw.Draw(right_img)
92
+ try:
93
+ font = ImageFont.truetype("Arial Unicode.ttf", font_size)
94
+ print("arial.ttf")
95
+ except IOError:
96
+ font = ImageFont.load_default()
97
+ print("default")
98
+ section_width = scale_bar_width_px / 4
99
+ section_x_position = x_position - 1 * section_width #base 0 incremental position
100
+ text_position = (section_x_position + section_width - font_size / 4, y_position - font_size - 20)
101
+ draw.text(text_position, "0", fill="black", font=font)
102
+ for i in range(4): #other incremental positions
103
+ section_x_position = x_position + i * section_width
104
+ fill_color = "black" if i % 2 == 0 else "white"
105
+ draw.rectangle([section_x_position, y_position, section_x_position + section_width, y_position + scale_bar_height_px], fill=fill_color)
106
+ text = str(round(scale_max / 4 * (i + 1), 2))
107
+ if text.endswith('.0'):
108
+ text = text.rstrip('0').rstrip('.')
109
+ if i == 3:
110
+ text += " feet"
111
+ text_position = (section_x_position + section_width - font_size / 4, y_position - font_size - 20)
112
+ draw.text(text_position, text, fill="black", font=font)
113
+
114
+ # Draw outline around scale bar
115
+ outline_width = 3
116
+ draw.line([(x_position, y_position), (x_position + scale_bar_width_px, y_position)], fill="black", width=outline_width)
117
+ draw.line([(x_position, y_position), (x_position, y_position + scale_bar_height_px)], fill="black", width=outline_width)
118
+ draw.line([(x_position + scale_bar_width_px, y_position), (x_position + scale_bar_width_px, y_position + scale_bar_height_px)], fill="black", width=outline_width)
119
+ draw.line([(x_position, y_position + scale_bar_height_px), (x_position + scale_bar_width_px, y_position + scale_bar_height_px)], fill="black", width=outline_width)
120
+
121
+ #feet per inch
122
+ try:
123
+ font = ImageFont.truetype("Arial Unicode.ttf", int(font_size * 1.3))
124
+ except IOError:
125
+ font = ImageFont.load_default()
126
+ dpi = calculate_dpi(pixel_scale_x, latitude)
127
+ dpi = 96
128
+ fpi = round(feet_per_inch(dpi, pixel_size_x), 2)
129
+ feet_per_inch_text = '1" = ' + str(fpi) + ' feet'
130
+ paste_y_position = int(right_img.height - (right_img.height - paste_y_position - scale_bar_height_px) * 3)
131
+ text_position = (x_position, paste_y_position)
132
+ # text_position = (x_position, y_position - font_size - 200)
133
+ draw.text(text_position, feet_per_inch_text, fill='black', font=font)
134
+
135
+ # # Add in a small compass
136
+ compass = compass.convert("RGBA")
137
+ new_compass_width = int(right_img.width * 0.05)
138
+ compass_ratio = new_compass_width / compass.width
139
+ new_compass_height = int(compass.height * compass_ratio)
140
+ compass = compass.resize((new_compass_width, new_compass_height))
141
+ # Paste the compass in the top right of the image with 5% margin
142
+ paste_compass_x_position = int(right_img.width - (right_img.width + new_compass_width * 2 - paste_x_position) / 2)
143
+ # paste_compass_x_position = int(right_img.width * 0.05)
144
+ paste_compass_y_position = int(right_img.height * 0.05) # 5% margin on the top
145
+ right_img.paste(compass, (paste_compass_x_position, paste_compass_y_position), compass)
146
+ return right_img
147
+
148
+ def watermark(right_img, sb_logo, line_img):
149
+ sb_logo = sb_logo.convert("RGBA")
150
+ new_logo_width = int(line_img.width * 0.2)
151
+ logo_ratio = new_logo_width / sb_logo.width
152
+ new_logo_height = int(sb_logo.height * logo_ratio)
153
+ sb_logo = sb_logo.resize((new_logo_width, new_logo_height))
154
+ # Calculate the position for the logo to be 5% from the right
155
+ paste_x_position = int(right_img.width * 0.95 - new_logo_width)
156
+ paste_y_position = int(right_img.height * 0.95 - new_logo_height)#new_height_px - new_logo_height - int(bottom_space / 4)
157
+ right_img.paste(sb_logo, (paste_x_position, paste_y_position), sb_logo)
158
+ return right_img, paste_x_position, paste_y_position
159
+
160
+ def freemium_watermark(img, sb_logo):
161
+ width_px, height_px = img.size
162
+ # Convert the logo to "RGBA" mode and resize it to 80% of the image width
163
+ sb_logo = sb_logo.convert("RGBA")
164
+ new_logo_width = int(width_px * 0.8) # 80% of the image width
165
+ logo_ratio = new_logo_width / sb_logo.width
166
+ new_logo_height = int(sb_logo.height * logo_ratio)
167
+ sb_logo = sb_logo.resize((new_logo_width, new_logo_height))
168
+ # Make the logo semi-translucent
169
+ transparent_img = Image.new('RGBA', (sb_logo.width, sb_logo.height), (0, 0, 0, 0)) # Create a transparent image of the same size
170
+ sb_logo = Image.blend(transparent_img, sb_logo, alpha=0.3) # Blend the logo with the transparent image
171
+ # Calculate the position to paste the logo at the center of the image
172
+ paste_x_position = (width_px - new_logo_width) // 2
173
+ paste_y_position = (height_px - new_logo_height) // 2
174
+ img.paste(sb_logo, (paste_x_position, paste_y_position), sb_logo)
175
+ # Save the image
176
+ return img
177
 
178
+ def create_line_drawing(input_path):
179
+ with Image.open(input_path) as img:
180
+ img_array = np.array(img)
181
+ # Line processing
182
  blurred = cv2.GaussianBlur(img_array, (7, 7), 0)
183
+ edges = cv2.Canny(blurred, 100, 180)
184
+ structuring_element = cv2.getStructuringElement(cv2.MORPH_RECT, (4,3))
185
  dilated_edges = cv2.dilate(edges, structuring_element, iterations=1)
186
+ line_drawing = 255 - dilated_edges
187
+ line_img = Image.fromarray(line_drawing)
188
+
189
+ right_img = add_white_space_right(line_img)
190
+ right_img, paste_x_position, paste_y_position = watermark(right_img, sb_logo, line_img)
191
+ exif_data = list(get_exif(input_path))
192
+ if str(exif_data) != str([None, None, None]):
193
+ print(str(exif_data))
194
+ print("drawing scale bar")
195
+ line_img = draw_scale_bar(right_img, exif_data, compass, line_img, paste_x_position, paste_y_position)
196
+ line_img = freemium_watermark(line_img, sb_logo)
197
+ return line_img
198
+ else:
199
+ line_img = freemium_watermark(line_img, sb_logo)
200
+ return line_img
201
+
202
+ sb_logo = Image.open("../img/SB_logo_horizontal.png")
203
+ compass = Image.open("../img/compass.jpg")
204
 
205
+ demo = gr.Interface(create_line_drawing,
206
+ inputs=gr.File(type="filepath", label="Image"),
207
+ accept=".png,.jpg,.jpeg,.tiff,.tif,.heic",
208
+ outputs="image",
209
+ live=True)
210
  demo.queue(concurrency_count=10).launch()
211
+ # demo.queue().launch(share=False, server_name="0.0.0.0", server_port=8080, max_threads=1)