Spaces:
Sleeping
Sleeping
| # -*- coding: utf-8 -*- | |
| """Copy of XOR- ROI from plan-PileCaps-ADR.ipynb | |
| Automatically generated by Colaboratory. | |
| Original file is located at | |
| https://colab.research.google.com/drive/16RHtRae7VU_fqHMAjOUL4ET5slEFo3pf | |
| """ | |
| import numpy as np | |
| import cv2 | |
| from matplotlib import pyplot as plt | |
| from math import sin, cos, radians | |
| import pandas as pd | |
| from PIL import Image , ImageChops | |
| import numpy as np | |
| from googleapiclient.discovery import build | |
| from google.oauth2 import service_account | |
| import pygsheets | |
| import re | |
| import fitz | |
| import db | |
| import ast | |
| import Dropbox_TSA_API | |
| import tsadropboxretrieval | |
| from collections import Counter | |
| from unidecode import unidecode | |
| import google_sheet_Legend | |
| def textLists(img,dataDoc): | |
| allTexts = texts_from_pdf(dataDoc) | |
| doc = fitz.open('pdf',dataDoc) | |
| page=doc[0] | |
| if page.rotation!=0: | |
| page.set_rotation(0) | |
| pix = page.get_pixmap() # render page to an image | |
| ratio = pix.width/ img.shape[1] | |
| listall=[] | |
| pc_coor = [] | |
| for tpl in allTexts: | |
| if "GB" in tpl[4] or "RC" in tpl[4] or "PC" in tpl[4]: | |
| p1 = fitz.Point((tpl[2]/ratio),(tpl[3]/ratio)) | |
| if page.rotation==0: | |
| p1=p1*page.derotation_matrix | |
| pc_coor.append((p1[0],p1[1])) | |
| listall.append((p1[0],p1[1],tpl[4])) | |
| return pc_coor, listall | |
| def textListsAlltexts(dataDoc,span_df): | |
| listall=[] | |
| pc_coor = [] | |
| allTexts = texts_from_pdf(dataDoc) | |
| doc = fitz.open('pdf',dataDoc) | |
| page=doc[0] | |
| for i, row in span_df.iterrows(): | |
| p1 = fitz.Point((span_df['xmin'].loc[i]),(span_df['ymin'].loc[i])) | |
| if page.rotation==0: | |
| p1=p1*page.derotation_matrix | |
| pc_coor.append((p1[0],p1[1])) | |
| listall.append((p1[0],p1[1],span_df['text'].loc[i])) | |
| return pc_coor, listall | |
| # pc_coor,listall=textLists(img) | |
| #Prepare preprocessing | |
| def detectCircles(imgOriginal ): | |
| im=imgOriginal.copy() | |
| imgGry1 = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) | |
| kernel=np.ones((3,3),np.uint8) | |
| er1=cv2.erode(imgGry1,kernel, iterations=2) | |
| er1=cv2.dilate(er1,kernel, iterations=2) | |
| # cv2_imshow(er1) | |
| # Apply Hough transform on the blurred image. | |
| # min distance between circles, Upper threshold for the internal Canny edge detector. | |
| detected_circles = cv2.HoughCircles( er1, cv2.HOUGH_GRADIENT, 1, 50, param1= 700, | |
| param2 =21, minRadius = 20, maxRadius = 50) #18 param2 | |
| # Draw circles that are detected. | |
| if detected_circles is not None: | |
| # Convert the circle parameters a, b and r to integers. | |
| detected_circles = np.uint16(np.around(detected_circles)) | |
| detected_circles = np.round(detected_circles[0, :]).astype("int") | |
| for (x, y, r) in detected_circles: | |
| cv2.circle(im, (x, y), r, (255, 255, 255), 6) | |
| return im | |
| def detectSmallCircles(img ): | |
| #Remove tiny TOC points that interfere with shapes | |
| im=img.copy() | |
| imgGry1 = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) | |
| kernel=np.ones((3,3),np.uint8) | |
| er1=cv2.erode(imgGry1,kernel, iterations=1) | |
| # Apply Hough transform on the blurred image. | |
| # min distance between circles, Upper threshold for the internal Canny edge detector. | |
| detected_circles = cv2.HoughCircles( imgGry1, cv2.HOUGH_GRADIENT, 1, 60, param1 =550, | |
| param2 =13, minRadius = 1, maxRadius = 15) #18 param2 | |
| # Draw circles that are detected. | |
| if detected_circles is not None: | |
| # Convert the circle parameters a, b and r to integers. | |
| detected_circles = np.uint16(np.around(detected_circles)) | |
| detected_circles = np.round(detected_circles[0, :]).astype("int") | |
| #DRAW CIRCLES | |
| for (x, y, r) in detected_circles: | |
| cv2.circle(im, (x, y), r+3, (255, 255, 255), -1) | |
| return im | |
| def DashedPreprocessing(imgOriginal,imgnoSmall): | |
| h,w=imgOriginal.shape[0:2] | |
| #remove the gray contours from the plan | |
| imgBW=cv2.threshold(imgnoSmall, 180, 255, cv2.THRESH_BINARY)[1] | |
| im_copy=imgBW.copy() | |
| im_copy1=im_copy | |
| kernel1 = np.ones((3,5),np.uint8) | |
| kernel2 = np.ones((9,9),np.uint8) | |
| kernel3= np.ones((3,3),np.uint8) | |
| imgGray=cv2.cvtColor(imgBW,cv2.COLOR_BGR2GRAY) | |
| imgBW1=cv2.threshold(imgGray, 200, 255, cv2.THRESH_BINARY_INV)[1] | |
| img1=cv2.erode(imgBW1, kernel1, iterations=1) | |
| img2=cv2.dilate(img1, kernel2, iterations=3) | |
| img3 = cv2.bitwise_and(imgBW1,img2) | |
| img3= cv2.bitwise_not(img3) | |
| img4 = cv2.bitwise_and(imgBW1,imgBW1,mask=img3) | |
| img4=cv2.blur(img4,(7,7)) | |
| if h > w : | |
| max = h | |
| min = w | |
| else: | |
| max = w | |
| min = h | |
| return img4, imgBW, max,min | |
| def removeDashedLines(img4, imgBW ,max,min): | |
| imgLines= cv2.HoughLinesP(img4,1,np.pi/310,30,minLineLength=(max-min)//1.8,maxLineGap = 120) #was w-h , gap=150 0.99 | |
| for i in range(len(imgLines)): | |
| for x1,y1,x2,y2 in imgLines[i]: | |
| cv2.line(imgBW,(x1,y1),(x2,y2),(0,255,0),3) | |
| im_copy=imgBW.copy() | |
| green=im_copy[:,:,1] | |
| return green | |
| def removeSmallDashes(imgOriginal,green,num=0): | |
| smalldashes=green.copy() | |
| smalldashes=cv2.bitwise_not(smalldashes) | |
| kernel3= np.ones((3,3),np.uint8) | |
| img1=cv2.dilate(smalldashes, kernel3, iterations=2) | |
| img2=cv2.erode(img1, kernel3, iterations=2) | |
| smalldashes=cv2.medianBlur(img2,7) | |
| smalldashes=cv2.medianBlur(smalldashes,9) | |
| smalldashesOut=green.copy() | |
| # if num==1: | |
| # smalldashes=cv2.cvtColor(smalldashes,cv2.COLOR_GRAY2BGR) | |
| # smalldashes=detectSmallCircles(smalldashes) | |
| # smalldashes=cv2.cvtColor(smalldashes,cv2.COLOR_BGR2GRAY) | |
| smalldashesOut=cv2.cvtColor(smalldashesOut,cv2.COLOR_GRAY2BGR) | |
| imgLines= cv2.HoughLinesP(smalldashes,1,np.pi/180,27,minLineLength=70,maxLineGap = 70) #was w-h , gap=150 | |
| imgCopy=imgOriginal.copy() | |
| for i in range(len(imgLines)): | |
| for x1,y1,x2,y2 in imgLines[i]: | |
| cv2.line(smalldashesOut,(x1,y1),(x2,y2),(0,255,0),3) | |
| cv2.line(imgCopy,(x1,y1),(x2,y2),(0,255,0),2) | |
| imgCopy=imgCopy[:,:,1] | |
| smalldashesOut=smalldashesOut[:,:,1] | |
| return imgCopy,smalldashesOut | |
| def euclidian_distance(point1, point2): | |
| return sum([(point1[x] - point2[x]) ** 2 for x in range(len(point1))]) ** 0.5 | |
| def removeDashedLinesSmall(img4, imgBW ,max,min): | |
| imgBW=cv2.cvtColor(imgBW,cv2.COLOR_GRAY2BGR) | |
| imgLines= cv2.HoughLinesP(img4,1,np.pi/100,20,minLineLength=(max-min)//3.5,maxLineGap = 70) #2.1 | |
| for i in range(len(imgLines)): | |
| for x1,y1,x2,y2 in imgLines[i]: | |
| dist=euclidian_distance((x1,y1), (x2,y2)) | |
| if dist >= (max-min)//2.3 and dist < (max-min)//1.9: #1.4 | |
| cv2.line(imgBW,(x1,y1),(x2,y2),(0,255,0),3) | |
| im_copy=imgBW.copy() | |
| green=im_copy[:,:,1] | |
| return green | |
| def ConnectBeamLines(smalldashesOut, maxLineGap=0): | |
| if maxLineGap==0: | |
| maxLineGap=25 | |
| thresh=20 | |
| point=0.3 | |
| else: | |
| thresh=20 | |
| point=0.2 | |
| maxLineGap=40 | |
| green1=cv2.bitwise_not(smalldashesOut) | |
| smalldashesOut=cv2.cvtColor(smalldashesOut,cv2.COLOR_GRAY2BGR) | |
| imgLines= cv2.HoughLinesP(green1,point,np.pi/180,thresh,minLineLength=25,maxLineGap =maxLineGap) #try 180 | |
| for i in range(len(imgLines)): | |
| for x1,y1,x2,y2 in imgLines[i]: | |
| cv2.line(smalldashesOut,(x1,y1),(x2,y2),(0,0,0),2) | |
| return smalldashesOut | |
| def getImgDark(imgg): | |
| imgold=preprocessold(imgg,0) | |
| blurG = cv2.GaussianBlur(ChangeBrightness(imgg,1),(3,3),0 ) | |
| imgGry = cv2.cvtColor(blurG, cv2.COLOR_BGR2GRAY) | |
| ret3, thresh = cv2.threshold(imgGry, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) | |
| imgold=cv2.medianBlur(imgold,3) | |
| thresh=cv2.bitwise_or(thresh,imgold) | |
| imgDark=cv2.bitwise_not(thresh) | |
| imgDark = cv2.cvtColor(imgDark, cv2.COLOR_GRAY2BGR) | |
| return imgDark | |
| #create img with solid lines | |
| def allpreSteps(imgOriginal,num=0): | |
| noCircles=detectCircles(imgOriginal) | |
| imgold=preprocessold(imgOriginal,0) | |
| if num!=1: | |
| imgnoSmall=detectSmallCircles(noCircles ) | |
| img4,imgBW,max,min=DashedPreprocessing(imgOriginal,imgnoSmall) | |
| green=removeDashedLines(img4,imgBW,max,min) | |
| imgCopy,smalldashesOut=removeSmallDashes(imgOriginal,green) | |
| noSmallDashes=removeDashedLinesSmall(img4, smalldashesOut ,max,min) | |
| green2=ConnectBeamLines(noSmallDashes,0) | |
| return green2 | |
| else: | |
| #imgDark with no dashed lines or small dashes | |
| imgDark1=getImgDark(noCircles) | |
| img4,imgBW,max,min=DashedPreprocessing(imgOriginal,noCircles) | |
| imgDarkNoDashedLines=removeDashedLines(img4,imgDark1,max,min) #do preprocessing on normal img , and draw on darkimg | |
| imgBW0 = cv2.cvtColor(imgBW, cv2.COLOR_BGR2GRAY) | |
| imgDarkNoDashedLines = cv2.cvtColor(imgDarkNoDashedLines, cv2.COLOR_GRAY2BGR) | |
| imgDarkNoDashedLines,smalldashesOut0=removeSmallDashes(imgDarkNoDashedLines,imgBW0) | |
| #imgOld no small dashes - for oring purposes | |
| imgoldG = cv2.cvtColor(imgold, cv2.COLOR_GRAY2BGR) | |
| imgoldnoDashes,_=removeSmallDashes(cv2.bitwise_not(imgoldG),imgBW0,1) | |
| #to connect leader lines after removing dashed lines and circles | |
| Nodashedlines=removeDashedLines(img4,imgBW,max,min) | |
| imgCopy,smalldashesOut=removeSmallDashes(imgOriginal,Nodashedlines) | |
| noSmallDashes=removeDashedLinesSmall(img4, smalldashesOut ,max,min) | |
| # green2=ConnectBeamLines(noSmallDashes,1) | |
| # green2 = cv2.cvtColor(green2, cv2.COLOR_BGR2GRAY) | |
| green2=cv2.bitwise_or(cv2.bitwise_not(imgDarkNoDashedLines),cv2.bitwise_not(noSmallDashes) ) | |
| green2=cv2.bitwise_not(green2) | |
| # cv2_imshow(green2) | |
| green2=cv2.medianBlur(green2,5) | |
| # cv2_imshow(green2) | |
| imgoldnoDashes=cv2.medianBlur(imgoldnoDashes,5) | |
| return green2 , cv2.bitwise_not(imgoldnoDashes) | |
| def texts_from_pdf(input_pdf): | |
| pdf_document = fitz.open('pdf',input_pdf) | |
| for page_num in range(pdf_document.page_count): | |
| page = pdf_document[page_num] | |
| text_instances = page.get_text("words") | |
| page.apply_redactions() | |
| return text_instances | |
| def textDictionaryBlocks(img,dataDoc): | |
| doc = fitz.open('pdf',dataDoc) | |
| page=doc[0] | |
| if page.rotation!=0: | |
| page.set_rotation(0) | |
| pix = page.get_pixmap() # render page to an image | |
| ratio = pix.width/ img.shape[1] | |
| block_dict = {} | |
| page_num = 1 | |
| for page in doc: # Iterate all pages in the document | |
| file_dict = page.get_text('dict') # Get the page dictionary | |
| block = file_dict['blocks'] # Get the block information | |
| block_dict[page_num] = block # Store in block dictionary | |
| page_num += 1 # Increase the page value by 1 | |
| spans = pd.DataFrame(columns=['xmin', 'ymin', 'xmax', 'ymax', 'text','FitzPointP0','FitzPointP1']) | |
| rows = [] | |
| for page_num, blocks in block_dict.items(): | |
| for block in blocks: | |
| if block['type'] == 0: | |
| for line in block['lines']: | |
| for span in line['spans']: | |
| xmin, ymin, xmax, ymax = list(span['bbox']) | |
| text = unidecode(span['text']) | |
| XminRatio=xmin/ratio | |
| YminRatio=ymin/ratio | |
| p1=fitz.Point((XminRatio),(YminRatio)) | |
| if page.rotation==0: | |
| p1=p1*page.derotation_matrix | |
| if text.replace(" ","") != "": | |
| rows.append((XminRatio,YminRatio, xmax /ratio, ymax/ratio, text,p1[0],p1[1])) | |
| span_df = pd.DataFrame(rows, columns=['xmin','ymin','xmax','ymax', 'text','FitzPointP0','FitzPointP1']) | |
| return span_df | |
| def nearestText(a,b,span_df): | |
| allNearbyText=[] | |
| shapeTexts=[] | |
| for i, row in span_df.iterrows(): | |
| measuredDist=euclidian_distance((a,b),(span_df['FitzPointP0'].loc[i],span_df['FitzPointP1'].loc[i])) | |
| if measuredDist < 250: | |
| allNearbyText.append((span_df['FitzPointP0'].loc[i],span_df['FitzPointP1'].loc[i] )) | |
| shapeTexts.append(str(span_df['text'].loc[i])) | |
| if len(allNearbyText)==0: | |
| allNearbyText='none' | |
| return allNearbyText , shapeTexts | |
| def nearestTextPCCOOR(a,b , pc_coor): | |
| nearest_point=min(pc_coor,key=lambda x:euclidian_distance((a,b),x)) | |
| dist = euclidian_distance(nearest_point, (a,b)) | |
| if dist < 400: #distance threshold | |
| return nearest_point | |
| else: | |
| return 'none' | |
| def ChangeBrightness(img,k): | |
| imgdarker = 255 * (img/255)**k # k>1 darker , k <1 lighter | |
| imgdarker = imgdarker.astype('uint8') | |
| return imgdarker | |
| def getOutlinesDotIN(img): | |
| cc=detectSmallCircles(img) | |
| cc = cv2.cvtColor(cc, cv2.COLOR_BGR2GRAY) | |
| kernel=np.ones((3,3),np.uint8) | |
| er1=cv2.dilate(cc,kernel, iterations=2) #thinning | |
| blurG = ChangeBrightness(er1,10) | |
| ret3, thresh = cv2.threshold(blurG, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) | |
| threshCnt, threshHier2 = cv2.findContours(thresh, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) | |
| outlinesDotIN = np.zeros(img.shape[:2], dtype="uint8") | |
| for cnt in threshCnt: | |
| area1 = cv2.contourArea(cnt) | |
| if (area1 > 2000 ): | |
| cv2.drawContours(outlinesDotIN,[cnt],0,(255,255,255),2) | |
| return outlinesDotIN | |
| def connectsmallDot(blackwithNoDot): | |
| imgLines= cv2.HoughLinesP(blackwithNoDot,0.05,np.pi/180,8,minLineLength=30,maxLineGap = 30) #was w-h , gap=150 #50 | |
| for i in range(len(imgLines)): | |
| for x1,y1,x2,y2 in imgLines[i]: | |
| cv2.line(blackwithNoDot,(x1,y1),(x2,y2),(255,255,255),2) | |
| return blackwithNoDot | |
| def getDiff(img,green22,imgoldnodashes): | |
| # green22 , imgoldnoDashes= allpreSteps(img,1) | |
| imgoldnoDashes1=cv2.medianBlur(imgoldnodashes,7) | |
| kernel=np.ones((3,3),np.uint8) | |
| green3=cv2.erode(green22,kernel, iterations=6) | |
| green3=cv2.dilate(green3,kernel, iterations=3) | |
| imgoldnoDashes1=cv2.erode(imgoldnoDashes1,kernel, iterations=2) | |
| img1Eroded=cv2.dilate(imgoldnoDashes1,kernel, iterations=7) #5 | |
| diff = ImageChops.difference(Image.fromarray(img1Eroded), Image.fromarray(cv2.bitwise_not(green3))) | |
| diff=np.array(diff) | |
| diff=cv2.erode(diff,kernel, iterations=4) | |
| diff=cv2.dilate(diff,kernel, iterations=11) | |
| return diff | |
| #OLD method (White shapes) | |
| def preprocessold(img,number): | |
| blurG = cv2.GaussianBlur(ChangeBrightness(img,8),(3,3),0 ) | |
| # cv2.imwrite('imgold.png', blurG) | |
| imgGry = cv2.cvtColor(blurG, cv2.COLOR_BGR2GRAY) | |
| kernel=np.ones((3,3),np.uint8) | |
| er1=cv2.dilate(imgGry,kernel, iterations=2) #thinning | |
| if number == 0: | |
| ret3, thresh = cv2.threshold(er1, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) | |
| else: | |
| ret3, thresh = cv2.threshold(er1, 220, 255, cv2.THRESH_BINARY_INV) #`140 - 141 | |
| thresh=cv2.medianBlur(thresh,5) | |
| # thresh=cv2.dilate(thresh,kernel, iterations=1) #thinning | |
| return thresh | |
| #preprocessing for shapes with arrows (attach them to shape ) | |
| def getTextfromImg(grayimgtextdilated, img,dataDoc): | |
| span_df=textDictionaryBlocks(img,dataDoc) | |
| threshCnt2, threshHier2 = cv2.findContours(grayimgtextdilated, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) | |
| allshapesExtremes_Text=[] | |
| listallTexts=textListsAlltexts(dataDoc,span_df)[1] | |
| for cnt in threshCnt2: | |
| texts=[] | |
| area1 = cv2.contourArea(cnt) | |
| if (area1 >2000 ): | |
| x, y , width, height = cv2.boundingRect(cnt) | |
| perimeter=cv2.arcLength(cnt,True) | |
| approx = cv2.approxPolyDP(cnt, 0.01* perimeter, True) | |
| for extremePoint in approx: | |
| allnearbyPoints,alltxts=nearestText(int(extremePoint[0][0]),int(extremePoint[0][1]),span_df) | |
| if(allnearbyPoints!='none'): | |
| for nearbypoint in allnearbyPoints: | |
| for textTuple in listallTexts: | |
| if nearbypoint[0]==textTuple[0] and nearbypoint[1]==textTuple[1]: | |
| if textTuple[2] not in texts: | |
| texts.append(textTuple[2]) | |
| allshapesExtremes_Text.append([cnt,texts]) | |
| # print(allshapesExtremes_Text) | |
| ArrthreshCnt=[] | |
| for th in range(len(allshapesExtremes_Text)): | |
| eachcnt=[] | |
| for point in allshapesExtremes_Text[th][0]: | |
| eachcnt.append(list(point[0])) | |
| ArrthreshCnt.append(eachcnt) | |
| return ArrthreshCnt , allshapesExtremes_Text | |
| def mergingPreprocessing(img,number,green2,layeredflag,BlackmaskDetected1=0): | |
| # diff , imgoldnodashes=getDiff(img)#diff (img with tof leaders) | |
| img1=preprocessold(img,number) | |
| # green2Gray = cv2.cvtColor(green2, cv2.COLOR_BGR2GRAY) | |
| # anding=cv2.bitwise_and(green2Gray,img1) #and between old and green2 to get perfect shapes with no outer lines | |
| # ret3, thresh2 = cv2.threshold(anding, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) | |
| # if layeredflag.startswith('layer'): | |
| # thresh2=cv2.bitwise_and(thresh2,thresh2,mask=BlackmaskDetected1) | |
| threshcontours, threshHier = cv2.findContours(img1, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) | |
| return img1 , threshcontours , img1 | |
| #anding of old method output with solid lines img | |
| def preprocess(green22,imgoldnodashes,dataDoc,imgtransparent1,img,number,green2,layeredflag,BlackmaskDetected1=0): | |
| #first preprocessing ( old method - black img with white shapes) | |
| kernel0=np.ones((2,2),np.uint8) | |
| ##first preprocessing ( old method - black img with white shapes) | |
| img1,threshcontours,thresh2=mergingPreprocessing(img,number,green2,layeredflag,BlackmaskDetected1) | |
| diff =getDiff(img,green22,imgoldnodashes)#diff (img with tof leaders) | |
| iddk=cv2.bitwise_or(thresh2,diff) #add it to preprocessing img of anding | |
| iddk=cv2.medianBlur(iddk,5) | |
| iddk=cv2.dilate(iddk,kernel0, iterations=2) | |
| ArrthreshCnt , texts=getTextfromImg(iddk,img,dataDoc) #getText relations between each contour and its text | |
| outlinesDotIN=getOutlinesDotIN(img) | |
| pc_coor,listall=textLists(img,dataDoc) | |
| finalcntsP=[] | |
| finalcntsA=[] | |
| perimeters=[] | |
| openClosedFlag=0 | |
| threshCnt, threshHier2 = cv2.findContours(img1, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) | |
| outlines = np.zeros(img.shape[:2], dtype="uint8") | |
| for cnt in threshCnt: | |
| area1 = cv2.contourArea(cnt) | |
| if (area1 > 2000 ): | |
| cv2.drawContours(outlines,[cnt],0,(255,255,255),2) | |
| perimeter=0 | |
| shapetxts=[] | |
| for cnt in threshcontours: | |
| BlackmaskP = np.zeros(img.shape[:2], dtype="uint8") | |
| BlackmaskA=np.zeros(img.shape[:2], dtype="uint8") | |
| area1 = cv2.contourArea(cnt) | |
| if (area1 > 2000 ): | |
| x, y , width, height = cv2.boundingRect(cnt) | |
| #Get contours - Areas , Perimeters | |
| kernel=np.ones((2,2),np.uint8) | |
| cv2.drawContours(BlackmaskP,[cnt],0,(255,255,255), 4) | |
| BlackmaskP=cv2.dilate(BlackmaskP,kernel, iterations=2) | |
| contoursP, hier1 = cv2.findContours(BlackmaskP, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) | |
| finalcntsP.append(contoursP) | |
| cv2.drawContours(BlackmaskA,[cnt],0,(255,255,255), 3) | |
| BlackmaskA=cv2.erode(BlackmaskA,kernel, iterations=1) | |
| contoursA, hier1 = cv2.findContours(BlackmaskA, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) | |
| finalcntsA.append(contoursA) | |
| if pc_coor: | |
| textPoint=nearestTextPCCOOR(int(x+(width/2)), int(y+(height/2)) , pc_coor) | |
| txt='' | |
| if(textPoint!='none'): | |
| for textTuple in listall: | |
| if textPoint[0]==textTuple[0] and textPoint[1]==textTuple[1]: | |
| txt=textTuple[2] | |
| if "GB" in txt or "RC" in txt or "PC" in txt: | |
| shapetxts.append(txt) | |
| elif textPoint=='none': | |
| shapetxts.append('none') | |
| if 'GB' in shapetxts: | |
| xcBlk, ycBlk , width, height = cv2.boundingRect(contoursP[0]) | |
| xx=cv2.bitwise_and(outlines,outlines,mask=BlackmaskP) | |
| xx = cv2.threshold(xx, 250, 255, cv2.THRESH_BINARY)[1] | |
| cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) | |
| if len(cntsx)>0: | |
| hierx=hierx[0] | |
| xx=cv2.bitwise_and(outlinesDotIN,outlinesDotIN,mask=xx) | |
| cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) | |
| if len(cntsx)>0: | |
| xx=connectsmallDot(xx) | |
| cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) | |
| if len(cntsx)>0: | |
| hierx=hierx[0] | |
| for comp in zip(cntsx,hierx): | |
| c=comp[0] | |
| h=comp[1] | |
| xc, yc , width, height = cv2.boundingRect(c) | |
| perimeter=cv2.arcLength(c,True) | |
| shape=[] | |
| approx = cv2.approxPolyDP(c, 0.003* perimeter, True) | |
| if h[2]<0 and h[3] <0: | |
| perimeter1 = cv2.arcLength(approx, True) | |
| perimeter=perimeter1/2 | |
| # cv2_imshow(xx) | |
| openClosedFlag='open' | |
| imgtransparent1=cv2.polylines(imgtransparent1, [approx], False, (0,255,0), thickness=4,lineType=8) | |
| perimeters.append([xc, yc ,xcBlk, ycBlk ,perimeter ,openClosedFlag , approx]) | |
| else: | |
| if h[2] >0: | |
| openClosedFlag='closed' | |
| return tuple(finalcntsP),tuple(finalcntsA), perimeters , shapetxts , imgtransparent1 ,ArrthreshCnt , texts, iddk | |
| """# ROI (levels) | |
| ## Detect regions with specific color and mask them | |
| """ | |
| def hexRGB(color): | |
| color=color.lstrip('#') | |
| color= tuple(int(color[i:i+2], 16) for i in (0, 2, 4)) #hex to rgb | |
| color=np.array(color) #rgb to bgr | |
| return color | |
| def DetectColor(img,color=0): | |
| imgCopy=img.copy() | |
| imgCopy=cv2.cvtColor(imgCopy,cv2.COLOR_BGR2HSV) | |
| tol=5 #tolerance | |
| # color=hexRGB(color) | |
| h,s,v = cv2.cvtColor(np.uint8([[[color[2],color[1],color[0]]]]),cv2.COLOR_BGR2HSV)[0][0] | |
| lower =np.array( [h- tol, 100, 100 ], dtype='uint8') | |
| upper = np.array( [h + tol, 255, 255],dtype='uint8') | |
| mask = cv2.inRange(imgCopy, lower , upper) | |
| detectedColors = cv2.bitwise_and(imgCopy,imgCopy, mask= mask) # Bitwise-AND mask and original image | |
| kernel=np.ones((3,3),np.uint8) | |
| mask=cv2.dilate(mask,kernel, iterations=5) | |
| mask=cv2.erode(mask,kernel, iterations=4) | |
| detectedColors=cv2.dilate(detectedColors,kernel, iterations=5) | |
| detectedColors=cv2.erode(detectedColors,kernel, iterations=4) | |
| detectedColors=cv2.cvtColor(detectedColors,cv2.COLOR_HSV2BGR) | |
| detectedColors=cv2.medianBlur(detectedColors,7) | |
| cv2.imwrite('det.png',detectedColors) | |
| return mask, detectedColors, color | |
| def getinnerColor(BlackmaskDetected,img,detectedColors,finalColorArray,ratioarea,ratioperim,eachcolor): | |
| countBlackMasks=0 | |
| xored=detectedColors | |
| invertedmask=detectedColors | |
| imgc=img.copy() | |
| imgNewCopy=img.copy() | |
| Blackmask = np.zeros(img.shape[:2], dtype="uint8") | |
| for eachcolor in finalColorArray: | |
| masked=DetectColor(detectedColors,eachcolor)[0] | |
| pil_image=Image.fromarray(masked) | |
| extrema = pil_image.convert("L").getextrema() | |
| if extrema != (0, 0): # if image is not black --> has a colored mask within | |
| cc=detectedColors.copy() | |
| ColoredContour, Coloredhierarchy = cv2.findContours(masked, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) | |
| for cnt in ColoredContour: | |
| area1 = cv2.contourArea(cnt) | |
| if (area1 > 1000 ): | |
| x, y , width, height = cv2.boundingRect(cnt) | |
| cv2.drawContours(cc,[cnt],0,(255,255,255), 3) | |
| cv2.drawContours(Blackmask,[cnt] ,0, (255,255,255), 3) | |
| cv2.drawContours(cc,[cnt],0,(255,255,255), -1) # (x-5,y-5 ), (x+width, y+height), | |
| cv2.drawContours(Blackmask,[cnt] ,0, (255,255,255), -1) #,(x,y ), (x+width, y+height) | |
| cv2.drawContours(BlackmaskDetected,[cnt] ,0, (0,0,0), -1) #,(x,y ), (x+width, y+height) | |
| invertedmask = cv2.bitwise_and(imgc,imgc, mask= Blackmask) | |
| xored=cc | |
| detectedColors=xored | |
| else: #black mask , no other levels are found # to check law count == number of colors in array yb2a no more levels and break | |
| countBlackMasks+=1 | |
| return xored,invertedmask , BlackmaskDetected | |
| def allLevelsofColor(BlackmaskDetected,img,levelonly, invertedmask,color,finalColorArray): | |
| # cc=levelonly.copy() | |
| firstLevel=levelonly | |
| firstLevel1=levelonly | |
| print('in') | |
| Blackmask = np.zeros(img.shape[:2], dtype="uint8") | |
| masked,maskedColor,rgbcolor=DetectColor(invertedmask,color) | |
| color=[color[0],color[1],color[2]] | |
| rgbcolor=[rgbcolor[0],rgbcolor[1],rgbcolor[2]] | |
| print(rgbcolor,color) | |
| pil_image=Image.fromarray(masked) | |
| extrema = pil_image.convert("L").getextrema() | |
| if extrema != (0, 0): # if image is not black --> has a colored mask within | |
| if rgbcolor==color: #found level tany gowa b nfs el lon | |
| print('kkkkkkkk') | |
| ColoredContour, Coloredhierarchy = cv2.findContours(masked, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) | |
| Coloredhierarchy=Coloredhierarchy[0] | |
| for component in zip(ColoredContour,Coloredhierarchy): | |
| cnt=component[0] | |
| hier=component[1] | |
| area1 = cv2.contourArea(cnt) | |
| if (area1 > 1000 ): | |
| if hier[3]> -1: | |
| cv2.drawContours(Blackmask,[cnt],0,(255,255,255), -1) | |
| cv2.drawContours(Blackmask,[cnt],0,(0,0,0), 20) | |
| cv2.drawContours(BlackmaskDetected,[cnt],0,(255,255,255), -1) | |
| firstLevel=cv2.bitwise_and(invertedmask,invertedmask,mask=Blackmask) | |
| ####remove black pixels and let them be all white | |
| # get (i, j) positions of all RGB pixels that are black (i.e. [0, 0, 0]) | |
| firstLevel[np.all(firstLevel == (0,0,0), axis=-1)] = (255, 255, 255) | |
| firstLevel1=cv2.bitwise_and(levelonly,firstLevel) | |
| for othercolor in finalColorArray: | |
| # othercolor2=hexRGB(othercolor) | |
| othercolor2=[othercolor[0],othercolor[1],othercolor[2]] | |
| if othercolor2!=color: | |
| masked0=DetectColor(firstLevel,othercolor)[0] | |
| pil_image0=Image.fromarray(masked0) | |
| extrema0 = pil_image0.convert("L").getextrema() | |
| if extrema != (0, 0): # if image is not black --> has a colored mask within | |
| ColoredContour0, Coloredhierarchy0 = cv2.findContours(masked0, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) | |
| for cnt in ColoredContour0: | |
| area1 = cv2.contourArea(cnt) | |
| if (area1 > 1000 ): | |
| cv2.drawContours(firstLevel1,[cnt],0,(255,255,255), -1) | |
| cv2.drawContours(firstLevel1,[cnt],0,(255,255,255), 10) | |
| cv2.drawContours(BlackmaskDetected,[cnt],0,(0,0,0), -1) | |
| # cv2.drawContours(Blackmask,[cnt],0,(255,255,255), -1) | |
| # cv2.drawContours(Blackmask,[cnt],0,(255,255,255), 10) | |
| # cv2_imshow(firstLevel1) | |
| # cv2_imshow(Blackmask) | |
| return firstLevel1, BlackmaskDetected | |
| def getColoredContour(mask,img,finalColorArray,ratioarea,ratioperim,eachcolor): | |
| ColoredContour, Coloredhierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) | |
| Coloredhierarchy=Coloredhierarchy[0] | |
| imgc= img.copy() | |
| detectedColors=np.zeros(img.shape[:2], dtype="uint8") | |
| Blackmask = np.zeros(img.shape[:2], dtype="uint8") | |
| for component in zip( ColoredContour, Coloredhierarchy): | |
| cnt=component[0] | |
| hier=component[1] | |
| area1 = cv2.contourArea(cnt) | |
| if (area1 > 3000 ): | |
| # cv2.drawContours(imgNewCopy, [cnt], 0,(255,255,255), 20) #(x+20,y+20 ), (x+width-20, y+height-20), | |
| if hier[3] >-1: | |
| x, y , width, height = cv2.boundingRect(cnt) | |
| cv2.drawContours(Blackmask, [cnt], 0,(255,255,255), -1) #(x+20,y+20 ), (x+width-20, y+height-20), | |
| cv2.drawContours(Blackmask, [cnt], 0,(0,0,0), 10) #(x+20,y+20 ), (x+width-20, y+height-20), | |
| detectedColors = cv2.bitwise_and(imgc,imgc, mask= Blackmask) | |
| pil_image=Image.fromarray(detectedColors) | |
| extrema = pil_image.convert("L").getextrema() | |
| if extrema == (0, 0) :#and extremaB==(0,0): # if image is not black --> has a colored mask within | |
| break | |
| levelOnly,invertedmask,BlackmaskDetected=getinnerColor(Blackmask,img,detectedColors,finalColorArray,ratioarea,ratioperim,eachcolor) #mask inner levels b abyad | |
| firstLevel1, BlackmaskDetected1= allLevelsofColor(BlackmaskDetected,img,levelOnly, invertedmask,eachcolor,finalColorArray) | |
| return firstLevel1,invertedmask, BlackmaskDetected1 | |
| """# contours""" | |
| def findContoursFullImage(green22,imgoldnodashes,dataDoc,imgtransparent1,green2,img,number,finalColorArray,ratioarea,ratioperim,color=[0,0,0]): | |
| if number == 0: | |
| contourssP,contourssA,perimeters,alltxts,imgtransparent1,arrthresh,allshapesExtremes_Text,iddk=preprocess(green22,imgoldnodashes,dataDoc,imgtransparent1,img,number,green2, 'nolayer') | |
| return contourssP,contourssA, perimeters ,alltxts , imgtransparent1,arrthresh,allshapesExtremes_Text , iddk | |
| else: | |
| mask, detectedColors, rgbcolor =DetectColor(img,color) | |
| pil_image=Image.fromarray(mask) | |
| extrema = pil_image.convert("L").getextrema() | |
| if extrema != (0, 0): # if image is not black --> has a colored mask within | |
| coloredregions,invertedmask,BlackmaskDetected1=getColoredContour(mask,img,finalColorArray,ratioarea,ratioperim,color) | |
| contourssP,contourssA,perimeters,alltxts,imgtransparent1,arrthresh,allshapesExtremes_Text,iddk=preprocess(green22,imgoldnodashes,dataDoc,imgtransparent1,coloredregions,number,green2,'layer',BlackmaskDetected1) | |
| return contourssP,contourssA ,rgbcolor ,invertedmask , perimeters , alltxts , imgtransparent1 ,arrthresh,allshapesExtremes_Text , iddk | |
| else: | |
| contourssP,contourssA ,rgbcolor ,invertedmask , perimeters , alltxts , imgtransparent1 ,arrthresh,allshapesExtremes_Text , iddk=preprocess(green22,imgoldnodashes,dataDoc,imgtransparent1,img,number,green2,'nolayer') | |
| return contourssP,contourssA,color ,mask , perimeters , alltxts,imgtransparent1,arrthresh,allshapesExtremes_Text , iddk | |
| #Straighten tilted shapes | |
| def StraightenImage(contour,imgArea): | |
| rect = cv2.minAreaRect(contour) | |
| (center, (width, height), angleR) = cv2.minAreaRect(contour) | |
| box = cv2.boxPoints(rect) | |
| box = np.int0(box) | |
| # get width and height of the detected rectangle | |
| width = int(rect[1][0]) | |
| height = int(rect[1][1]) | |
| return angleR,width,height | |
| #get all areas and perimeter present | |
| def getAreasPerimeter(img,ratioarea,ratioperim,contourssP,contourssA): | |
| appended=[] | |
| for contour in range(len(contourssP)): | |
| area1 = cv2.contourArea(contourssP[contour][0]) | |
| if (area1 >2000 ): | |
| perimeter= cv2.arcLength(contourssP[contour][0],True) | |
| approx = cv2.approxPolyDP(contourssP[contour][0], 0.002* perimeter, True) | |
| perimeter1 = cv2.arcLength(approx, True) | |
| approx = cv2.approxPolyDP(contourssA[contour][0], 0.0002* perimeter, True) | |
| area1 = cv2.contourArea(approx) | |
| x, y , width, height = cv2.boundingRect(contourssP[contour][0]) | |
| angleR,widthR ,heightR= StraightenImage(contourssP[contour][0],img) | |
| if (angleR != 90.0 and angleR != -90.0 and angleR != 0.0 and angleR != -0.0 ): #inclined b ay degree | |
| width=widthR | |
| height=heightR | |
| if (area1 > 2000 ): #check perimeter kman fl condition -- 2800 | |
| if ratioarea!=0 and ratioperim!=0: | |
| areaa=round(area1* ratioarea , 3) # true value of area of any shape/ area px value of same shape | |
| appended.append([areaa,width,height]) | |
| return appended | |
| #fill dictionary with areas and perimeters and occurences | |
| def FillDictionary(SimilarAreaDictionary,img,ratioarea,ratioperim,contourssP,contourssA,rgbcolor=[0,0,0],color=[0,0,0]): | |
| #fills dictionary with key areas and number of occurences | |
| areas_Perimeters=sorted(getAreasPerimeter(img,ratioarea,ratioperim,contourssP,contourssA)) | |
| indices=[] | |
| 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]] | |
| colorsUsed=[] | |
| for i in range(len(areas_Perimeters)): | |
| # colorRGB=hexRGB(color) | |
| item1 = areas_Perimeters[i][0] | |
| width1 = areas_Perimeters[i][1] | |
| height1 = areas_Perimeters[i][2] | |
| widthMin= width1-15 | |
| widthMax= width1+15 | |
| heightMin=height1-15 | |
| heightMax= height1+15 | |
| areaPerimeterMin= round(item1,1) - 0.4 | |
| areaPerimeterMax= round(item1,1) + 0.4 | |
| # print (areaMin, areaMax) | |
| if color != [0,0,0]: #colored images | |
| mydata=[[],[rgbcolor[0],rgbcolor[1],rgbcolor[2] ],round(item1,1),width1,height1,1, 0,0,0,0,0,0,'',0,0,0,''] | |
| else: | |
| mydata=[[],' ', round(item1,1),width1,height1,1, 0,0,0,0,0,0,'',0,0,0,''] | |
| myindex= SimilarAreaDictionary.index[((SimilarAreaDictionary['Rounded'] >=areaPerimeterMin) &(SimilarAreaDictionary['Rounded']<=areaPerimeterMax) )].tolist() | |
| if color!= [0,0,0]: #leveled image | |
| checkifColorExists=0 # to check whether this row was found or not( area and color ) | |
| for i in myindex: # loop on indices that were found --> rows containing this area to check its color and add occ. | |
| if SimilarAreaDictionary['Color'].loc[i]==[rgbcolor[0],rgbcolor[1],rgbcolor[2]] and ( SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin and SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax) : | |
| 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 ) : | |
| checkifColorExists=1 #found and incremented | |
| SimilarAreaDictionary['Occurences'].loc[i]+=1 | |
| if checkifColorExists==0: #couldnt find the color , doesnt exist so add it | |
| SimilarAreaDictionary.loc[len(SimilarAreaDictionary)] =mydata | |
| else: #full image | |
| #same code bs mgher color | |
| checkifColorExists=0 | |
| for i in myindex: | |
| if ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) : | |
| 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 ) : | |
| checkifColorExists=1 #found and incremented | |
| SimilarAreaDictionary['Occurences'].loc[i]+=1 | |
| if checkifColorExists==0: #couldnt find the color , doesnt exist so add it | |
| SimilarAreaDictionary.loc[len(SimilarAreaDictionary)] =mydata | |
| # s= SimilarAreaDictionary | |
| for i in range(len(SimilarAreaDictionary)): | |
| SimilarAreaDictionary.loc[i, "R"] = colorRanges[i][0] | |
| SimilarAreaDictionary.loc[i, "G"] = colorRanges[i][1] | |
| SimilarAreaDictionary.loc[i, "B"] = colorRanges[i][2] | |
| colorsUsed.append(colorRanges[i]) | |
| return SimilarAreaDictionary, colorsUsed , areas_Perimeters | |
| #detect and draw and measure | |
| def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim , path,pdfpath): | |
| green2=allpreSteps(img) | |
| green22,imgoldnodashes=allpreSteps(img,num=1) | |
| doc = fitz.open("pdf",dataDoc) | |
| page = doc[0] | |
| rotationOld=page.rotation | |
| pix=page.get_pixmap() | |
| if page.rotation!=0: | |
| page.set_rotation(0) | |
| ratio = pix.width/ img.shape[0] | |
| else: | |
| ratio = pix.width/ img.shape[1] | |
| areasinImage=[] | |
| imgArea1= img.copy() | |
| imgPerimeter1=img.copy() | |
| imgtransparent1=img.copy() | |
| if number ==220: | |
| SimilarAreaDictionary= pd.DataFrame(columns=['Guess','Color','Rounded','Width','Height','Occurences','Area','Total Area','Perimeter','Total Perimeter','Length','Total Length','Texts','R','G','B','Comments']) | |
| # firstcolor=finalColorArray[0] | |
| # counter=0 | |
| maskDone=img.copy() | |
| for eachcolor in finalColorArray: | |
| contourssP,contourssA,rgbcolor,invertedmask , perimeters , alltxts,imgtransparent1 , ArrthreshCnt ,allshapesExtremes_Text, green22Gry=findContoursFullImage(green22,imgoldnodashes,dataDoc,imgtransparent1,green2,maskDone,number,finalColorArray,ratioarea,ratioperim,eachcolor) | |
| SimilarAreaDictionary, colorsUsed , areas_Perimeters= FillDictionary(SimilarAreaDictionary,maskDone,ratioarea,ratioperim,contourssP,contourssA,rgbcolor,eachcolor) | |
| perimTotal=0 | |
| for contour in range(len(contourssP)): | |
| shape=[] | |
| area1 = cv2.contourArea(contourssA[contour][0]) | |
| if (area1 > 3500 ): #check perimeter kman fl condition -- 2800 | |
| perimeter=cv2.arcLength(contourssP[contour][0],True) | |
| shape=[] | |
| angleR,widthR ,heightR= StraightenImage(contourssP[contour][0],imgArea1) | |
| x, y , width, height = cv2.boundingRect(contourssP[contour][0]) | |
| Blackmask = np.zeros(img.shape[:2], dtype="uint8") | |
| Blackmask = cv2.rectangle(Blackmask, (int(x-10),int(y-10)), (int(x+width+10),int(y+height+10)), (255, 255, 255), -1) | |
| Blackmask=cv2.bitwise_and(green22Gry,green22Gry,mask=Blackmask) | |
| BlackmaskCnt,_= cv2.findContours(Blackmask, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) | |
| areas = [cv2.contourArea(c) for c in BlackmaskCnt] | |
| if len(areas)>0: | |
| max_index = np.argmax(areas) | |
| blackcnt=BlackmaskCnt[max_index] | |
| blackcnt=tuple(blackcnt) | |
| texts='' | |
| for th in range(len(ArrthreshCnt)): | |
| for e in blackcnt: | |
| if list(e[0]) in ArrthreshCnt[th]: | |
| texts=allshapesExtremes_Text[th][1] | |
| break | |
| if len(texts)>0: | |
| break | |
| approxA = cv2.approxPolyDP(contourssA[contour][0], 0.0002* perimeter, True) | |
| area1 = cv2.contourArea(approxA) | |
| approx = cv2.approxPolyDP(contourssP[contour][0], 0.002 * perimeter, True) #0.0009 | |
| perimeter1 = cv2.arcLength(approx, True) | |
| for point in approxA: | |
| x1, y1 = point[0] | |
| p1 = fitz.Point(x1*ratio,y1*ratio) | |
| p1=p1*page.derotation_matrix | |
| shape.append([p1[0],p1[1]]) | |
| if (angleR != 90.0 and angleR != -90.0 and angleR != 0.0 and angleR != -0.0 ): #inclined b ay degree | |
| width=widthR | |
| height=heightR | |
| if width>height: | |
| lengthShape = width | |
| else: | |
| lengthShape = height | |
| widthMin= width-15 | |
| widthMax= width+15 | |
| heightMin=height-15 | |
| heightMax= height+15 | |
| if ratioarea !=0 and ratioperim!=0: | |
| areaa=round(area1* ratioarea, 3) # true value of area of any shape/ area px value of same shape | |
| perimeterr=round(perimeter1* ratioperim,3) | |
| lengthShape=round(lengthShape* ratioperim,3) | |
| else: | |
| areaa=area1 | |
| perimeterr=perimeter1 | |
| areaPerimeterMin= round(areaa,1) - 0.4 | |
| areaPerimeterMax= round(areaa,1) + 0.4 | |
| masked=SimilarAreaDictionary.loc[SimilarAreaDictionary.index[((SimilarAreaDictionary['Rounded'] >=areaPerimeterMin) &(SimilarAreaDictionary['Rounded']<=areaPerimeterMax) )]] | |
| passed=0 | |
| for i, row in masked.iterrows(): | |
| if passed ==0: | |
| if SimilarAreaDictionary['Color'].loc[i] == [rgbcolor[0],rgbcolor[1],rgbcolor[2]] and ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) : | |
| 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 ) : | |
| if len(alltxts)>0: | |
| SimilarAreaDictionary['Guess'].loc[i].append(str(alltxts[contour])) | |
| for t in texts: | |
| if "GB" not in t or "RC" not in t or "PC" not in t: | |
| if t not in SimilarAreaDictionary['Texts'].loc[i]: | |
| SimilarAreaDictionary['Texts'].loc[i]+=' '+t | |
| SimilarAreaDictionary['Total Area'].loc[i]+=areaa | |
| SimilarAreaDictionary['Area'].loc[i]=areaa | |
| pFlagDF=0 | |
| color= (int(SimilarAreaDictionary['R'].loc[i])/255 , int(SimilarAreaDictionary['G'].loc[i])/255 , int(SimilarAreaDictionary['B'].loc[i])/255 ) | |
| for p in perimeters: | |
| if p[2]==x and p[3]==y and p[5]=='open': | |
| # if areaa >=5.15 and areaa<=5.25: | |
| shapee=[] | |
| SimilarAreaDictionary['Total Perimeter'].loc[i]+=round((p[4]-1)*ratioperim,3) | |
| SimilarAreaDictionary['Perimeter'].loc[i]=round((p[4]-1)*ratioperim,3) | |
| for poi in p[6]: | |
| x1, y1 = poi[0] | |
| p1 = fitz.Point(x1*ratio,y1*ratio) | |
| p1=p1*page.derotation_matrix | |
| shapee.append([p1[0],p1[1]]) | |
| annot11 = page.add_polyline_annot( points=shapee) # 'Polygon' | |
| annot11.set_border(width=0.2, dashes=[3]) | |
| annot11.set_colors(stroke=color ,fill=None) | |
| if len(alltxts)>0: | |
| annot11.set_info(content='Perimeter='+str(round((p[4]-1)*ratioperim,3))+' m',subject='ADR Team',title=str(alltxts[contour])) | |
| # annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE) | |
| annot11.update() | |
| pFlagDF=1 | |
| if pFlagDF==0: | |
| annot1 = page.add_polyline_annot( points=shape) # 'Polygon' | |
| annot1.set_border(width=0.2 ,dashes=[3]) | |
| annot1.set_colors(stroke=color , fill=None) | |
| if len(alltxts)>0: | |
| annot1.set_info(content='Perimeter='+str(perimeterr)+' m',subject='ADR Team',title=str(alltxts[contour])) | |
| SimilarAreaDictionary['Total Perimeter'].loc[i]+=perimeterr | |
| SimilarAreaDictionary['Perimeter'].loc[i]=perimeterr | |
| SimilarAreaDictionary['Total Length'].loc[i]+=lengthShape | |
| SimilarAreaDictionary['Length'].loc[i]=lengthShape | |
| passed=1 | |
| cv2.drawContours(imgArea1, [contourssP[contour][0]], 0, ( int(SimilarAreaDictionary['B'].loc[i]), int(SimilarAreaDictionary['G'].loc[i]), int(SimilarAreaDictionary['R'].loc[i])), -1) | |
| annot = page.add_polygon_annot( points=shape) # 'Polygon' | |
| annot.set_border(width=0.2) | |
| annot.set_colors(stroke=color, fill= color ) | |
| annot.set_opacity(0.5) | |
| if len(alltxts)>0: | |
| annot.set_info(content='Area='+str(areaa)+ " m²",subject='ADR Team',title=str(alltxts[contour])) | |
| # annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE) | |
| annot.update() | |
| annot11 = page.add_polyline_annot( points=shape) # 'Polygon' | |
| annot11.set_border(width=0.2, dashes=[3]) | |
| annot1.set_colors(stroke=color ,fill=None) | |
| annot11.set_info(content=' Length='+str(lengthShape)+' m',subject='ADR Team',title=str(alltxts[contour])) | |
| annot11.update() | |
| # areasinImage.append(areaa) | |
| cv2.putText(imgPerimeter1,'Perimeter: '+str(perimeterr)+ ' m', (x+70,y-30) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2) | |
| cv2.putText(imgPerimeter1,'Area: '+str(areaa)+' m2', (x+50,y-40) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2) | |
| # for i,row in SimilarAreaDictionary.iterrows(): | |
| # # print(row) | |
| # if row[5] not in areasinImage: # column of area | |
| # SimilarAreaDictionary = SimilarAreaDictionary.drop(SimilarAreaDictionary.loc[SimilarAreaDictionary.index==i].index) | |
| # print(SimilarAreaDictionary) | |
| # display(totaldf) | |
| ######################### | |
| else: | |
| SimilarAreaDictionary= pd.DataFrame(columns=['Guess','Color','Rounded','Width','Height','Occurences','Area','Total Area','Perimeter','Total Perimeter','Length','Total Length','Texts','R','G','B','Comments']) | |
| contourssP,contourssA , perimeters , alltxts , imgtransparent1 , ArrthreshCnt ,allshapesExtremes_Text, green22Gry=findContoursFullImage(green22,imgoldnodashes,dataDoc,imgtransparent1,green2,img,number,finalColorArray,ratioarea,ratioperim) | |
| SimilarAreaDictionary,colorsUsed , areas_Perimeters= FillDictionary(SimilarAreaDictionary,img,ratioarea,ratioperim,contourssP,contourssA) | |
| for contour in range(len(contourssP)): | |
| area1 = cv2.contourArea(contourssA[contour][0]) | |
| if (area1 >4000 ): | |
| perimeter=cv2.arcLength(contourssP[contour][0],True) | |
| shape=[] | |
| angleR,widthR ,heightR= StraightenImage(contourssP[contour][0],imgArea1) | |
| x, y , width, height = cv2.boundingRect(contourssP[contour][0]) | |
| Blackmask = np.zeros(img.shape[:2], dtype="uint8") | |
| Blackmask = cv2.rectangle(Blackmask, (int(x-10),int(y-10)), (int(x+width+10),int(y+height+10)), (255, 255, 255), -1) | |
| Blackmask=cv2.bitwise_and(green22Gry,green22Gry,mask=Blackmask) | |
| BlackmaskCnt,_= cv2.findContours(Blackmask, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) | |
| areas = [cv2.contourArea(c) for c in BlackmaskCnt] | |
| if len(areas)>0: | |
| max_index = np.argmax(areas) | |
| blackcnt=BlackmaskCnt[max_index] | |
| blackcnt=tuple(blackcnt) | |
| texts='' | |
| # textsMid='' | |
| for th in range(len(ArrthreshCnt)): | |
| for e in blackcnt: | |
| if list(e[0]) in ArrthreshCnt[th]: | |
| texts=allshapesExtremes_Text[th][1] | |
| # textsMid=allshapesExtremes_Text[th][2] | |
| break | |
| if len(texts)>0: | |
| break | |
| # print(texts) | |
| approxA = cv2.approxPolyDP(contourssA[contour][0], 0.0002* perimeter, True) | |
| area1 = cv2.contourArea(approxA) | |
| approx = cv2.approxPolyDP(contourssP[contour][0], 0.002* perimeter, True) #0.0009 | |
| perimeter1 = cv2.arcLength(approx, True) | |
| for point in approxA: | |
| x1, y1 = point[0] | |
| p1 = fitz.Point(x1*ratio,y1*ratio) | |
| p1=p1*page.derotation_matrix | |
| shape.append([p1[0],p1[1]]) | |
| if (angleR != 90.0 and angleR != -90.0 and angleR != 0.0 and angleR != -0.0 ): #inclined b ay degree | |
| width=widthR | |
| height=heightR | |
| if width>height: | |
| lengthShape = width | |
| if height>width: | |
| lengthShape = height | |
| widthMin= width-15 | |
| widthMax= width+15 | |
| heightMin=height-15 | |
| heightMax= height+15 | |
| if ratioarea !=0 and ratioperim!=0: | |
| areaa= round(area1* ratioarea,3) # true value of area of any shape/ area px value of same shape | |
| perimeterr=round(perimeter1* ratioperim,3) | |
| lengthShape=round(lengthShape* ratioperim,3) | |
| else: | |
| perimeterr=perimeter1 | |
| areaPerimeterMin= round(areaa,1) - 0.4 | |
| areaPerimeterMax= round(areaa,1) + 0.4 | |
| masked=SimilarAreaDictionary.loc[SimilarAreaDictionary.index[((SimilarAreaDictionary['Rounded'] >=areaPerimeterMin) & (SimilarAreaDictionary['Rounded']<=areaPerimeterMax) )]] | |
| passed=0 | |
| for i, row in masked.iterrows(): | |
| if passed ==0: | |
| if ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) : | |
| 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 ) : | |
| if len(alltxts)>0: | |
| SimilarAreaDictionary['Guess'].loc[i].append(str(alltxts[contour])) | |
| for t in texts: | |
| if "GB" not in t or "RC" not in t or "PC" not in t: | |
| if t not in SimilarAreaDictionary['Texts'].loc[i]: | |
| SimilarAreaDictionary['Texts'].loc[i]+=' '+t | |
| SimilarAreaDictionary['Total Area'].loc[i]+=areaa | |
| SimilarAreaDictionary['Area'].loc[i]=areaa | |
| pFlagDF=0 | |
| color= (int(SimilarAreaDictionary['R'].loc[i])/255 , int(SimilarAreaDictionary['G'].loc[i])/255 , int(SimilarAreaDictionary['B'].loc[i])/255 ) | |
| for p in perimeters: | |
| if p[2]==x and p[3]==y and p[5]=='open': | |
| # if areaa >=5.15 and areaa<=5.25: | |
| shapee=[] | |
| SimilarAreaDictionary['Total Perimeter'].loc[i]+=round((p[4]-1)*ratioperim,3) | |
| SimilarAreaDictionary['Perimeter'].loc[i]=round((p[4]-1)*ratioperim,3) | |
| for poi in p[6]: | |
| x1, y1 = poi[0] | |
| p1 = fitz.Point(x1*ratio,y1*ratio) | |
| p1=p1*page.derotation_matrix | |
| shapee.append([p1[0],p1[1]]) | |
| annot11 = page.add_polyline_annot( points=shapee) # 'Polygon' | |
| annot11.set_border(width=0.2, dashes=[3]) | |
| annot1.set_colors(stroke=color ,fill=None) | |
| if len(alltxts)>0: | |
| annot11.set_info(content='Perimeter='+str(round((p[4]-1)*ratioperim,3))+' m',subject='ADR Team',title=str(alltxts[contour])) | |
| # annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE) | |
| annot11.update() | |
| pFlagDF=1 | |
| if pFlagDF==0: | |
| annot1 = page.add_polyline_annot( points=shape) # 'Polygon' | |
| annot1.set_border(width=0.2 ,dashes=[3]) | |
| annot1.set_colors(stroke=color ,fill=None) | |
| if len(alltxts)>0: | |
| annot1.set_info(content='Perimeter='+str(perimeterr)+' m',subject='ADR Team',title=str(alltxts[contour])) | |
| SimilarAreaDictionary['Total Perimeter'].loc[i]+=perimeterr | |
| SimilarAreaDictionary['Perimeter'].loc[i]=perimeterr | |
| SimilarAreaDictionary['Total Length'].loc[i]+=lengthShape | |
| SimilarAreaDictionary['Length'].loc[i]=lengthShape | |
| passed=1 | |
| cv2.drawContours(imgArea1, [contourssP[contour][0]], 0, ( int(SimilarAreaDictionary['B'].loc[i]), int(SimilarAreaDictionary['G'].loc[i]), int(SimilarAreaDictionary['R'].loc[i])), -1) | |
| annot = page.add_polygon_annot( points=shape) # 'Polygon' | |
| annot.set_border(width=0.2) | |
| annot.set_colors(stroke=color, fill= color ) | |
| annot.set_opacity(0.5) | |
| if len(alltxts)>0: | |
| annot.set_info(content='Area='+str(areaa)+ " m²",subject='ADR Team',title=str(alltxts[contour])) | |
| # annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE) | |
| annot.update() | |
| annot11 = page.add_polyline_annot( points=shapee) # 'Polygon' | |
| annot11.set_border(width=0.2, dashes=[3]) | |
| annot1.set_colors(stroke=color ,fill=None) | |
| annot11.set_info(content=' Length='+str(lengthShape)+' m',subject='ADR Team',title=str(alltxts[contour])) | |
| annot11.update() | |
| # cv2.putText(imgtransparent1,'Area: '+str(areaa) +' '+str(alltxts[contour])+' m2', (x+50,y-10) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2) | |
| pFlag=0 | |
| # for p in perimeters: | |
| # if p[2]==x and p[3]==y and p[5]=='open': | |
| # # if areaa >=5.15 and areaa<=5.25: | |
| # perimTotal+=round((p[4]-1)*ratioperim,3) | |
| # cv2.putText(imgtransparent1,'Perimeter: '+str(round((p[4])*ratioperim,3))+ ' m', (p[0]+50,p[1]-40) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2) | |
| # pFlag=1 | |
| # if pFlag==0: | |
| # cv2.putText(imgtransparent1,'Perimeter: '+str(perimeterr)+' m', (x+50,y-40) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2) | |
| for i, row in SimilarAreaDictionary.iterrows(): | |
| c = Counter( SimilarAreaDictionary['Guess'].loc[i]) | |
| if len(c) >0: | |
| value, count = c.most_common()[0] | |
| SimilarAreaDictionary['Guess'].loc[i]= value | |
| else: | |
| SimilarAreaDictionary['Guess'].loc[i]= 'none' | |
| # cv2.circle (imgtransparent1, (img.shape[0],img.shape[0]1), 5, 255, 5) | |
| alpha = 0.4 # Transparency factor. | |
| image_new1 = cv2.addWeighted(imgArea1, alpha, imgtransparent1, 1 - alpha, 0) | |
| if rotationOld==90: | |
| image_new1 = cv2.rotate(image_new1, cv2.ROTATE_90_CLOCKWISE) | |
| if rotationOld==180: | |
| image_new1 = cv2.rotate(image_new1, cv2.ROTATE_180) | |
| if rotationOld==270: | |
| image_new1 = cv2.rotate(image_new1, cv2.ROTATE_90_COUNTERCLOCKWISE) | |
| page.set_rotation(rotationOld) | |
| dbPath='/TSA JOBS/ADR Test'+pdfpath+'Measured Plan/' | |
| pdflink= tsadropboxretrieval.uploadanyFile(doc=doc,path=dbPath,pdfname=path) #doc=doc,pdfname=path,pdfpath=pdfpath+'Measured Plan/' | |
| dbxTeam=tsadropboxretrieval.ADR_Access_DropboxTeam('user') | |
| md, res =dbxTeam.files_download(path= dbPath+path) | |
| data = res.content | |
| doc=fitz.open("pdf", data) | |
| # list1=pd.DataFrame(columns=['content', 'creationDate', 'id', 'modDate', 'name', 'subject', 'title']) | |
| list1=pd.DataFrame(columns=['content', 'id', 'subject']) | |
| for page in doc: | |
| for annot in page.annots(): | |
| list1.loc[len(list1)] =annot.info | |
| gc,spreadsheet_service,spreadsheetId, spreadsheet_url , namepathArr=google_sheet_Legend.legendGoogleSheets(SimilarAreaDictionary , path,pdfpath) | |
| return imgPerimeter1,image_new1,SimilarAreaDictionary, colorsUsed , spreadsheet_url , spreadsheetId , list1 , pdflink , areas_Perimeters , namepathArr | |
| ###################################################### | |
| def deletemarkups(list1, dbPath , path): | |
| '''list1 : original markup pdf | |
| list2 : deleted markup pdf | |
| deletedrows : deleted markups - difference betw both dfs | |
| ''' | |
| myDict1=eval(list1) | |
| list1=pd.DataFrame(myDict1) | |
| areastodelete = [] | |
| perimstodelete=[] | |
| dbxTeam=tsadropboxretrieval.ADR_Access_DropboxTeam('user') | |
| # print('pathhhhh',dbPath+path) | |
| md, res =dbxTeam.files_download(path= dbPath+path) | |
| data = res.content | |
| doc=fitz.open("pdf", data) | |
| list2=pd.DataFrame(columns=['content', 'id', 'subject']) | |
| # list2=pd.DataFrame(columns=['content', 'creationDate', 'id', 'modDate', 'name', 'subject', 'title']) | |
| for page in doc: | |
| for annot in page.annots(): | |
| list2.loc[len(list2)] =annot.info | |
| # print(list1) | |
| deletedrows=pd.concat([list1,list2]).drop_duplicates(keep=False) | |
| print(deletedrows,len(deletedrows)) | |
| flag=0 | |
| if len(deletedrows)!=0: | |
| flag=1 | |
| deletedrows=deletedrows[['content', 'id', 'subject']] | |
| deletedrows = deletedrows.drop(deletedrows.index[deletedrows['content'].str.startswith('Scale')] )#, inplace=True) | |
| else: | |
| flag=0 | |
| return deletedrows | |
| ####################################################### | |