Marthee commited on
Commit
8758a2f
·
verified ·
1 Parent(s): 1070671

Create OLD_doors_fasterrcnn.py

Browse files
Files changed (1) hide show
  1. OLD_doors_fasterrcnn.py +452 -0
OLD_doors_fasterrcnn.py ADDED
@@ -0,0 +1,452 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """MartheDeployment_Doors_fasterRCNN.ipynb
3
+
4
+ Automatically generated by Colab.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1kgEtpfNt0jxSwPRhOzODIC6P_prg-c4L
8
+
9
+ ## Libraries
10
+ """
11
+
12
+ # from google.colab.patches import cv2_imshow
13
+ import cv2
14
+ import numpy as np
15
+ import pandas as pd
16
+
17
+ import statistics
18
+ from statistics import mode
19
+
20
+ from PIL import Image
21
+
22
+ # pip install PyPDF2
23
+
24
+ # pip install PyMuPDF
25
+
26
+ # pip install pip install PyMuPDF==1.19.0
27
+
28
+ import io
29
+
30
+ # !pip install pypdfium2
31
+ import pypdfium2 as pdfium
32
+
33
+ import fitz # PyMuPDF
34
+
35
+ import os
36
+
37
+ #drive.mount("/content/drive", force_remount=True)
38
+
39
+ import torch
40
+ from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
41
+ from PIL import Image, ImageDraw
42
+ import torchvision.transforms.functional as F
43
+ import matplotlib.pyplot as plt
44
+ import google_sheet_Legend
45
+ """# updated for (fullpath, pdf_name)
46
+
47
+
48
+
49
+ """
50
+
51
+ def convert2pillow(path):
52
+ pdf = pdfium.PdfDocument(path)
53
+ page = pdf.get_page(0)
54
+ pil_image = page.render().to_pil()
55
+ return pil_image
56
+
57
+ import torch
58
+ import torchvision
59
+ from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
60
+
61
+ # Function to get the model
62
+ def get_model(num_classes):
63
+ # Load a pre-trained Faster R-CNN model with a ResNet-50-FPN backbone
64
+ model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
65
+
66
+ # Get the number of input features for the classifier
67
+ in_features = model.roi_heads.box_predictor.cls_score.in_features
68
+
69
+ # Replace the pre-trained head with a new one for our number of classes
70
+ model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
71
+
72
+ return model
73
+
74
+ '''def ev_model(img, model, device, threshold):
75
+ image_tensor = F.to_tensor(img).unsqueeze(0)
76
+ image_tensor = image_tensor.to(device)
77
+ model.eval()
78
+
79
+ with torch.no_grad():
80
+ predictions = model(image_tensor)
81
+
82
+ single_boxes = []
83
+ double_boxes = []
84
+ for element in range(len(predictions[0]['boxes'])):
85
+ score = predictions[0]['scores'][element].item()
86
+ if score > threshold:
87
+ if predictions[0]['labels'][element].item() == 1:
88
+ single_boxes.append(predictions[0]['boxes'][element].tolist())
89
+ else:
90
+ double_boxes.append(predictions[0]['boxes'][element].tolist())
91
+
92
+ return single_boxes, double_boxes'''
93
+
94
+ def ev_model(img, model, device, threshold):
95
+ image_tensor = F.to_tensor(img).unsqueeze(0)
96
+ image_tensor = image_tensor.to(device)
97
+ model.eval()
98
+
99
+ with torch.no_grad():
100
+ predictions = model(image_tensor)
101
+
102
+ doors_info = []
103
+ for element in range(len(predictions[0]['boxes'])):
104
+ score = predictions[0]['scores'][element].item()
105
+ if score > threshold:
106
+ box = predictions[0]['boxes'][element].tolist()
107
+ label = predictions[0]['labels'][element].item()
108
+ doors_info.append((box,label))
109
+ return doors_info
110
+
111
+
112
+ def distance(point1, point2):
113
+ x1, y1 = point1
114
+ x2, y2 = point2
115
+ return np.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
116
+
117
+ def calculate_midpoint(p1, p2):
118
+ x1, y1 = p1
119
+ x2, y2 = p2
120
+ # Calculate the midpoint
121
+ xm = int((x1 + x2) / 2)
122
+ ym = int((y1 + y2) / 2)
123
+ return (xm, ym)
124
+ def get_door_info(doors_info):
125
+ width_pixels = []
126
+ lines = []
127
+ sanda = []
128
+ line_midpoint = []
129
+ for door_inf in doors_info:
130
+ xmin, ymin, xmax, ymax = door_inf[0]
131
+ #horz_bottom
132
+ if door_inf[1] == 2:
133
+ #for drawing
134
+ point_st = (int(xmin), int(ymax) + 5)
135
+ point_end = (int(xmax),int(ymax) + 5)
136
+ lines.append((point_st,point_end))
137
+
138
+ sanda_st = (int(xmin), int(ymax))
139
+ sand_end = (int(xmax),int(ymax))
140
+ sanda.append((sanda_st, sand_end))
141
+
142
+ line_midpoint.append(calculate_midpoint(sanda_st,sand_end))
143
+ #for calculation
144
+ width = distance((xmin,ymax), (xmax,ymax))
145
+ width_pixels.append(width)
146
+
147
+ #horz_upper
148
+ if door_inf[1] == 3:
149
+ #for drawing
150
+ point_st = (int(xmin),int(ymin) -5)
151
+ point_end = (int(xmax),int(ymin) - 5)
152
+ lines.append((point_st,point_end))
153
+
154
+ sanda_st = (int(xmin),int(ymin))
155
+ sand_end = (int(xmax),int(ymin))
156
+ sanda.append((sanda_st, sand_end))
157
+ line_midpoint.append(calculate_midpoint(sanda_st,sand_end))
158
+ #for calculation
159
+ width = distance((xmin,ymin), (xmax,ymin))
160
+ width_pixels.append(width)
161
+
162
+ #vert_right
163
+ if door_inf[1] == 4:
164
+ #for drawing
165
+ point_st = (int(xmax) + 5,int(ymin))
166
+ point_end = (int(xmax) + 5,int(ymax))
167
+ lines.append((point_st,point_end))
168
+
169
+ sanda_st = (int(xmax), int(ymin))
170
+ sand_end = (int(xmax), int(ymax))
171
+ sanda.append((sanda_st, sand_end))
172
+ line_midpoint.append(calculate_midpoint(sanda_st,sand_end))
173
+ #for calculation
174
+ width = distance((xmax,ymin), (xmax,ymax))
175
+ width_pixels.append(width)
176
+ #vert_left
177
+ if door_inf[1] == 5:
178
+ #for drawing
179
+ point_st = (int(xmin) -5,int(ymin))
180
+ point_end = (int(xmin) -5,int(ymax))
181
+ lines.append((point_st,point_end))
182
+
183
+ sanda_st = (int(xmin),int(ymin))
184
+ sand_end = (int(xmin),int(ymax))
185
+ sanda.append((sanda_st, sand_end))
186
+ line_midpoint.append(calculate_midpoint(sanda_st,sand_end))
187
+ #for calculation
188
+ width = distance((xmin,ymin), (xmin,ymax))
189
+ width_pixels.append(width)
190
+
191
+ return width_pixels, lines, sanda, line_midpoint
192
+
193
+ def pxl2meter(width_pixels, ratio):
194
+ real_width = []
195
+ for width in width_pixels:
196
+ real_width.append(round(width*ratio, 2))
197
+ return real_width
198
+
199
+ def width_as_char(real_width):
200
+ char_width = []
201
+ for width in real_width:
202
+ char_width.append(f"{width}m")
203
+ return char_width
204
+
205
+ def add_annotations_to_pdf(image, pdf_name, lines, sanda, char_width, line_midpoint):
206
+ image_width, image_height = image.size
207
+
208
+ # Create a new PDF document
209
+ pdf_document = fitz.open()
210
+
211
+ # Add a new page to the document with the same dimensions as the image
212
+ page = pdf_document.new_page(width=image_width, height=image_height)
213
+
214
+ # Insert the image into the PDF page
215
+ image_stream = io.BytesIO()
216
+ image.save(image_stream, format="PNG")
217
+ page.insert_image(page.rect, stream=image_stream.getvalue())
218
+
219
+
220
+ #Annotation for drawin lines as in the markups
221
+ for i in range(len(line_midpoint)):
222
+ x, y = line_midpoint[i]
223
+ text = char_width[i]
224
+ rect = fitz.Rect(x, y, x + 200, y + 50) # Adjust the width and height as needed
225
+ annot = page.add_freetext_annot(rect, text, fontsize=10, fontname="helv", text_color=(1,0,0))
226
+ annot.update()
227
+ #Annotation for drawin lines as in the markups
228
+ for i in range(len(lines)):
229
+ annot = page.add_line_annot(lines[i][0], lines[i][1])
230
+ annot = page.add_line_annot(sanda[i][0], lines[i][0])
231
+ annot = page.add_line_annot(sanda[i][1], lines[i][1])
232
+ annot.set_border(width=2, dashes=None) # Optional border styling
233
+ annot.set_colors(stroke=(1, 0, 0)) # Set the line color to red
234
+ annot.update()
235
+
236
+
237
+ output_pdf_path = pdf_name+"_annotated.pdf"
238
+ # Save the PDF with annotations
239
+
240
+ return pdf_document
241
+
242
+
243
+
244
+ '''def calculate_width(bbox):
245
+ #if looking right or left, width < height
246
+ bbox_width = bbox[2] - bbox[0]
247
+ bbox_height = bbox[3] - bbox[1]
248
+ if bbox_width > bbox_height:
249
+ door_width = bbox_width
250
+ else:
251
+ door_width = bbox_height
252
+ return door_width
253
+ '''
254
+ '''def width_annotations(bbox, ratio):
255
+ lines = []
256
+ width = []
257
+
258
+ for box in bbox:
259
+ door_width = calculate_width(box)
260
+ door_width = round(door_width*ratio, 2)
261
+ x1,y1,x2,y2 = box
262
+ b_width = x2 - x1
263
+ b_height = y2 - y1
264
+
265
+ if b_width > b_height:
266
+ lines.append(((x1, y1), (x2, y1)))
267
+ x = (x1+x2)/2
268
+ y = (y1+y1)/2
269
+ width.append(((x,y),door_width))
270
+ else:
271
+ lines.append(((x1, y1), (x1, y2)))
272
+ x = (x1+x1)/2
273
+ y = (y1+y2)/2
274
+ width.append(((x,y), door_width))
275
+ return lines, width'''
276
+
277
+ '''def create_width_annotations(width_info):
278
+ annotations = []
279
+ for i in range(len(width_info)):
280
+ annotations.append(((width_info[i][0][0]),(width_info[i][0][1]),f"{width_info[i][1]} m"))
281
+ return annotations'''
282
+
283
+ '''def calculate_midpoint(top_left, bottom_right):
284
+ x1, y1 = top_left
285
+ x2, y2 = bottom_right
286
+ # Calculate the midpoint
287
+ xm = int((x1 + x2) / 2)
288
+ ym = int((y1 + y2) / 2)
289
+ return (xm, ym)'''
290
+
291
+ '''def mid_points_bbox(bbox):
292
+ midpoint = []
293
+ for i in range(len(bbox)):
294
+ x1 = int(bbox[i][0])
295
+ y1 = int(bbox[i][1])
296
+ x2 = int(bbox[i][2])
297
+ y2 = int(bbox[i][3])
298
+ top_left_corner = (x1, y1)
299
+ bottom_right_corner = (x2, y2)
300
+ midpoint.append(calculate_midpoint(top_left_corner, bottom_right_corner))
301
+ return midpoint'''
302
+
303
+ '''def create_annotations(door_kind, midpoints):
304
+ door = door_kind
305
+ annotations = []
306
+ for i in range(len(midpoints)):
307
+ annotations.append((midpoints[i][0],midpoints[i][1], door))
308
+ return annotations
309
+
310
+ def add_annotations_to_pdf(image, pdf_name, annotation_s, annotation_d,width_ann_single, width_ann_double,line_single,line_double):
311
+ image_width, image_height = image.size
312
+
313
+ # Create a new PDF document
314
+ pdf_document = fitz.open()
315
+
316
+ # Add a new page to the document with the same dimensions as the image
317
+ page = pdf_document.new_page(width=image_width, height=image_height)
318
+
319
+ # Insert the image into the PDF page
320
+ image_stream = io.BytesIO()
321
+ image.save(image_stream, format="PNG")
322
+ page.insert_image(page.rect, stream=image_stream.getvalue())
323
+
324
+ # Add annotations
325
+ for annotation in annotation_s:
326
+ x, y, text = annotation
327
+ # Create an annotation (sticky note)
328
+ annot = page.add_text_annot(fitz.Point(x, y), text)
329
+ annot.set_border(width=0.2, dashes=(1, 2)) # Optional border styling
330
+ annot.set_colors(stroke=(1, 0, 0), fill=None) # Set the stroke color to red
331
+ annot.update()
332
+ for annotation in annotation_d:
333
+ x, y, text = annotation
334
+ # Create an annotation (sticky note)
335
+ annot = page.add_text_annot(fitz.Point(x, y), text)
336
+ annot.set_border(width=0.2, dashes=(1, 2)) # Optional border styling
337
+ annot.set_colors(stroke=(0, 1, 0), fill=None) # Set the stroke color to red
338
+ annot.update()
339
+
340
+ #Annotations for width measurement (marra single we marra double)
341
+ for annotation in width_ann_single:
342
+ x, y, text = annotation
343
+ rect = fitz.Rect(x, y, x + 200, y + 50) # Adjust the width and height as needed
344
+ annot = page.add_freetext_annot(rect, text, fontsize=10, fontname="helv", text_color=(1,0,0))
345
+ annot.update()
346
+ for annotation in width_ann_double:
347
+ x, y, text = annotation
348
+ rect = fitz.Rect(x, y, x + 200, y + 50) # Adjust the width and height as needed
349
+ annot = page.add_freetext_annot(rect, text, fontsize=10, fontname="helv", text_color=(1,0,0))
350
+ annot.update()
351
+
352
+ #Annotation kind of the line drawings (marra single we marra double)
353
+ for line in line_single:
354
+ start_point, end_point = line
355
+ annot = page.add_line_annot(start_point, end_point)
356
+ annot.set_border(width=2, dashes=None) # Optional border styling
357
+ annot.set_colors(stroke=(1, 0, 0)) # Set the line color to red
358
+ annot.update()
359
+ for line in line_double:
360
+ start_point, end_point = line
361
+ annot = page.add_line_annot(start_point, end_point)
362
+ annot.set_border(width=2, dashes=None) # Optional border styling
363
+ annot.set_colors(stroke=(1, 0, 0)) # Set the line color to red
364
+ annot.update()
365
+
366
+
367
+ output_pdf_path = pdf_name+"_annotated.pdf"
368
+ # Save the PDF with annotations
369
+
370
+ return pdf_document
371
+ # pdf_document.save(output_pdf_path)
372
+ # pdf_document.close()
373
+ '''
374
+ def main_run(pdf_fullpath, weights_path, pdf_name,pdfpath,ratio): ####pdf_fullpath here is the data and not the path
375
+ img_pillow = convert2pillow(pdf_fullpath)
376
+ #new_image = img_pillow.resize((2384, 1684))
377
+
378
+ # Specify the number of classes (including the background)
379
+ num_classes = 10 # Ensure this matches the saved model's number of classes
380
+
381
+ # Load the model with the specified number of classes
382
+ model = get_model(num_classes)
383
+
384
+ # Load the saved model's state dictionary with map_location to handle CPU
385
+ device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
386
+
387
+ try:
388
+ model.load_state_dict(torch.load(weights_path, map_location=device), strict=False)
389
+ except RuntimeError as e:
390
+ print(f"Error loading model state_dict: {e}")
391
+ return
392
+
393
+ # Set the model to evaluation mode
394
+ model.eval()
395
+
396
+ # Move the model to the appropriate device
397
+ model.to(device)
398
+
399
+ # START INFERENCE
400
+ #sbox, dbox = ev_model(img_pillow, model, device, 0.6)
401
+
402
+ #Dataframe for Doors count
403
+ #doors_count = {'Type': ['Single Doors', 'Double Doors'], 'Quantity': [len(sbox), len(dbox)]}
404
+ #df_doors = pd.DataFrame(doors_count)
405
+
406
+ #single_midpoint = mid_points_bbox(sbox)
407
+ #double_midpoint = mid_points_bbox(dbox)
408
+
409
+ #Kind Annotations
410
+ #single_annotations = create_annotations("single door", single_midpoint)
411
+ #double_annotations = create_annotations("double door", double_midpoint)
412
+ #Lines Annotations
413
+ #line_single, width_signle = width_annotations(sbox, 1)
414
+ #line_double, width_double = width_annotations(dbox, 1)
415
+ #Width Annotations
416
+ #width_single_ann = create_width_annotations(width_signle)
417
+ #width_double_ann = create_width_annotations(width_double)
418
+
419
+ # add_annotations_to_pdf(new_image, pdf_name, single_annotations, double_annotations)
420
+
421
+
422
+ #NEW
423
+ doors_info = ev_model(img_pillow, model, device, 0.9)
424
+ width_pixels, lines, sanda, line_midpoint = get_door_info(doors_info)
425
+ real_width = pxl2meter(width_pixels, ratio)
426
+ char_width = width_as_char(real_width)
427
+
428
+ pdf_document = add_annotations_to_pdf(img_pillow, plan, lines, sanda, char_width, line_midpoint)
429
+
430
+ #pdf_document=add_annotations_to_pdf(img_pillow, pdf_name, single_annotations, double_annotations,width_single_ann,width_double_ann,line_single,line_double)
431
+
432
+ page=pdf_document[0]
433
+ pix = page.get_pixmap() # render page to an image
434
+ pl=Image.frombytes('RGB', [pix.width,pix.height],pix.samples)
435
+ img=np.array(pl)
436
+ annotatedimg = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
437
+
438
+ df_doors = df_doors.fillna(' ')
439
+ gc,spreadsheet_service,spreadsheetId, spreadsheet_url , namepathArr=google_sheet_Legend.legendGoogleSheets(df_doors , pdf_name,pdfpath)
440
+ list1=pd.DataFrame(columns=['content', 'id', 'subject'])
441
+ for page in pdf_document:
442
+ for annot in page.annots():
443
+ list1.loc[len(list1)] =annot.info
444
+
445
+
446
+ # modify this return
447
+ return annotatedimg, pdf_document , spreadsheet_url, list1 , df_doors
448
+
449
+ # model_path = '/content/drive/MyDrive/separated_classes.pth'
450
+ # #pdf_name = data
451
+ # for i in range(len(fullpath)):
452
+ # main_run(fullpath[i], model_path, pdf_name[i])