def loadBalloonsFromSVG(filename, foldername, tagName, attributeClass, verbose): polygons = [] contours = [] #w, h = imgSize nbContour = 0 #nbMatch = 0 #nbSmooth = 0 #nbWavy = 0 #nbZigzag = 0 #nbNoTMatch = 0 sumMeanHeight = 0 #s = filepath.split(os.sep) #filepath = s[len(s) - 1] if verbose: img = cv2.imread('/media/Donnees/DATA/DATASET/eBDtheque_100/'+filename.split('.')[0]+'.jpg') if not filename.endswith('svg'): print 'ERROR in loadBalloonsFromSVG: not an SVG file (',filename,')' return w, h = toolbox_svg.getImageSizeFromSvg(foldername+filename) xmldoc = parse(foldername+filename) itemlist = xmldoc.getElementsByTagName(tagName) # find all polygon elements #contoursSVGImg = numpy.zeros([h, w], numpy.uint8) #defectsImg = numpy.zeros([h, w], numpy.uint8) itemListIterator = 0 for item in itemlist : # process only polygon that are in a svg tag with class=Balloon if item.parentNode.attributes['class'].value == attributeClass: points = item.attributes['points'].value coords = points.split(' ') balloonType = 'unknown' #if loadTypeFromText: # balloonType = getTypeFromTextFile(filepath.split('.')[0]+'.txt', itemListIterator) # itemListIterator += 1 #else: # for child in item.childNodes: # if child.nodeType == 1: # balloonType = child.attributes['shape'].value #if balloonType == 'unknown' or balloonType == '': # print 'WARNING: unknwon or empty balloon type in',filepath, #Convert point list into an array contour = toolbox_svg.svgList2NumpyArray(coords) #Barycenter M = cv2.moments(contour) try: c_x = int(M['m10']/M['m00']) c_y = int(M['m01']/M['m00']) except: print 'ERROR: division by zero in barycenter of contour',contour,'in file',filename,'(coords=',coords,')' c_x = 0 c_y = 0 #Spacial position of the balloon t, b, l, r = coord2box(coords, w, h)#xList, yList, w, h ) #coef = 100 / max((b-t),(r-l))# / 100.0 #contourDiv = rint(contour/coef).astype(int) #divide the contour by a scalar and keep the closest integer value. Then convert as integer #print 'coef=',coef,'contour=',contour,'contourDiv=',contourDiv #Draw contour to equalize the number of points newDrawing = numpy.zeros([h, w], numpy.uint8) cv2.drawContours(newDrawing,[contour],0,(100,50,255),0) #Normalize and detect again contour (spatial lost) newContours, hierachy = cv2.findContours(newDrawing.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) newContour = newContours[0] #Get tail direction and position fro metadata tag tailDirection = item.childNodes[1].attributes['tailDirection'].value tailTip = item.childNodes[1].attributes['tailTip'].value #if verbose: # cv2.circle(img,(c_x, c_y),1,[255,0,0],2) #plot barycenter for thumbnail # cv2.circle(img,tuple(newContour[0][0]),1,[0,255,0],2) #plot starting point for thumbnail if verbose: #Draw contour cv2.drawContours(img,[newContour],0,(255,0,0),1) #RGB #Draw position line if tailTip != '': x1, y1 = tailTip.split(',') cv2.circle(img, (int(x1), int(y1)), 5, (0,255,0), 2) thumbnail = img[t:b, l:r] else: thumbnail = None #New MyBalloon object myBalloon = class_balloon.MyBalloon(points, [c_x, c_y], newContour, balloonType, [t, b, l, r], thumbnail, [c_x, c_y], tailTip, tailDirection ) #Add new contour to the contour list contours.append(myBalloon) del contour #if verbose: #Draw contour for later use #cv2.drawContours(img,[newContour],0,(255,0,0),1) #RGB nbContour += 1 return contours
def loadFromGT(self, svgPath, objectType, boundingBoxOnly, nonValidRegionList=None, modeGT=False): """ Load regions from ground truth SVG (eBDtheque dataset) """ regions = [] n = 1 #Test file existence if not os.path.isfile(svgPath): print 'ERROR: file not found (',svgPath,')' return xmldoc = parse(svgPath) itemlist = xmldoc.getElementsByTagName('polygon') for s in itemlist : if s.parentNode.attributes['class'].value == objectType: xList = [] yList = [] points = s.attributes['points'].value #If the region has been detected as invalid before then ignore it (do not load) if nonValidRegionList != None: idRegion = s.childNodes[1].attributes['id'].value + '\n' if idRegion in nonValidRegionList: print '-',#idRegion,'is nonValidRegionList (not loaded)' continue coords = points.split(' ') #Compute bounding box for c in coords: pts = c.split(',') xList.append(int(pts[0])) yList.append(int(pts[1])) #Build the region bounding box l = min(xList) t = min(yList) r = max(xList) b = max(yList) box = (int(l),int(t),int(r),int(b)) if modeGT: if objectType == 'Balloon': # Filter on closed balloons only for GT only # try: # borderStyle = s.childNodes[1].attributes['borderStyle'].value # if borderStyle == 'other': # print '-', # n = n + 1 # continue # except: # pass # Filter on speech balloons (with tail) # try: # tailTip = s.childNodes[1].attributes['tailTip'].value # if tailTip == "": # print '-', # n = n + 1 # continue # except: # pass pass if objectType == 'Line': # #Filter on speech text for GT only # r1 = (box[0], box[1]), (box[2], box[3]) # (left, top), (right, bottom) # #Load balloons # balloons = self.loadFromGT(svgPath, 'Balloon', boundingBoxOnly=True, nonValidRegionList=None, modeGT=False) # isContained = False # for b in balloons: # obj = b # r2 = (obj[0], obj[1]), (obj[2], obj[3]) # res = self.intersect(r1, r2) # empty = (0, 0), (0, 0)# The empty rectangle. # #If included in a balloon # if res != empty: # intersectArea = (res[1][0]-res[0][0]) * (res[1][1]-res[0][1]) # if intersectArea > 50: # #print 'Line',box,'intersect balloon',b # isContained = True # break # if not isContained: # print '-', # #Ignore text line # continue # else: # #Ignore if this balloon has no tail # try: # tailTip = s.childNodes[1].attributes['tailTip'].value # if tailTip == "": # print '-', # n = n + 1 # #Ignore text line # continue # except: # pass pass #Add region to the list if boundingBoxOnly: regions.append(box) else: regions.append(toolbox_svg.svgList2NumpyArray(coords)) n = n + 1 return regions