Marthee commited on
Commit
e51a8dc
·
verified ·
1 Parent(s): 9049c2d

Update pilecaps_adr.py

Browse files
Files changed (1) hide show
  1. pilecaps_adr.py +384 -174
pilecaps_adr.py CHANGED
@@ -11,7 +11,7 @@ import cv2
11
  from matplotlib import pyplot as plt
12
  from math import sin, cos, radians
13
  import pandas as pd
14
- from PIL import Image
15
  import numpy as np
16
  from googleapiclient.discovery import build
17
  from google.oauth2 import service_account
@@ -23,6 +23,7 @@ import ast
23
  import Dropbox_TSA_API
24
  import tsadropboxretrieval
25
  from collections import Counter
 
26
 
27
  def textLists(img,dataDoc):
28
  allTexts = texts_from_pdf(dataDoc)
@@ -43,27 +44,46 @@ def textLists(img,dataDoc):
43
  listall.append((p1[0],p1[1],tpl[4]))
44
  return pc_coor, listall
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  #Prepare preprocessing
47
  def detectCircles(imgOriginal ):
48
  im=imgOriginal.copy()
49
  imgGry1 = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
50
  kernel=np.ones((3,3),np.uint8)
51
  er1=cv2.erode(imgGry1,kernel, iterations=2)
52
-
53
- er1=cv2.dilate(er1,kernel, iterations=1)
54
- detected_circles = cv2.HoughCircles( er1, cv2.HOUGH_GRADIENT, 1, 50, param1= 550,
 
 
55
  param2 =21, minRadius = 20, maxRadius = 50) #18 param2
56
-
57
  # Draw circles that are detected.
58
  if detected_circles is not None:
59
  # Convert the circle parameters a, b and r to integers.
60
  detected_circles = np.uint16(np.around(detected_circles))
61
  detected_circles = np.round(detected_circles[0, :]).astype("int")
62
- #DRAW CIRCLES
63
  for (x, y, r) in detected_circles:
64
- cv2.circle(im, (x, y), r, (255, 255, 255), 5)
65
  return im
66
 
 
 
67
  def detectSmallCircles(img ):
68
  #Remove tiny TOC points that interfere with shapes
69
  im=img.copy()
@@ -121,38 +141,38 @@ def removeDashedLines(img4, imgBW ,max,min):
121
  green=im_copy[:,:,1]
122
  return green
123
 
124
- def removeSmallDashes(imgOriginal,green):
 
125
  smalldashes=green.copy()
126
  smalldashes=cv2.bitwise_not(smalldashes)
127
 
128
  kernel3= np.ones((3,3),np.uint8)
129
-
130
  img1=cv2.dilate(smalldashes, kernel3, iterations=2)
131
  img2=cv2.erode(img1, kernel3, iterations=2)
132
 
133
  smalldashes=cv2.medianBlur(img2,7)
134
  smalldashes=cv2.medianBlur(smalldashes,9)
135
- # cv2_imshow(smalldashes)
136
  smalldashesOut=green.copy()
 
 
 
 
 
137
  smalldashesOut=cv2.cvtColor(smalldashesOut,cv2.COLOR_GRAY2BGR)
138
- imgLines= cv2.HoughLinesP(smalldashes,1,np.pi/150,27,minLineLength=10,maxLineGap = 70) #was w-h , gap=150
139
 
140
  imgCopy=imgOriginal.copy()
141
  for i in range(len(imgLines)):
142
  for x1,y1,x2,y2 in imgLines[i]:
143
  cv2.line(smalldashesOut,(x1,y1),(x2,y2),(0,255,0),3)
144
-
145
-
146
- smalldashesOut=smalldashesOut[:,:,1]
147
- # cv2_imshow(smalldashesOut)
148
- for i in range(len(imgLines)):
149
- for x1,y1,x2,y2 in imgLines[i]:
150
- cv2.line(imgCopy,(x1,y1),(x2,y2),(0,255,0),6)
151
-
152
  imgCopy=imgCopy[:,:,1]
153
- # cv2_imshow(imgCopy)
154
  return imgCopy,smalldashesOut
155
 
 
156
  def euclidian_distance(point1, point2):
157
  return sum([(point1[x] - point2[x]) ** 2 for x in range(len(point1))]) ** 0.5
158
 
@@ -168,37 +188,137 @@ def removeDashedLinesSmall(img4, imgBW ,max,min):
168
  green=im_copy[:,:,1]
169
  return green
170
 
171
- def ConnectBeamLines(smalldashesOut):
 
 
 
 
 
 
 
 
 
172
  green1=cv2.bitwise_not(smalldashesOut)
173
- green2=smalldashesOut.copy()
174
- green2=cv2.cvtColor(green2,cv2.COLOR_GRAY2BGR)
175
- imgLines= cv2.HoughLinesP(green1,0.3,np.pi/180,20,minLineLength=25,maxLineGap = 25) #try 180
176
  for i in range(len(imgLines)):
177
  for x1,y1,x2,y2 in imgLines[i]:
178
- cv2.line(green2,(x1,y1),(x2,y2),(0,0,0),2)
179
- return green2
 
 
 
 
 
 
 
 
 
 
 
 
180
  #create img with solid lines
181
- def allpreSteps(imgOriginal):
182
  noCircles=detectCircles(imgOriginal)
183
- imgnoSmall=detectSmallCircles(noCircles )
184
- img4,imgBW,max,min=DashedPreprocessing(imgOriginal,imgnoSmall)
185
- green=removeDashedLines(img4,imgBW,max,min)
186
- imgCopy,smalldashesOut=removeSmallDashes(imgOriginal,green)
187
- noSmallDashes=removeDashedLinesSmall(img4, smalldashesOut ,max,min)
188
- green2=ConnectBeamLines(noSmallDashes)
189
- # cv2_imshow(green2)
190
- return green2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
- def texts_from_pdf(input_pdf):
193
- pdf_document = fitz.open("pdf",input_pdf)
194
 
 
 
195
  for page_num in range(pdf_document.page_count):
196
  page = pdf_document[page_num]
197
  text_instances = page.get_text("words")
198
  page.apply_redactions()
199
  return text_instances
200
 
201
- def nearestText(a,b , pc_coor):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  nearest_point=min(pc_coor,key=lambda x:euclidian_distance((a,b),x))
203
  dist = euclidian_distance(nearest_point, (a,b))
204
  if dist < 400: #distance threshold
@@ -232,9 +352,26 @@ def connectsmallDot(blackwithNoDot):
232
  for x1,y1,x2,y2 in imgLines[i]:
233
  cv2.line(blackwithNoDot,(x1,y1),(x2,y2),(255,255,255),2)
234
  return blackwithNoDot
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  #OLD method (White shapes)
236
  def preprocessold(img,number):
237
- blurG = cv2.GaussianBlur(ChangeBrightness(img,6),(3,3),0 )
 
238
  imgGry = cv2.cvtColor(blurG, cv2.COLOR_BGR2GRAY)
239
  kernel=np.ones((3,3),np.uint8)
240
  er1=cv2.dilate(imgGry,kernel, iterations=2) #thinning
@@ -244,21 +381,66 @@ def preprocessold(img,number):
244
  ret3, thresh = cv2.threshold(er1, 220, 255, cv2.THRESH_BINARY_INV) #`140 - 141
245
  return thresh
246
 
247
- #anding of old method output with solid lines img
248
- def preprocess(dataDoc,imgtransparent1,img,number,green2,flag,layeredflag,BlackmaskDetected1=0):
249
- #first preprocessing ( old method - black img with white shapes)
250
- alltxts=[]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  img1=preprocessold(img,number)
252
- anding=cv2.bitwise_and(green2,green2,mask=img1)
253
- anding = cv2.cvtColor(anding, cv2.COLOR_BGR2GRAY)
 
254
  ret3, thresh2 = cv2.threshold(anding, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
255
-
256
  if layeredflag.startswith('layer'):
257
  thresh2=cv2.bitwise_and(thresh2,thresh2,mask=BlackmaskDetected1)
258
  threshcontours, threshHier = cv2.findContours(thresh2, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
259
- threshHier= threshHier[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  outlinesDotIN=getOutlinesDotIN(img)
261
- finalcnts=[]
 
 
262
  perimeters=[]
263
  openClosedFlag=0
264
  threshCnt, threshHier2 = cv2.findContours(img1, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
@@ -267,70 +449,72 @@ def preprocess(dataDoc,imgtransparent1,img,number,green2,flag,layeredflag,Blackm
267
  area1 = cv2.contourArea(cnt)
268
  if (area1 > 2000 ):
269
  cv2.drawContours(outlines,[cnt],0,(255,255,255),2)
270
- pc_coor, listall=textLists(img,dataDoc)
271
  perimeter=0
 
272
  for cnt in threshcontours:
273
- Blackmask = np.zeros(img.shape[:2], dtype="uint8")
 
274
  area1 = cv2.contourArea(cnt)
275
  if (area1 > 2000 ):
276
  x, y , width, height = cv2.boundingRect(cnt)
277
- textPoint=nearestText(int(x+(width/2)), int(y+(height/2)) , pc_coor)
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  txt=''
279
  if(textPoint!='none'):
280
  for textTuple in listall:
281
  if textPoint[0]==textTuple[0] and textPoint[1]==textTuple[1]:
282
  txt=textTuple[2]
283
- alltxts.append(txt)
 
284
  elif textPoint=='none':
285
- alltxts.append('none')
286
- if flag.startswith('perimeter'):
287
- kernel=np.ones((2,2),np.uint8)
288
- cv2.drawContours(Blackmask,[cnt],0,(255,255,255), 6)
289
- Blackmask=cv2.dilate(Blackmask,kernel, iterations=1)
290
- if 'GB' in txt:
291
- cBlk,_= cv2.findContours(Blackmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
292
- xcBlk, ycBlk , width, height = cv2.boundingRect(cBlk[0])
293
- xx=cv2.bitwise_and(outlines,outlines,mask=Blackmask)
294
- xx = cv2.threshold(xx, 250, 255, cv2.THRESH_BINARY)[1]
295
  cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
296
  if len(cntsx)>0:
297
- hierx=hierx[0]
298
- xx=cv2.bitwise_and(outlinesDotIN,outlinesDotIN,mask=xx)
299
  cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
300
  if len(cntsx)>0:
301
- xx=connectsmallDot(xx)
302
- cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
303
- if len(cntsx)>0:
304
- hierx=hierx[0]
305
- for comp in zip(cntsx,hierx):
306
- c=comp[0]
307
- h=comp[1]
308
- xc, yc , width, height = cv2.boundingRect(c)
309
- perimeter=cv2.arcLength(c,True)
310
- shape=[]
311
- approx = cv2.approxPolyDP(c, 0.003* perimeter, True)
312
- if h[2]<0 and h[3] <0:
313
- perimeter1 = cv2.arcLength(approx, True)
314
- perimeter=perimeter1/2
315
- # cv2_imshow(xx)
316
- openClosedFlag='open'
317
- imgtransparent1=cv2.polylines(imgtransparent1, [approx], False, (0,255,0), thickness=4,lineType=8)
318
-
319
- perimeters.append([xc, yc ,xcBlk, ycBlk ,perimeter ,openClosedFlag , txt , approx])
320
- else:
321
- if h[2] >0:
322
- openClosedFlag='closed'
323
- if flag.startswith('area'):
324
- kernel=np.ones((2,2),np.uint8)
325
- cv2.drawContours(Blackmask,[cnt],0,(255,255,255), 5)
326
- Blackmask=cv2.erode(Blackmask,kernel, iterations=1)
327
- openClosedFlag='none'
328
- contours1, hier1 = cv2.findContours(Blackmask, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
329
- finalcnts.append(contours1)
330
- finalcnts=tuple(finalcnts)
331
- # ###############
332
-
333
- return finalcnts, perimeters , alltxts , imgtransparent1
334
 
335
  """# ROI (levels)
336
  ## Detect regions with specific color and mask them
@@ -368,7 +552,7 @@ def DetectColor(img,color=0):
368
  cv2.imwrite('det.png',detectedColors)
369
  return mask, detectedColors, color
370
 
371
- def getinnerColor(BlackmaskDetected,img,detectedColors,finalColorArray,ratioarea,ratioperim,flag,eachcolor):
372
 
373
  countBlackMasks=0
374
  xored=detectedColors
@@ -384,34 +568,22 @@ def getinnerColor(BlackmaskDetected,img,detectedColors,finalColorArray,ratioarea
384
  extrema = pil_image.convert("L").getextrema()
385
  if extrema != (0, 0): # if image is not black --> has a colored mask within
386
  cc=detectedColors.copy()
387
- # cc1=detectedColorsB.copy()
388
  ColoredContour, Coloredhierarchy = cv2.findContours(masked, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
389
-
390
  for cnt in ColoredContour:
391
-
392
  area1 = cv2.contourArea(cnt)
393
  if (area1 > 1000 ):
394
 
395
  x, y , width, height = cv2.boundingRect(cnt)
396
- # cv2.rectangle(cc, (x,y ), (x+width, y+height), (255,255,255), -1)
397
- # cv2.rectangle(Blackmask, (x,y ), (x+width, y+height), 255, -1)
398
- #to get rid of the edge of the inner reectangles
399
  cv2.drawContours(cc,[cnt],0,(255,255,255), 3)
400
  cv2.drawContours(Blackmask,[cnt] ,0, (255,255,255), 3)
401
-
402
  cv2.drawContours(cc,[cnt],0,(255,255,255), -1) # (x-5,y-5 ), (x+width, y+height),
403
  cv2.drawContours(Blackmask,[cnt] ,0, (255,255,255), -1) #,(x,y ), (x+width, y+height)
404
-
405
  cv2.drawContours(BlackmaskDetected,[cnt] ,0, (0,0,0), -1) #,(x,y ), (x+width, y+height)
406
-
407
  invertedmask = cv2.bitwise_and(imgc,imgc, mask= Blackmask)
408
  xored=cc
409
- # masked b abyad
410
  detectedColors=xored
411
-
412
  else: #black mask , no other levels are found # to check law count == number of colors in array yb2a no more levels and break
413
  countBlackMasks+=1
414
-
415
  return xored,invertedmask , BlackmaskDetected
416
 
417
  def allLevelsofColor(BlackmaskDetected,img,levelonly, invertedmask,color,finalColorArray):
@@ -423,9 +595,7 @@ def allLevelsofColor(BlackmaskDetected,img,levelonly, invertedmask,color,finalCo
423
  Blackmask = np.zeros(img.shape[:2], dtype="uint8")
424
 
425
  masked,maskedColor,rgbcolor=DetectColor(invertedmask,color)
426
- # color=hexRGB(color)
427
  color=[color[0],color[1],color[2]]
428
-
429
  rgbcolor=[rgbcolor[0],rgbcolor[1],rgbcolor[2]]
430
  print(rgbcolor,color)
431
  pil_image=Image.fromarray(masked)
@@ -451,9 +621,7 @@ def allLevelsofColor(BlackmaskDetected,img,levelonly, invertedmask,color,finalCo
451
  # get (i, j) positions of all RGB pixels that are black (i.e. [0, 0, 0])
452
  firstLevel[np.all(firstLevel == (0,0,0), axis=-1)] = (255, 255, 255)
453
  firstLevel1=cv2.bitwise_and(levelonly,firstLevel)
454
- # cv2_imshow(firstLevel1)
455
 
456
- # cv2_imshow(firstLevel1)
457
  for othercolor in finalColorArray:
458
  # othercolor2=hexRGB(othercolor)
459
  othercolor2=[othercolor[0],othercolor[1],othercolor[2]]
@@ -477,7 +645,7 @@ def allLevelsofColor(BlackmaskDetected,img,levelonly, invertedmask,color,finalCo
477
  # cv2_imshow(Blackmask)
478
  return firstLevel1, BlackmaskDetected
479
 
480
- def getColoredContour(mask,img,finalColorArray,ratioarea,ratioperim,flag,eachcolor):
481
  ColoredContour, Coloredhierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
482
  Coloredhierarchy=Coloredhierarchy[0]
483
 
@@ -504,28 +672,28 @@ def getColoredContour(mask,img,finalColorArray,ratioarea,ratioperim,flag,eachcol
504
  if extrema == (0, 0) :#and extremaB==(0,0): # if image is not black --> has a colored mask within
505
  break
506
 
507
- levelOnly,invertedmask,BlackmaskDetected=getinnerColor(Blackmask,img,detectedColors,finalColorArray,ratioarea,ratioperim,flag,eachcolor) #mask inner levels b abyad
508
  firstLevel1, BlackmaskDetected1= allLevelsofColor(BlackmaskDetected,img,levelOnly, invertedmask,eachcolor,finalColorArray)
509
  return firstLevel1,invertedmask, BlackmaskDetected1
510
 
511
  """# contours"""
512
 
513
- def findContoursFullImage(dataDoc,imgtransparent1,green2,img,number,finalColorArray,ratioarea,ratioperim,flag,color=[0,0,0]):
514
  if number == 0:
515
- contourss, perimeters ,alltxts , imgtransparent1=preprocess(dataDoc,imgtransparent1,img,number,green2,flag, 'nolayer')
516
- return contourss , perimeters, alltxts , imgtransparent1
517
  else:
518
  mask, detectedColors, rgbcolor =DetectColor(img,color)
519
  pil_image=Image.fromarray(mask)
520
  extrema = pil_image.convert("L").getextrema()
521
  if extrema != (0, 0): # if image is not black --> has a colored mask within
522
- coloredregions,invertedmask,BlackmaskDetected1=getColoredContour(mask,img,finalColorArray,ratioarea,ratioperim,flag,color)
523
 
524
- contourss,perimeters , alltxts , imgtransparent1=preprocess(dataDoc,imgtransparent1,coloredregions,number,green2,flag,'layer',BlackmaskDetected1)
525
- return contourss,rgbcolor ,invertedmask , perimeters , alltxts , imgtransparent1
526
  else:
527
- contourss, perimeters , alltxts , imgtransparent1=preprocess(dataDoc,imgtransparent1,img,number,green2,flag,'nolayer')
528
- return contourss,color ,mask , perimeters , alltxts
529
 
530
  #Straighten tilted shapes
531
  def StraightenImage(contour,imgArea):
@@ -539,18 +707,18 @@ def StraightenImage(contour,imgArea):
539
  return angleR,width,height
540
 
541
  #get all areas and perimeter present
542
- def getAreasPerimeter(img,ratioarea,ratioperim,contourss,contourssA):
543
  appended=[]
544
- for contour in range(len(contourss)):
545
- area1 = cv2.contourArea(contourss[contour][0])
546
  if (area1 >2000 ):
547
- perimeter= cv2.arcLength(contourss[contour][0],True)
548
- approx = cv2.approxPolyDP(contourss[contour][0], 0.01* perimeter, True)
549
  perimeter1 = cv2.arcLength(approx, True)
550
  approx = cv2.approxPolyDP(contourssA[contour][0], 0.0002* perimeter, True)
551
  area1 = cv2.contourArea(approx)
552
- x, y , width, height = cv2.boundingRect(contourss[contour][0])
553
- angleR,widthR ,heightR= StraightenImage(contourss[contour][0],img)
554
 
555
  if (angleR != 90.0 and angleR != -90.0 and angleR != 0.0 and angleR != -0.0 ): #inclined b ay degree
556
  width=widthR
@@ -561,9 +729,9 @@ def getAreasPerimeter(img,ratioarea,ratioperim,contourss,contourssA):
561
  appended.append([areaa,width,height])
562
  return appended
563
  #fill dictionary with areas and perimeters and occurences
564
- def FillDictionary(SimilarAreaDictionary,img,ratioarea,ratioperim,contourss,contourssA,rgbcolor=[0,0,0],color=[0,0,0]):
565
  #fills dictionary with key areas and number of occurences
566
- areas_Perimeters=sorted(getAreasPerimeter(img,ratioarea,ratioperim,contourss,contourssA))
567
 
568
  indices=[]
569
  colorRanges=[[255,0,0],[0,0,255],[0,255,255],[0,64,0],[255,204,0],[255,128,64],[255,0,128],[255,128,192],[128,128,255],[128,64,0],[0,255,0],[179,106,179],[115,52,179],[0,128,192],[128,0,128],[128,0,0],[0,128,255],[255,182,128],[255,0,255],[0,0,128],[0,128,64],[255,255,0],[128,0,64],[203,203,106],[128,255,166],[255,128,0],[255,98,98],[90,105,138],[114,10,72],[36,82,78],[225,105,29],[108,62,40],[11,35,75],[42,176,203],[255,153,153],[129,74,138],[99,123,137],[159,179,30],[255,0,0],[0,0,255],[0,255,255],[0,64,0],[255,204,0],[255,128,64],[255,0,128],[255,128,192],[128,128,255],[128,64,0],[0,255,0],[179,106,179],[115,52,179],[0,128,192],[128,0,128],[128,0,0],[0,128,255],[255,182,128],[255,0,255],[0,0,128],[0,128,64],[255,255,0],[128,0,64],[203,203,106],[128,255,166],[255,128,0],[255,98,98],[90,105,138],[114,10,72],[36,82,78],[225,105,29],[108,62,40],[11,35,75],[42,176,203],[255,153,153],[129,74,138],[99,123,137],[159,179,30]]
@@ -582,9 +750,9 @@ def FillDictionary(SimilarAreaDictionary,img,ratioarea,ratioperim,contourss,cont
582
  areaPerimeterMax= round(item1,1) + 0.4
583
  # print (areaMin, areaMax)
584
  if color != [0,0,0]: #colored images
585
- mydata=[[],[rgbcolor[0],rgbcolor[1],rgbcolor[2] ],round(item1,1),width1,height1,1, 0,0,0,0,0,0,0,0,0]
586
  else:
587
- mydata=[[],' ', round(item1,1),width1,height1,1, 0,0,0,0,0,0,0,0,0]
588
  myindex= SimilarAreaDictionary.index[((SimilarAreaDictionary['Rounded'] >=areaPerimeterMin) &(SimilarAreaDictionary['Rounded']<=areaPerimeterMax) )].tolist()
589
  if color!= [0,0,0]: #leveled image
590
  checkifColorExists=0 # to check whether this row was found or not( area and color )
@@ -614,8 +782,9 @@ def FillDictionary(SimilarAreaDictionary,img,ratioarea,ratioperim,contourss,cont
614
 
615
  return SimilarAreaDictionary, colorsUsed , areas_Perimeters
616
  #detect and draw and measure
617
- def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim,flag , path,pdfpath):
618
  green2=allpreSteps(img)
 
619
  doc = fitz.open("pdf",dataDoc)
620
  page = doc[0]
621
  rotationOld=page.rotation
@@ -632,33 +801,44 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim,flag
632
  imgtransparent1=img.copy()
633
 
634
  if number ==220:
635
- SimilarAreaDictionary= pd.DataFrame(columns=['Guess','Color','Rounded','Width','Height','Occurences','Area','Total Area','Perimeter','Total Perimeter','Length','Total Length','R','G','B'])
636
- firstcolor=finalColorArray[0]
637
- counter=0
638
  maskDone=img.copy()
639
  for eachcolor in finalColorArray:
640
-
641
- contourss,rgbcolor,invertedmask , perimeters , alltxts,imgtransparent1=findContoursFullImage(dataDoc,imgtransparent1,green2,maskDone,number,finalColorArray,ratioarea,ratioperim,'perimeter',eachcolor)
642
- contourssA,rgbcolor,invertedmask, perimeters , alltxts,imgtransparent1=findContoursFullImage(dataDoc,imgtransparent1,green2,maskDone,number,finalColorArray,ratioarea,ratioperim,'area',eachcolor)
643
-
644
- SimilarAreaDictionary, colorsUsed , areas_Perimeters= FillDictionary(SimilarAreaDictionary,maskDone,ratioarea,ratioperim,contourss,contourssA,rgbcolor,eachcolor)
645
  perimTotal=0
646
- for contour in range(len(contourss)):
647
  shape=[]
648
-
649
- # cv2_imshow(imgStraight)
650
  area1 = cv2.contourArea(contourssA[contour][0])
651
-
652
- # perimeter1 = cv2.arcLength(contourss[contour][0], True)
653
  if (area1 > 3500 ): #check perimeter kman fl condition -- 2800
654
- perimeter=cv2.arcLength(contourss[contour][0],True)
655
  shape=[]
656
- angleR,widthR ,heightR= StraightenImage(contourss[contour][0],imgArea1)
657
- x, y , width, height = cv2.boundingRect(contourss[contour][0])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
658
  approxA = cv2.approxPolyDP(contourssA[contour][0], 0.0002* perimeter, True)
659
  area1 = cv2.contourArea(approxA)
660
-
661
- approx = cv2.approxPolyDP(contourss[contour][0], 0.01 * perimeter, True) #0.0009
662
  perimeter1 = cv2.arcLength(approx, True)
663
  for point in approxA:
664
  x1, y1 = point[0]
@@ -693,9 +873,14 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim,flag
693
  if passed ==0:
694
  if SimilarAreaDictionary['Color'].loc[i] == [rgbcolor[0],rgbcolor[1],rgbcolor[2]] and ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) :
695
  if (SimilarAreaDictionary['Width'].loc[i] <=widthMax and SimilarAreaDictionary['Width'].loc[i] >= widthMin) and (SimilarAreaDictionary['Height'].loc[i] <= heightMax and SimilarAreaDictionary['Height'].loc[i] >= heightMin ) or (SimilarAreaDictionary['Width'].loc[i] <=heightMax and SimilarAreaDictionary['Width'].loc[i] >= heightMin) and (SimilarAreaDictionary['Height'].loc[i] <= widthMax and SimilarAreaDictionary['Height'].loc[i] >= widthMin ) :
 
 
 
 
 
696
  SimilarAreaDictionary['Total Area'].loc[i]+=areaa
697
  SimilarAreaDictionary['Area'].loc[i]=areaa
698
- SimilarAreaDictionary['Guess'].loc[i].append(str(alltxts[contour]))
699
  pFlagDF=0
700
  color= (int(SimilarAreaDictionary['R'].loc[i])/255 , int(SimilarAreaDictionary['G'].loc[i])/255 , int(SimilarAreaDictionary['B'].loc[i])/255 )
701
 
@@ -731,7 +916,7 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim,flag
731
  SimilarAreaDictionary['Length'].loc[i]=lengthShape
732
 
733
  passed=1
734
- cv2.drawContours(imgArea1, [contourss[contour][0]], 0, ( int(SimilarAreaDictionary['B'].loc[i]), int(SimilarAreaDictionary['G'].loc[i]), int(SimilarAreaDictionary['R'].loc[i])), -1)
735
  annot = page.add_polygon_annot( points=shape) # 'Polygon'
736
  annot.set_border(width=0.2)
737
  annot.set_colors(stroke=color, fill= color )
@@ -755,23 +940,43 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim,flag
755
  #########################
756
  else:
757
 
758
- SimilarAreaDictionary= pd.DataFrame(columns=['Guess','Color','Rounded','Width','Height','Occurences','Area','Total Area','Perimeter','Total Perimeter','Length','Total Length','R','G','B'])
759
- contourss , perimeters , alltxts , imgtransparent1=findContoursFullImage(dataDoc,imgtransparent1,green2,img,number,finalColorArray,ratioarea,ratioperim,'perimeter')
760
- contourssA , perimetersA , alltxts , imgtransparent1=findContoursFullImage(dataDoc,imgtransparent1,green2,img,number,finalColorArray,ratioarea,ratioperim,'area')
761
- SimilarAreaDictionary,colorsUsed , areas_Perimeters= FillDictionary(SimilarAreaDictionary,img,ratioarea,ratioperim,contourss,contourssA)
762
 
763
- for contour in range(len(contourss)):
764
  area1 = cv2.contourArea(contourssA[contour][0])
765
  if (area1 >4000 ):
766
- perimeter=cv2.arcLength(contourss[contour][0],True)
767
 
768
 
769
  shape=[]
770
- angleR,widthR ,heightR= StraightenImage(contourss[contour][0],imgArea1)
771
- x, y , width, height = cv2.boundingRect(contourss[contour][0])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
772
  approxA = cv2.approxPolyDP(contourssA[contour][0], 0.0002* perimeter, True)
773
  area1 = cv2.contourArea(approxA)
774
- approx = cv2.approxPolyDP(contourss[contour][0], 0.01 * perimeter, True) #0.0009
775
  perimeter1 = cv2.arcLength(approx, True)
776
  for point in approxA:
777
  x1, y1 = point[0]
@@ -805,9 +1010,14 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim,flag
805
  if passed ==0:
806
  if ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) :
807
  if (SimilarAreaDictionary['Width'].loc[i] <=widthMax and SimilarAreaDictionary['Width'].loc[i] >= widthMin) and (SimilarAreaDictionary['Height'].loc[i] <= heightMax and SimilarAreaDictionary['Height'].loc[i] >= heightMin ) or (SimilarAreaDictionary['Width'].loc[i] <=heightMax and SimilarAreaDictionary['Width'].loc[i] >= heightMin) and (SimilarAreaDictionary['Height'].loc[i] <= widthMax and SimilarAreaDictionary['Height'].loc[i] >= widthMin ) :
 
 
 
 
 
808
  SimilarAreaDictionary['Total Area'].loc[i]+=areaa
809
  SimilarAreaDictionary['Area'].loc[i]=areaa
810
- SimilarAreaDictionary['Guess'].loc[i].append(str(alltxts[contour]))
811
  pFlagDF=0
812
  color= (int(SimilarAreaDictionary['R'].loc[i])/255 , int(SimilarAreaDictionary['G'].loc[i])/255 , int(SimilarAreaDictionary['B'].loc[i])/255 )
813
 
@@ -842,7 +1052,7 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim,flag
842
  SimilarAreaDictionary['Length'].loc[i]=lengthShape
843
 
844
  passed=1
845
- cv2.drawContours(imgArea1, [contourss[contour][0]], 0, ( int(SimilarAreaDictionary['B'].loc[i]), int(SimilarAreaDictionary['G'].loc[i]), int(SimilarAreaDictionary['R'].loc[i])), -1)
846
  annot = page.add_polygon_annot( points=shape) # 'Polygon'
847
  annot.set_border(width=0.2)
848
  annot.set_colors(stroke=color, fill= color )
@@ -851,7 +1061,7 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim,flag
851
  # annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
852
  annot.update()
853
 
854
- cv2.putText(imgtransparent1,'Area: '+str(areaa) +' m2', (x+50,y-10) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2)
855
  pFlag=0
856
 
857
  for p in perimeters:
@@ -1114,7 +1324,7 @@ def legendGoogleSheets(SimilarAreaDictionary,path ,pdfpath, spreadsheetId=0):
1114
  'startRowIndex': 0,
1115
  'endRowIndex': 1,
1116
  'startColumnIndex': 0,
1117
- 'endColumnIndex':9
1118
  }
1119
 
1120
  }}
@@ -1129,6 +1339,7 @@ def legendGoogleSheets(SimilarAreaDictionary,path ,pdfpath, spreadsheetId=0):
1129
  worksheet.cell((2,4)).value='Areas'
1130
  worksheet.cell((2,6)).value='Perimeters'
1131
  worksheet.cell((2,8)).value='Lengths'
 
1132
  second_row_data=['Nr','m2','Total','m','Total','m','Total']
1133
  if splittedpdfpath[-2].startswith('1.0') or splittedpdfpath[-2].startswith('3.2'):
1134
  worksheet.update_row(3,second_row_data,col_offset=2)
@@ -1141,6 +1352,7 @@ def legendGoogleSheets(SimilarAreaDictionary,path ,pdfpath, spreadsheetId=0):
1141
 
1142
  worksheet.update_col(8,list(SimilarAreaDictionary['Length']),row_offset=3)
1143
  worksheet.update_col(9,list(SimilarAreaDictionary['Total Length']),row_offset=3)
 
1144
  if splittedpdfpath[-2].startswith('1.0'):
1145
  colorsUsed=[]
1146
  for i in range(len(SimilarAreaDictionary)):
@@ -1159,6 +1371,7 @@ def legendGoogleSheets(SimilarAreaDictionary,path ,pdfpath, spreadsheetId=0):
1159
  lastUsedCol=columnsLen+1
1160
 
1161
  worksheet.adjust_column_width(start=2,end=3)
 
1162
  # if splittedpdfpath[-2].startswith('1.0'):
1163
  worksheet.adjust_column_width(start=4,end=9,pixel_size=60)
1164
  startrow = 3
@@ -1213,11 +1426,8 @@ def legendGoogleSheets(SimilarAreaDictionary,path ,pdfpath, spreadsheetId=0):
1213
  }
1214
  res = spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheetId, body=body).execute()
1215
  # if splittedpdfpath[-2].startswith('1.0'):
1216
- endColindex=9
1217
  endrow=3
1218
- # elif splittedpdfpath[-2].startswith('3.2'):
1219
- # endColindex=3
1220
- # endrow=2
1221
  body2={
1222
  "requests": [
1223
  {
@@ -1293,7 +1503,7 @@ def legendGoogleSheets(SimilarAreaDictionary,path ,pdfpath, spreadsheetId=0):
1293
  model_cell.set_text_format('bold', True)
1294
  model_cell.set_horizontal_alignment( pygsheets.custom_types.HorizontalAlignment.CENTER )
1295
  model_cell.color = (213/255, 219/255 ,255/255)
1296
- pygsheets.DataRange('A2','I2', worksheet=worksheet).apply_format(model_cell)
1297
  spreadsheet_url = "https://docs.google.com/spreadsheets/d/%s" % spreadsheetId
1298
  print(spreadsheet_url)
1299
  drive_service.permissions().update(transferOwnership=True , fileId=spreadsheetId,permissionId='11OfoB4Z6wOVII8mYmbnCbbqTQs7rYA65')
 
11
  from matplotlib import pyplot as plt
12
  from math import sin, cos, radians
13
  import pandas as pd
14
+ from PIL import Image , ImageChops
15
  import numpy as np
16
  from googleapiclient.discovery import build
17
  from google.oauth2 import service_account
 
23
  import Dropbox_TSA_API
24
  import tsadropboxretrieval
25
  from collections import Counter
26
+ from unidecode import unidecode
27
 
28
  def textLists(img,dataDoc):
29
  allTexts = texts_from_pdf(dataDoc)
 
44
  listall.append((p1[0],p1[1],tpl[4]))
45
  return pc_coor, listall
46
 
47
+ def textListsAlltexts(dataDoc,span_df):
48
+ listall=[]
49
+ pc_coor = []
50
+ allTexts = texts_from_pdf(dataDoc)
51
+ doc = fitz.open('pdf',dataDoc)
52
+ page=doc[0]
53
+ for i, row in span_df.iterrows():
54
+ p1 = fitz.Point((span_df['xmin'].loc[i]),(span_df['ymin'].loc[i]))
55
+ if page.rotation==0:
56
+ p1=p1*page.derotation_matrix
57
+ pc_coor.append((p1[0],p1[1]))
58
+ listall.append((p1[0],p1[1],span_df['text'].loc[i]))
59
+ return pc_coor, listall
60
+ # pc_coor,listall=textLists(img)
61
+
62
+
63
  #Prepare preprocessing
64
  def detectCircles(imgOriginal ):
65
  im=imgOriginal.copy()
66
  imgGry1 = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
67
  kernel=np.ones((3,3),np.uint8)
68
  er1=cv2.erode(imgGry1,kernel, iterations=2)
69
+ er1=cv2.dilate(er1,kernel, iterations=2)
70
+ # cv2_imshow(er1)
71
+ # Apply Hough transform on the blurred image.
72
+ # min distance between circles, Upper threshold for the internal Canny edge detector.
73
+ detected_circles = cv2.HoughCircles( er1, cv2.HOUGH_GRADIENT, 1, 50, param1= 700,
74
  param2 =21, minRadius = 20, maxRadius = 50) #18 param2
75
+
76
  # Draw circles that are detected.
77
  if detected_circles is not None:
78
  # Convert the circle parameters a, b and r to integers.
79
  detected_circles = np.uint16(np.around(detected_circles))
80
  detected_circles = np.round(detected_circles[0, :]).astype("int")
 
81
  for (x, y, r) in detected_circles:
82
+ cv2.circle(im, (x, y), r, (255, 255, 255), 6)
83
  return im
84
 
85
+
86
+
87
  def detectSmallCircles(img ):
88
  #Remove tiny TOC points that interfere with shapes
89
  im=img.copy()
 
141
  green=im_copy[:,:,1]
142
  return green
143
 
144
+
145
+ def removeSmallDashes(imgOriginal,green,num=0):
146
  smalldashes=green.copy()
147
  smalldashes=cv2.bitwise_not(smalldashes)
148
 
149
  kernel3= np.ones((3,3),np.uint8)
150
+
151
  img1=cv2.dilate(smalldashes, kernel3, iterations=2)
152
  img2=cv2.erode(img1, kernel3, iterations=2)
153
 
154
  smalldashes=cv2.medianBlur(img2,7)
155
  smalldashes=cv2.medianBlur(smalldashes,9)
156
+
157
  smalldashesOut=green.copy()
158
+
159
+ # if num==1:
160
+ # smalldashes=cv2.cvtColor(smalldashes,cv2.COLOR_GRAY2BGR)
161
+ # smalldashes=detectSmallCircles(smalldashes)
162
+ # smalldashes=cv2.cvtColor(smalldashes,cv2.COLOR_BGR2GRAY)
163
  smalldashesOut=cv2.cvtColor(smalldashesOut,cv2.COLOR_GRAY2BGR)
164
+ imgLines= cv2.HoughLinesP(smalldashes,1,np.pi/180,27,minLineLength=70,maxLineGap = 70) #was w-h , gap=150
165
 
166
  imgCopy=imgOriginal.copy()
167
  for i in range(len(imgLines)):
168
  for x1,y1,x2,y2 in imgLines[i]:
169
  cv2.line(smalldashesOut,(x1,y1),(x2,y2),(0,255,0),3)
170
+ cv2.line(imgCopy,(x1,y1),(x2,y2),(0,255,0),2)
 
 
 
 
 
 
 
171
  imgCopy=imgCopy[:,:,1]
172
+ smalldashesOut=smalldashesOut[:,:,1]
173
  return imgCopy,smalldashesOut
174
 
175
+
176
  def euclidian_distance(point1, point2):
177
  return sum([(point1[x] - point2[x]) ** 2 for x in range(len(point1))]) ** 0.5
178
 
 
188
  green=im_copy[:,:,1]
189
  return green
190
 
191
+ def ConnectBeamLines(smalldashesOut, maxLineGap=0):
192
+ if maxLineGap==0:
193
+ maxLineGap=25
194
+ thresh=20
195
+ point=0.3
196
+ else:
197
+ thresh=20
198
+ point=0.2
199
+ maxLineGap=40
200
+ print(maxLineGap)
201
  green1=cv2.bitwise_not(smalldashesOut)
202
+ smalldashesOut=cv2.cvtColor(smalldashesOut,cv2.COLOR_GRAY2BGR)
203
+ imgLines= cv2.HoughLinesP(green1,point,np.pi/180,thresh,minLineLength=25,maxLineGap =maxLineGap) #try 180
 
204
  for i in range(len(imgLines)):
205
  for x1,y1,x2,y2 in imgLines[i]:
206
+ cv2.line(smalldashesOut,(x1,y1),(x2,y2),(0,0,0),2)
207
+ return smalldashesOut
208
+
209
+ def getImgDark(imgg):
210
+ imgold=preprocessold(imgg,0)
211
+ blurG = cv2.GaussianBlur(ChangeBrightness(imgg,1),(3,3),0 )
212
+ imgGry = cv2.cvtColor(blurG, cv2.COLOR_BGR2GRAY)
213
+ ret3, thresh = cv2.threshold(imgGry, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
214
+ imgold=cv2.medianBlur(imgold,3)
215
+ thresh=cv2.bitwise_or(thresh,imgold)
216
+ imgDark=cv2.bitwise_not(thresh)
217
+ imgDark = cv2.cvtColor(imgDark, cv2.COLOR_GRAY2BGR)
218
+ return imgDark
219
+
220
  #create img with solid lines
221
+ def allpreSteps(imgOriginal,num=0):
222
  noCircles=detectCircles(imgOriginal)
223
+ imgold=preprocessold(imgOriginal,0)
224
+ if num!=1:
225
+ imgnoSmall=detectSmallCircles(noCircles )
226
+ img4,imgBW,max,min=DashedPreprocessing(imgOriginal,imgnoSmall)
227
+ green=removeDashedLines(img4,imgBW,max,min)
228
+ imgCopy,smalldashesOut=removeSmallDashes(imgOriginal,green)
229
+ noSmallDashes=removeDashedLinesSmall(img4, smalldashesOut ,max,min)
230
+ green2=ConnectBeamLines(noSmallDashes,0)
231
+
232
+ return green2
233
+ else:
234
+ #imgDark with no dashed lines or small dashes
235
+ print('p1')
236
+ imgDark1=getImgDark(noCircles)
237
+ print('p11')
238
+ img4,imgBW,max,min=DashedPreprocessing(imgOriginal,noCircles)
239
+ imgDarkNoDashedLines=removeDashedLines(img4,imgDark1,max,min) #do preprocessing on normal img , and draw on darkimg
240
+ imgBW0 = cv2.cvtColor(imgBW, cv2.COLOR_BGR2GRAY)
241
+ imgDarkNoDashedLines = cv2.cvtColor(imgDarkNoDashedLines, cv2.COLOR_GRAY2BGR)
242
+ imgDarkNoDashedLines,smalldashesOut0=removeSmallDashes(imgDarkNoDashedLines,imgBW0)
243
+ print('p2')
244
+ #imgOld no small dashes - for oring purposes
245
+ imgoldG = cv2.cvtColor(imgold, cv2.COLOR_GRAY2BGR)
246
+ imgoldnoDashes,_=removeSmallDashes(cv2.bitwise_not(imgoldG),imgBW0,1)
247
+ print('p3')
248
+ #to connect leader lines after removing dashed lines and circles
249
+ Nodashedlines=removeDashedLines(img4,imgBW,max,min)
250
+ imgCopy,smalldashesOut=removeSmallDashes(imgOriginal,Nodashedlines)
251
+
252
+ noSmallDashes=removeDashedLinesSmall(img4, smalldashesOut ,max,min)
253
+ green2=ConnectBeamLines(noSmallDashes,1)
254
+
255
+ green2 = cv2.cvtColor(green2, cv2.COLOR_BGR2GRAY)
256
+ green2=cv2.bitwise_or(cv2.bitwise_not(imgDarkNoDashedLines),cv2.bitwise_not(green2) )
257
+ green2=cv2.bitwise_not(green2)
258
+ # cv2_imshow(green2)
259
+ green2=cv2.medianBlur(green2,5)
260
+ # cv2_imshow(green2)
261
+ imgoldnoDashes=cv2.medianBlur(imgoldnoDashes,5)
262
+ print('p4')
263
+ return green2 , cv2.bitwise_not(imgoldnoDashes)
264
 
 
 
265
 
266
+ def texts_from_pdf(input_pdf):
267
+ pdf_document = fitz.open('pdf',input_pdf)
268
  for page_num in range(pdf_document.page_count):
269
  page = pdf_document[page_num]
270
  text_instances = page.get_text("words")
271
  page.apply_redactions()
272
  return text_instances
273
 
274
+
275
+ def textDictionaryBlocks(img,dataDoc):
276
+ doc = fitz.open('pdf',dataDoc)
277
+ page=doc[0]
278
+ if page.rotation!=0:
279
+ page.set_rotation(0)
280
+ pix = page.get_pixmap() # render page to an image
281
+ ratio = pix.width/ img.shape[1]
282
+
283
+ block_dict = {}
284
+ page_num = 1
285
+ for page in doc: # Iterate all pages in the document
286
+ file_dict = page.get_text('dict') # Get the page dictionary
287
+ block = file_dict['blocks'] # Get the block information
288
+ block_dict[page_num] = block # Store in block dictionary
289
+ page_num += 1 # Increase the page value by 1
290
+ spans = pd.DataFrame(columns=['xmin', 'ymin', 'xmax', 'ymax', 'text','FitzPointP0','FitzPointP1'])
291
+ rows = []
292
+ for page_num, blocks in block_dict.items():
293
+ for block in blocks:
294
+ if block['type'] == 0:
295
+ for line in block['lines']:
296
+ for span in line['spans']:
297
+ xmin, ymin, xmax, ymax = list(span['bbox'])
298
+ text = unidecode(span['text'])
299
+ XminRatio=xmin/ratio
300
+ YminRatio=ymin/ratio
301
+ p1=fitz.Point((XminRatio),(YminRatio))
302
+ if page.rotation==0:
303
+ p1=p1*page.derotation_matrix
304
+ if text.replace(" ","") != "":
305
+ rows.append((XminRatio,YminRatio, xmax /ratio, ymax/ratio, text,p1[0],p1[1]))
306
+ span_df = pd.DataFrame(rows, columns=['xmin','ymin','xmax','ymax', 'text','FitzPointP0','FitzPointP1'])
307
+ return span_df
308
+
309
+ def nearestText(a,b,span_df):
310
+ allNearbyText=[]
311
+ shapeTexts=[]
312
+ for i, row in span_df.iterrows():
313
+ measuredDist=euclidian_distance((a,b),(span_df['FitzPointP0'].loc[i],span_df['FitzPointP1'].loc[i]))
314
+ if measuredDist < 250:
315
+ allNearbyText.append((span_df['FitzPointP0'].loc[i],span_df['FitzPointP1'].loc[i] ))
316
+ shapeTexts.append(str(span_df['text'].loc[i]))
317
+ if len(allNearbyText)==0:
318
+ allNearbyText='none'
319
+ return allNearbyText , shapeTexts
320
+
321
+ def nearestTextPCCOOR(a,b , pc_coor):
322
  nearest_point=min(pc_coor,key=lambda x:euclidian_distance((a,b),x))
323
  dist = euclidian_distance(nearest_point, (a,b))
324
  if dist < 400: #distance threshold
 
352
  for x1,y1,x2,y2 in imgLines[i]:
353
  cv2.line(blackwithNoDot,(x1,y1),(x2,y2),(255,255,255),2)
354
  return blackwithNoDot
355
+
356
+ def getDiff(img,green22,imgoldnodashes):
357
+ # green22 , imgoldnoDashes= allpreSteps(img,1)
358
+ imgoldnoDashes1=cv2.medianBlur(imgoldnodashes,7)
359
+ kernel=np.ones((3,3),np.uint8)
360
+ green3=cv2.erode(green22,kernel, iterations=6)
361
+ green3=cv2.dilate(green3,kernel, iterations=3)
362
+ imgoldnoDashes1=cv2.erode(imgoldnoDashes1,kernel, iterations=2)
363
+ img1Eroded=cv2.dilate(imgoldnoDashes1,kernel, iterations=7) #5
364
+ diff = ImageChops.difference(Image.fromarray(img1Eroded), Image.fromarray(cv2.bitwise_not(green3)))
365
+ diff=np.array(diff)
366
+ diff=cv2.erode(diff,kernel, iterations=4)
367
+ diff=cv2.dilate(diff,kernel, iterations=11)
368
+ return diff
369
+
370
+
371
  #OLD method (White shapes)
372
  def preprocessold(img,number):
373
+ blurG = cv2.GaussianBlur(ChangeBrightness(img,8),(3,3),0 )
374
+ cv2.imwrite('imgold.png', blurG)
375
  imgGry = cv2.cvtColor(blurG, cv2.COLOR_BGR2GRAY)
376
  kernel=np.ones((3,3),np.uint8)
377
  er1=cv2.dilate(imgGry,kernel, iterations=2) #thinning
 
381
  ret3, thresh = cv2.threshold(er1, 220, 255, cv2.THRESH_BINARY_INV) #`140 - 141
382
  return thresh
383
 
384
+ #preprocessing for shapes with arrows (attach them to shape )
385
+ def getTextfromImg(grayimgtextdilated, img,dataDoc):
386
+ span_df=textDictionaryBlocks(img,dataDoc)
387
+ threshCnt2, threshHier2 = cv2.findContours(grayimgtextdilated, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
388
+ allshapesExtremes_Text=[]
389
+ listallTexts=textListsAlltexts(dataDoc,span_df)[1]
390
+ for cnt in threshCnt2:
391
+ texts=[]
392
+ area1 = cv2.contourArea(cnt)
393
+ if (area1 >2000 ):
394
+ x, y , width, height = cv2.boundingRect(cnt)
395
+ perimeter=cv2.arcLength(cnt,True)
396
+ approx = cv2.approxPolyDP(cnt, 0.01* perimeter, True)
397
+ for extremePoint in approx:
398
+ allnearbyPoints,alltxts=nearestText(int(extremePoint[0][0]),int(extremePoint[0][1]),span_df)
399
+ if(allnearbyPoints!='none'):
400
+ for nearbypoint in allnearbyPoints:
401
+ for textTuple in listallTexts:
402
+ if nearbypoint[0]==textTuple[0] and nearbypoint[1]==textTuple[1]:
403
+ if textTuple[2] not in texts:
404
+ texts.append(textTuple[2])
405
+ allshapesExtremes_Text.append([cnt,texts])
406
+ # print(allshapesExtremes_Text)
407
+ ArrthreshCnt=[]
408
+ for th in range(len(allshapesExtremes_Text)):
409
+ eachcnt=[]
410
+ for point in allshapesExtremes_Text[th][0]:
411
+ eachcnt.append(list(point[0]))
412
+ ArrthreshCnt.append(eachcnt)
413
+ return ArrthreshCnt , allshapesExtremes_Text
414
+
415
+
416
+ def mergingPreprocessing(img,number,green2,layeredflag,BlackmaskDetected1=0):
417
+ # diff , imgoldnodashes=getDiff(img)#diff (img with tof leaders)
418
  img1=preprocessold(img,number)
419
+
420
+ green2Gray = cv2.cvtColor(green2, cv2.COLOR_BGR2GRAY)
421
+ anding=cv2.bitwise_and(green2Gray,img1) #and between old and green2 to get perfect shapes with no outer lines
422
  ret3, thresh2 = cv2.threshold(anding, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
 
423
  if layeredflag.startswith('layer'):
424
  thresh2=cv2.bitwise_and(thresh2,thresh2,mask=BlackmaskDetected1)
425
  threshcontours, threshHier = cv2.findContours(thresh2, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
426
+
427
+ return img1 , threshcontours , thresh2
428
+
429
+ #anding of old method output with solid lines img
430
+ def preprocess(green22,imgoldnodashes,dataDoc,imgtransparent1,img,number,green2,layeredflag,BlackmaskDetected1=0):
431
+ #first preprocessing ( old method - black img with white shapes)
432
+ kernel0=np.ones((2,2),np.uint8)
433
+ ##first preprocessing ( old method - black img with white shapes)
434
+ img1,threshcontours,thresh2=mergingPreprocessing(img,number,green2,layeredflag,BlackmaskDetected1)
435
+ diff =getDiff(img,green22,imgoldnodashes)#diff (img with tof leaders)
436
+ iddk=cv2.bitwise_or(thresh2,diff) #add it to preprocessing img of anding
437
+ iddk=cv2.medianBlur(iddk,5)
438
+ iddk=cv2.dilate(iddk,kernel0, iterations=2)
439
+ ArrthreshCnt , texts=getTextfromImg(iddk,img,dataDoc) #getText relations between each contour and its text
440
  outlinesDotIN=getOutlinesDotIN(img)
441
+ pc_coor,listall=textLists(img,dataDoc)
442
+ finalcntsP=[]
443
+ finalcntsA=[]
444
  perimeters=[]
445
  openClosedFlag=0
446
  threshCnt, threshHier2 = cv2.findContours(img1, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
 
449
  area1 = cv2.contourArea(cnt)
450
  if (area1 > 2000 ):
451
  cv2.drawContours(outlines,[cnt],0,(255,255,255),2)
 
452
  perimeter=0
453
+ shapetxts=[]
454
  for cnt in threshcontours:
455
+ BlackmaskP = np.zeros(img.shape[:2], dtype="uint8")
456
+ BlackmaskA=np.zeros(img.shape[:2], dtype="uint8")
457
  area1 = cv2.contourArea(cnt)
458
  if (area1 > 2000 ):
459
  x, y , width, height = cv2.boundingRect(cnt)
460
+ #Get contours - Areas , Perimeters
461
+ kernel=np.ones((2,2),np.uint8)
462
+
463
+ cv2.drawContours(BlackmaskP,[cnt],0,(255,255,255), 6)
464
+ BlackmaskP=cv2.dilate(BlackmaskP,kernel, iterations=1)
465
+ contoursP, hier1 = cv2.findContours(BlackmaskP, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
466
+ finalcntsP.append(contoursP)
467
+
468
+ cv2.drawContours(BlackmaskA,[cnt],0,(255,255,255), 5)
469
+ BlackmaskA=cv2.erode(BlackmaskA,kernel, iterations=1)
470
+ contoursA, hier1 = cv2.findContours(BlackmaskA, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
471
+ finalcntsA.append(contoursA)
472
+
473
+ textPoint=nearestTextPCCOOR(int(x+(width/2)), int(y+(height/2)) , pc_coor)
474
  txt=''
475
  if(textPoint!='none'):
476
  for textTuple in listall:
477
  if textPoint[0]==textTuple[0] and textPoint[1]==textTuple[1]:
478
  txt=textTuple[2]
479
+ if "GB" in txt or "RC" in txt or "PC" in txt:
480
+ shapetxts.append(txt)
481
  elif textPoint=='none':
482
+ shapetxts.append('none')
483
+
484
+ if 'GB' in shapetxts:
485
+ xcBlk, ycBlk , width, height = cv2.boundingRect(contoursP[0])
486
+ xx=cv2.bitwise_and(outlines,outlines,mask=BlackmaskP)
487
+ xx = cv2.threshold(xx, 250, 255, cv2.THRESH_BINARY)[1]
488
+ cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
489
+ if len(cntsx)>0:
490
+ hierx=hierx[0]
491
+ xx=cv2.bitwise_and(outlinesDotIN,outlinesDotIN,mask=xx)
492
  cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
493
  if len(cntsx)>0:
494
+ xx=connectsmallDot(xx)
 
495
  cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
496
  if len(cntsx)>0:
497
+ hierx=hierx[0]
498
+ for comp in zip(cntsx,hierx):
499
+ c=comp[0]
500
+ h=comp[1]
501
+ xc, yc , width, height = cv2.boundingRect(c)
502
+ perimeter=cv2.arcLength(c,True)
503
+ shape=[]
504
+ approx = cv2.approxPolyDP(c, 0.003* perimeter, True)
505
+ if h[2]<0 and h[3] <0:
506
+ perimeter1 = cv2.arcLength(approx, True)
507
+ perimeter=perimeter1/2
508
+ # cv2_imshow(xx)
509
+ openClosedFlag='open'
510
+ imgtransparent1=cv2.polylines(imgtransparent1, [approx], False, (0,255,0), thickness=4,lineType=8)
511
+ perimeters.append([xc, yc ,xcBlk, ycBlk ,perimeter ,openClosedFlag , approx])
512
+ else:
513
+ if h[2] >0:
514
+ openClosedFlag='closed'
515
+
516
+ return tuple(finalcntsP),tuple(finalcntsA), perimeters , shapetxts , imgtransparent1 ,ArrthreshCnt , texts, iddk
517
+
 
 
 
 
 
 
 
 
 
 
 
 
518
 
519
  """# ROI (levels)
520
  ## Detect regions with specific color and mask them
 
552
  cv2.imwrite('det.png',detectedColors)
553
  return mask, detectedColors, color
554
 
555
+ def getinnerColor(BlackmaskDetected,img,detectedColors,finalColorArray,ratioarea,ratioperim,eachcolor):
556
 
557
  countBlackMasks=0
558
  xored=detectedColors
 
568
  extrema = pil_image.convert("L").getextrema()
569
  if extrema != (0, 0): # if image is not black --> has a colored mask within
570
  cc=detectedColors.copy()
 
571
  ColoredContour, Coloredhierarchy = cv2.findContours(masked, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
 
572
  for cnt in ColoredContour:
 
573
  area1 = cv2.contourArea(cnt)
574
  if (area1 > 1000 ):
575
 
576
  x, y , width, height = cv2.boundingRect(cnt)
 
 
 
577
  cv2.drawContours(cc,[cnt],0,(255,255,255), 3)
578
  cv2.drawContours(Blackmask,[cnt] ,0, (255,255,255), 3)
 
579
  cv2.drawContours(cc,[cnt],0,(255,255,255), -1) # (x-5,y-5 ), (x+width, y+height),
580
  cv2.drawContours(Blackmask,[cnt] ,0, (255,255,255), -1) #,(x,y ), (x+width, y+height)
 
581
  cv2.drawContours(BlackmaskDetected,[cnt] ,0, (0,0,0), -1) #,(x,y ), (x+width, y+height)
 
582
  invertedmask = cv2.bitwise_and(imgc,imgc, mask= Blackmask)
583
  xored=cc
 
584
  detectedColors=xored
 
585
  else: #black mask , no other levels are found # to check law count == number of colors in array yb2a no more levels and break
586
  countBlackMasks+=1
 
587
  return xored,invertedmask , BlackmaskDetected
588
 
589
  def allLevelsofColor(BlackmaskDetected,img,levelonly, invertedmask,color,finalColorArray):
 
595
  Blackmask = np.zeros(img.shape[:2], dtype="uint8")
596
 
597
  masked,maskedColor,rgbcolor=DetectColor(invertedmask,color)
 
598
  color=[color[0],color[1],color[2]]
 
599
  rgbcolor=[rgbcolor[0],rgbcolor[1],rgbcolor[2]]
600
  print(rgbcolor,color)
601
  pil_image=Image.fromarray(masked)
 
621
  # get (i, j) positions of all RGB pixels that are black (i.e. [0, 0, 0])
622
  firstLevel[np.all(firstLevel == (0,0,0), axis=-1)] = (255, 255, 255)
623
  firstLevel1=cv2.bitwise_and(levelonly,firstLevel)
 
624
 
 
625
  for othercolor in finalColorArray:
626
  # othercolor2=hexRGB(othercolor)
627
  othercolor2=[othercolor[0],othercolor[1],othercolor[2]]
 
645
  # cv2_imshow(Blackmask)
646
  return firstLevel1, BlackmaskDetected
647
 
648
+ def getColoredContour(mask,img,finalColorArray,ratioarea,ratioperim,eachcolor):
649
  ColoredContour, Coloredhierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
650
  Coloredhierarchy=Coloredhierarchy[0]
651
 
 
672
  if extrema == (0, 0) :#and extremaB==(0,0): # if image is not black --> has a colored mask within
673
  break
674
 
675
+ levelOnly,invertedmask,BlackmaskDetected=getinnerColor(Blackmask,img,detectedColors,finalColorArray,ratioarea,ratioperim,eachcolor) #mask inner levels b abyad
676
  firstLevel1, BlackmaskDetected1= allLevelsofColor(BlackmaskDetected,img,levelOnly, invertedmask,eachcolor,finalColorArray)
677
  return firstLevel1,invertedmask, BlackmaskDetected1
678
 
679
  """# contours"""
680
 
681
+ def findContoursFullImage(green22,imgoldnodashes,dataDoc,imgtransparent1,green2,img,number,finalColorArray,ratioarea,ratioperim,color=[0,0,0]):
682
  if number == 0:
683
+ contourssP,contourssA,perimeters,alltxts,imgtransparent1,arrthresh,allshapesExtremes_Text,iddk=preprocess(green22,imgoldnodashes,dataDoc,imgtransparent1,img,number,green2, 'nolayer')
684
+ return contourssP,contourssA, perimeters ,alltxts , imgtransparent1,arrthresh,allshapesExtremes_Text , iddk
685
  else:
686
  mask, detectedColors, rgbcolor =DetectColor(img,color)
687
  pil_image=Image.fromarray(mask)
688
  extrema = pil_image.convert("L").getextrema()
689
  if extrema != (0, 0): # if image is not black --> has a colored mask within
690
+ coloredregions,invertedmask,BlackmaskDetected1=getColoredContour(mask,img,finalColorArray,ratioarea,ratioperim,color)
691
 
692
+ contourssP,contourssA,perimeters,alltxts,imgtransparent1,arrthresh,allshapesExtremes_Text,iddk=preprocess(green22,imgoldnodashes,dataDoc,imgtransparent1,coloredregions,number,green2,'layer',BlackmaskDetected1)
693
+ return contourssP,contourssA ,rgbcolor ,invertedmask , perimeters , alltxts , imgtransparent1 ,arrthresh,allshapesExtremes_Text , iddk
694
  else:
695
+ contourssP,contourssA ,rgbcolor ,invertedmask , perimeters , alltxts , imgtransparent1 ,arrthresh,allshapesExtremes_Text , iddk=preprocess(green22,imgoldnodashes,dataDoc,imgtransparent1,img,number,green2,'nolayer')
696
+ return contourssP,contourssA,color ,mask , perimeters , alltxts,imgtransparent1,arrthresh,allshapesExtremes_Text , iddk
697
 
698
  #Straighten tilted shapes
699
  def StraightenImage(contour,imgArea):
 
707
  return angleR,width,height
708
 
709
  #get all areas and perimeter present
710
+ def getAreasPerimeter(img,ratioarea,ratioperim,contourssP,contourssA):
711
  appended=[]
712
+ for contour in range(len(contourssP)):
713
+ area1 = cv2.contourArea(contourssP[contour][0])
714
  if (area1 >2000 ):
715
+ perimeter= cv2.arcLength(contourssP[contour][0],True)
716
+ approx = cv2.approxPolyDP(contourssP[contour][0], 0.01* perimeter, True)
717
  perimeter1 = cv2.arcLength(approx, True)
718
  approx = cv2.approxPolyDP(contourssA[contour][0], 0.0002* perimeter, True)
719
  area1 = cv2.contourArea(approx)
720
+ x, y , width, height = cv2.boundingRect(contourssP[contour][0])
721
+ angleR,widthR ,heightR= StraightenImage(contourssP[contour][0],img)
722
 
723
  if (angleR != 90.0 and angleR != -90.0 and angleR != 0.0 and angleR != -0.0 ): #inclined b ay degree
724
  width=widthR
 
729
  appended.append([areaa,width,height])
730
  return appended
731
  #fill dictionary with areas and perimeters and occurences
732
+ def FillDictionary(SimilarAreaDictionary,img,ratioarea,ratioperim,contourssP,contourssA,rgbcolor=[0,0,0],color=[0,0,0]):
733
  #fills dictionary with key areas and number of occurences
734
+ areas_Perimeters=sorted(getAreasPerimeter(img,ratioarea,ratioperim,contourssP,contourssA))
735
 
736
  indices=[]
737
  colorRanges=[[255,0,0],[0,0,255],[0,255,255],[0,64,0],[255,204,0],[255,128,64],[255,0,128],[255,128,192],[128,128,255],[128,64,0],[0,255,0],[179,106,179],[115,52,179],[0,128,192],[128,0,128],[128,0,0],[0,128,255],[255,182,128],[255,0,255],[0,0,128],[0,128,64],[255,255,0],[128,0,64],[203,203,106],[128,255,166],[255,128,0],[255,98,98],[90,105,138],[114,10,72],[36,82,78],[225,105,29],[108,62,40],[11,35,75],[42,176,203],[255,153,153],[129,74,138],[99,123,137],[159,179,30],[255,0,0],[0,0,255],[0,255,255],[0,64,0],[255,204,0],[255,128,64],[255,0,128],[255,128,192],[128,128,255],[128,64,0],[0,255,0],[179,106,179],[115,52,179],[0,128,192],[128,0,128],[128,0,0],[0,128,255],[255,182,128],[255,0,255],[0,0,128],[0,128,64],[255,255,0],[128,0,64],[203,203,106],[128,255,166],[255,128,0],[255,98,98],[90,105,138],[114,10,72],[36,82,78],[225,105,29],[108,62,40],[11,35,75],[42,176,203],[255,153,153],[129,74,138],[99,123,137],[159,179,30]]
 
750
  areaPerimeterMax= round(item1,1) + 0.4
751
  # print (areaMin, areaMax)
752
  if color != [0,0,0]: #colored images
753
+ mydata=[[],[rgbcolor[0],rgbcolor[1],rgbcolor[2] ],round(item1,1),width1,height1,1, 0,0,0,0,0,0,'',0,0,0]
754
  else:
755
+ mydata=[[],' ', round(item1,1),width1,height1,1, 0,0,0,0,0,0,'',0,0,0]
756
  myindex= SimilarAreaDictionary.index[((SimilarAreaDictionary['Rounded'] >=areaPerimeterMin) &(SimilarAreaDictionary['Rounded']<=areaPerimeterMax) )].tolist()
757
  if color!= [0,0,0]: #leveled image
758
  checkifColorExists=0 # to check whether this row was found or not( area and color )
 
782
 
783
  return SimilarAreaDictionary, colorsUsed , areas_Perimeters
784
  #detect and draw and measure
785
+ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim , path,pdfpath):
786
  green2=allpreSteps(img)
787
+ green22,imgoldnodashes=allpreSteps(img,num=1)
788
  doc = fitz.open("pdf",dataDoc)
789
  page = doc[0]
790
  rotationOld=page.rotation
 
801
  imgtransparent1=img.copy()
802
 
803
  if number ==220:
804
+ SimilarAreaDictionary= pd.DataFrame(columns=['Guess','Color','Rounded','Width','Height','Occurences','Area','Total Area','Perimeter','Total Perimeter','Length','Total Length','Texts','R','G','B'])
805
+ # firstcolor=finalColorArray[0]
806
+ # counter=0
807
  maskDone=img.copy()
808
  for eachcolor in finalColorArray:
809
+ contourssP,contourssA,rgbcolor,invertedmask , perimeters , alltxts,imgtransparent1 , ArrthreshCnt ,allshapesExtremes_Text, green22Gry=findContoursFullImage(green22,imgoldnodashes,dataDoc,imgtransparent1,green2,maskDone,number,finalColorArray,ratioarea,ratioperim,eachcolor)
810
+ SimilarAreaDictionary, colorsUsed , areas_Perimeters= FillDictionary(SimilarAreaDictionary,maskDone,ratioarea,ratioperim,contourssP,contourssA,rgbcolor,eachcolor)
 
 
 
811
  perimTotal=0
812
+ for contour in range(len(contourssP)):
813
  shape=[]
 
 
814
  area1 = cv2.contourArea(contourssA[contour][0])
 
 
815
  if (area1 > 3500 ): #check perimeter kman fl condition -- 2800
816
+ perimeter=cv2.arcLength(contourssP[contour][0],True)
817
  shape=[]
818
+ angleR,widthR ,heightR= StraightenImage(contourssP[contour][0],imgArea1)
819
+ x, y , width, height = cv2.boundingRect(contourssP[contour][0])
820
+
821
+ Blackmask = np.zeros(img.shape[:2], dtype="uint8")
822
+ Blackmask = cv2.rectangle(Blackmask, (int(x-10),int(y-10)), (int(x+width+10),int(y+height+10)), (255, 255, 255), -1)
823
+ Blackmask=cv2.bitwise_and(green22Gry,green22Gry,mask=Blackmask)
824
+ BlackmaskCnt,_= cv2.findContours(Blackmask, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
825
+ areas = [cv2.contourArea(c) for c in BlackmaskCnt]
826
+ if len(areas)>0:
827
+ max_index = np.argmax(areas)
828
+ blackcnt=BlackmaskCnt[max_index]
829
+ blackcnt=tuple(blackcnt)
830
+ texts=''
831
+ for th in range(len(ArrthreshCnt)):
832
+ for e in blackcnt:
833
+ if list(e[0]) in ArrthreshCnt[th]:
834
+ texts=allshapesExtremes_Text[th][1]
835
+ break
836
+ if len(texts)>0:
837
+ break
838
+
839
  approxA = cv2.approxPolyDP(contourssA[contour][0], 0.0002* perimeter, True)
840
  area1 = cv2.contourArea(approxA)
841
+ approx = cv2.approxPolyDP(contourssP[contour][0], 0.01 * perimeter, True) #0.0009
 
842
  perimeter1 = cv2.arcLength(approx, True)
843
  for point in approxA:
844
  x1, y1 = point[0]
 
873
  if passed ==0:
874
  if SimilarAreaDictionary['Color'].loc[i] == [rgbcolor[0],rgbcolor[1],rgbcolor[2]] and ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) :
875
  if (SimilarAreaDictionary['Width'].loc[i] <=widthMax and SimilarAreaDictionary['Width'].loc[i] >= widthMin) and (SimilarAreaDictionary['Height'].loc[i] <= heightMax and SimilarAreaDictionary['Height'].loc[i] >= heightMin ) or (SimilarAreaDictionary['Width'].loc[i] <=heightMax and SimilarAreaDictionary['Width'].loc[i] >= heightMin) and (SimilarAreaDictionary['Height'].loc[i] <= widthMax and SimilarAreaDictionary['Height'].loc[i] >= widthMin ) :
876
+ SimilarAreaDictionary['Guess'].loc[i].append(str(alltxts[contour]))
877
+ for t in texts:
878
+ if "GB" not in t or "RC" not in t or "PC" not in t:
879
+ if t not in SimilarAreaDictionary['Texts'].loc[i]:
880
+ SimilarAreaDictionary['Texts'].loc[i]+=' '+t
881
  SimilarAreaDictionary['Total Area'].loc[i]+=areaa
882
  SimilarAreaDictionary['Area'].loc[i]=areaa
883
+
884
  pFlagDF=0
885
  color= (int(SimilarAreaDictionary['R'].loc[i])/255 , int(SimilarAreaDictionary['G'].loc[i])/255 , int(SimilarAreaDictionary['B'].loc[i])/255 )
886
 
 
916
  SimilarAreaDictionary['Length'].loc[i]=lengthShape
917
 
918
  passed=1
919
+ cv2.drawContours(imgArea1, [contourssP[contour][0]], 0, ( int(SimilarAreaDictionary['B'].loc[i]), int(SimilarAreaDictionary['G'].loc[i]), int(SimilarAreaDictionary['R'].loc[i])), -1)
920
  annot = page.add_polygon_annot( points=shape) # 'Polygon'
921
  annot.set_border(width=0.2)
922
  annot.set_colors(stroke=color, fill= color )
 
940
  #########################
941
  else:
942
 
943
+ SimilarAreaDictionary= pd.DataFrame(columns=['Guess','Color','Rounded','Width','Height','Occurences','Area','Total Area','Perimeter','Total Perimeter','Length','Total Length','Texts','R','G','B'])
944
+ contourssP,contourssA , perimeters , alltxts , imgtransparent1 , ArrthreshCnt ,allshapesExtremes_Text, green22Gry=findContoursFullImage(green22,imgoldnodashes,dataDoc,imgtransparent1,green2,img,number,finalColorArray,ratioarea,ratioperim)
945
+ SimilarAreaDictionary,colorsUsed , areas_Perimeters= FillDictionary(SimilarAreaDictionary,img,ratioarea,ratioperim,contourssP,contourssA)
 
946
 
947
+ for contour in range(len(contourssP)):
948
  area1 = cv2.contourArea(contourssA[contour][0])
949
  if (area1 >4000 ):
950
+ perimeter=cv2.arcLength(contourssP[contour][0],True)
951
 
952
 
953
  shape=[]
954
+ angleR,widthR ,heightR= StraightenImage(contourssP[contour][0],imgArea1)
955
+ x, y , width, height = cv2.boundingRect(contourssP[contour][0])
956
+
957
+ Blackmask = np.zeros(img.shape[:2], dtype="uint8")
958
+ Blackmask = cv2.rectangle(Blackmask, (int(x-10),int(y-10)), (int(x+width+10),int(y+height+10)), (255, 255, 255), -1)
959
+ Blackmask=cv2.bitwise_and(green22Gry,green22Gry,mask=Blackmask)
960
+ BlackmaskCnt,_= cv2.findContours(Blackmask, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
961
+ areas = [cv2.contourArea(c) for c in BlackmaskCnt]
962
+ if len(areas)>0:
963
+ max_index = np.argmax(areas)
964
+ blackcnt=BlackmaskCnt[max_index]
965
+ blackcnt=tuple(blackcnt)
966
+ texts=''
967
+ # textsMid=''
968
+ for th in range(len(ArrthreshCnt)):
969
+ for e in blackcnt:
970
+ if list(e[0]) in ArrthreshCnt[th]:
971
+ texts=allshapesExtremes_Text[th][1]
972
+ # textsMid=allshapesExtremes_Text[th][2]
973
+ break
974
+ if len(texts)>0:
975
+ break
976
+ # print(texts)
977
  approxA = cv2.approxPolyDP(contourssA[contour][0], 0.0002* perimeter, True)
978
  area1 = cv2.contourArea(approxA)
979
+ approx = cv2.approxPolyDP(contourssP[contour][0], 0.01 * perimeter, True) #0.0009
980
  perimeter1 = cv2.arcLength(approx, True)
981
  for point in approxA:
982
  x1, y1 = point[0]
 
1010
  if passed ==0:
1011
  if ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) :
1012
  if (SimilarAreaDictionary['Width'].loc[i] <=widthMax and SimilarAreaDictionary['Width'].loc[i] >= widthMin) and (SimilarAreaDictionary['Height'].loc[i] <= heightMax and SimilarAreaDictionary['Height'].loc[i] >= heightMin ) or (SimilarAreaDictionary['Width'].loc[i] <=heightMax and SimilarAreaDictionary['Width'].loc[i] >= heightMin) and (SimilarAreaDictionary['Height'].loc[i] <= widthMax and SimilarAreaDictionary['Height'].loc[i] >= widthMin ) :
1013
+ SimilarAreaDictionary['Guess'].loc[i].append(str(alltxts[contour]))
1014
+ for t in texts:
1015
+ if "GB" not in t or "RC" not in t or "PC" not in t:
1016
+ if t not in SimilarAreaDictionary['Texts'].loc[i]:
1017
+ SimilarAreaDictionary['Texts'].loc[i]+=' '+t
1018
  SimilarAreaDictionary['Total Area'].loc[i]+=areaa
1019
  SimilarAreaDictionary['Area'].loc[i]=areaa
1020
+
1021
  pFlagDF=0
1022
  color= (int(SimilarAreaDictionary['R'].loc[i])/255 , int(SimilarAreaDictionary['G'].loc[i])/255 , int(SimilarAreaDictionary['B'].loc[i])/255 )
1023
 
 
1052
  SimilarAreaDictionary['Length'].loc[i]=lengthShape
1053
 
1054
  passed=1
1055
+ cv2.drawContours(imgArea1, [contourssP[contour][0]], 0, ( int(SimilarAreaDictionary['B'].loc[i]), int(SimilarAreaDictionary['G'].loc[i]), int(SimilarAreaDictionary['R'].loc[i])), -1)
1056
  annot = page.add_polygon_annot( points=shape) # 'Polygon'
1057
  annot.set_border(width=0.2)
1058
  annot.set_colors(stroke=color, fill= color )
 
1061
  # annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
1062
  annot.update()
1063
 
1064
+ cv2.putText(imgtransparent1,'Area: '+str(areaa) +' '+str(alltxts[contour])+' m2', (x+50,y-10) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2)
1065
  pFlag=0
1066
 
1067
  for p in perimeters:
 
1324
  'startRowIndex': 0,
1325
  'endRowIndex': 1,
1326
  'startColumnIndex': 0,
1327
+ 'endColumnIndex':10
1328
  }
1329
 
1330
  }}
 
1339
  worksheet.cell((2,4)).value='Areas'
1340
  worksheet.cell((2,6)).value='Perimeters'
1341
  worksheet.cell((2,8)).value='Lengths'
1342
+ worksheet.cell((2,10)).value='Texts'
1343
  second_row_data=['Nr','m2','Total','m','Total','m','Total']
1344
  if splittedpdfpath[-2].startswith('1.0') or splittedpdfpath[-2].startswith('3.2'):
1345
  worksheet.update_row(3,second_row_data,col_offset=2)
 
1352
 
1353
  worksheet.update_col(8,list(SimilarAreaDictionary['Length']),row_offset=3)
1354
  worksheet.update_col(9,list(SimilarAreaDictionary['Total Length']),row_offset=3)
1355
+ worksheet.update_col(10,list(SimilarAreaDictionary['Texts']),row_offset=3)
1356
  if splittedpdfpath[-2].startswith('1.0'):
1357
  colorsUsed=[]
1358
  for i in range(len(SimilarAreaDictionary)):
 
1371
  lastUsedCol=columnsLen+1
1372
 
1373
  worksheet.adjust_column_width(start=2,end=3)
1374
+ worksheet.adjust_column_width(start=10,end=10)
1375
  # if splittedpdfpath[-2].startswith('1.0'):
1376
  worksheet.adjust_column_width(start=4,end=9,pixel_size=60)
1377
  startrow = 3
 
1426
  }
1427
  res = spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheetId, body=body).execute()
1428
  # if splittedpdfpath[-2].startswith('1.0'):
1429
+ endColindex=10
1430
  endrow=3
 
 
 
1431
  body2={
1432
  "requests": [
1433
  {
 
1503
  model_cell.set_text_format('bold', True)
1504
  model_cell.set_horizontal_alignment( pygsheets.custom_types.HorizontalAlignment.CENTER )
1505
  model_cell.color = (213/255, 219/255 ,255/255)
1506
+ pygsheets.DataRange('A2','J2', worksheet=worksheet).apply_format(model_cell)
1507
  spreadsheet_url = "https://docs.google.com/spreadsheets/d/%s" % spreadsheetId
1508
  print(spreadsheet_url)
1509
  drive_service.permissions().update(transferOwnership=True , fileId=spreadsheetId,permissionId='11OfoB4Z6wOVII8mYmbnCbbqTQs7rYA65')