Spaces:
Sleeping
Sleeping
Update pilecaps_adr.py
Browse files- 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 |
-
|
| 54 |
-
|
|
|
|
|
|
|
| 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),
|
| 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 |
-
|
|
|
|
| 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 |
-
|
| 136 |
smalldashesOut=green.copy()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
smalldashesOut=cv2.cvtColor(smalldashesOut,cv2.COLOR_GRAY2BGR)
|
| 138 |
-
imgLines= cv2.HoughLinesP(smalldashes,1,np.pi/
|
| 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 |
-
|
| 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 |
-
|
| 174 |
-
|
| 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(
|
| 179 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
#create img with solid lines
|
| 181 |
-
def allpreSteps(imgOriginal):
|
| 182 |
noCircles=detectCircles(imgOriginal)
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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,
|
|
|
|
| 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 |
-
#
|
| 248 |
-
def
|
| 249 |
-
|
| 250 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 251 |
img1=preprocessold(img,number)
|
| 252 |
-
|
| 253 |
-
|
|
|
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 260 |
outlinesDotIN=getOutlinesDotIN(img)
|
| 261 |
-
|
|
|
|
|
|
|
| 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 |
-
|
|
|
|
| 274 |
area1 = cv2.contourArea(cnt)
|
| 275 |
if (area1 > 2000 ):
|
| 276 |
x, y , width, height = cv2.boundingRect(cnt)
|
| 277 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
|
|
|
| 284 |
elif textPoint=='none':
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
cv2.
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
xx
|
| 295 |
cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
|
| 296 |
if len(cntsx)>0:
|
| 297 |
-
|
| 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 |
-
|
| 302 |
-
cntsx,hierx
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
| 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,
|
| 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,
|
| 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,
|
| 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,
|
| 514 |
if number == 0:
|
| 515 |
-
|
| 516 |
-
return
|
| 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,
|
| 523 |
|
| 524 |
-
|
| 525 |
-
return
|
| 526 |
else:
|
| 527 |
-
|
| 528 |
-
return
|
| 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,
|
| 543 |
appended=[]
|
| 544 |
-
for contour in range(len(
|
| 545 |
-
area1 = cv2.contourArea(
|
| 546 |
if (area1 >2000 ):
|
| 547 |
-
perimeter= cv2.arcLength(
|
| 548 |
-
approx = cv2.approxPolyDP(
|
| 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(
|
| 553 |
-
angleR,widthR ,heightR= StraightenImage(
|
| 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,
|
| 565 |
#fills dictionary with key areas and number of occurences
|
| 566 |
-
areas_Perimeters=sorted(getAreasPerimeter(img,ratioarea,ratioperim,
|
| 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
|
| 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 |
-
|
| 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(
|
| 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(
|
| 655 |
shape=[]
|
| 656 |
-
angleR,widthR ,heightR= StraightenImage(
|
| 657 |
-
x, y , width, height = cv2.boundingRect(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 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, [
|
| 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 |
-
|
| 760 |
-
|
| 761 |
-
SimilarAreaDictionary,colorsUsed , areas_Perimeters= FillDictionary(SimilarAreaDictionary,img,ratioarea,ratioperim,contourss,contourssA)
|
| 762 |
|
| 763 |
-
for contour in range(len(
|
| 764 |
area1 = cv2.contourArea(contourssA[contour][0])
|
| 765 |
if (area1 >4000 ):
|
| 766 |
-
perimeter=cv2.arcLength(
|
| 767 |
|
| 768 |
|
| 769 |
shape=[]
|
| 770 |
-
angleR,widthR ,heightR= StraightenImage(
|
| 771 |
-
x, y , width, height = cv2.boundingRect(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 772 |
approxA = cv2.approxPolyDP(contourssA[contour][0], 0.0002* perimeter, True)
|
| 773 |
area1 = cv2.contourArea(approxA)
|
| 774 |
-
approx = cv2.approxPolyDP(
|
| 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 |
-
|
| 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, [
|
| 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':
|
| 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=
|
| 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','
|
| 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')
|