def findContours(self):
        im = cv2.imread('0.png')
        drawBoundsImg = im
        imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
        imgray = cv2.bilateralFilter(imgray, 11, 17, 17)
        edged = cv2.Canny(imgray, 30, 200)
        cv2.imwrite('canny.png',edged)
        image, contours, hierarchy = cv2.findContours(edged,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
        print 'origin ' + 'contours: ' + str(len(contours)) + ', ' + 'hierarchy: ' + str(len(hierarchy[0]))

        #build tree
        cn = CheckNode(123, '[0,48][720,1180]', 'removeExternalNode')
        cn.initialNode()
        tree = Tree()
        tree.add_node('root')
        listContours = []
        listPrintContours = [] #for tesing
        for i in xrange(len(contours)):
            tempCnt = []
            cnt = contours[i]
            hier = hierarchy[0][i]
            area = cv2.contourArea(cnt)
            x, y, w, h = cv2.boundingRect(cnt)
            tempCnt.append(x)
            tempCnt.append(y)
            tempCnt.append(x + w)
            tempCnt.append(y + h)
            listContours.append(tempCnt)
            if cn.checkNodeInRegion(tempCnt[0:2],tempCnt[2:4]) == True:
                if hier[3] ==  -1 and area > 300:
                    tree.add_node(str(tempCnt), 'root')
                    listPrintContours.append(tempCnt)
                elif hier[3] != -1 and area > 300:
                    nodeParent = str(listContours[hier[3]])
                    if nodeParent != str(tempCnt):
                        tree.add_node(str(tempCnt), nodeParent)
                        listPrintContours.append(tempCnt)
        tree.display('root')
        print "***** DEPTH-FIRST ITERATION *****"
        for node in tree.traverse('root'):
            print node 
        print 'remove small nodes and out of ROI nodes: ' + str(len(listPrintContours))
        for i, bounds in enumerate(listPrintContours):
            cv2.rectangle(drawBoundsImg, (bounds[0], bounds[1]), (bounds[2], bounds[3]), (255, 0, 0), 5)
            cv2.putText(drawBoundsImg,str(i),(bounds[0],bounds[1]), cv2.FONT_HERSHEY_SIMPLEX, 1,(0,0,255),3)
        cv2.imwrite('12345.png', drawBoundsImg)
    def findContoursForNoClickable(self, clickableButtonList, ROI):
        clickableXmlButtonList = copy.deepcopy(self.clickableButtonList)
        im = cv2.imread('0.png')
        drawBoundsImg = im
        imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
        imgray = cv2.bilateralFilter(imgray, 11, 17, 17)
        edged = cv2.Canny(imgray, 30, 200)
        cv2.imwrite('canny.png',edged)
        image, contours, hierarchy = cv2.findContours(edged,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
        try:
            print 'origin ' + 'contours: ' + str(len(contours)) + ', ' + 'hierarchy: ' + str(len(hierarchy[0]))
        except TypeError:
            print 'TypeError'

        #build tree
        #cn = CheckNode(123, '[0,48][720,1180]', 'removeExternalNode')
        cn = CheckNode(123, ROI, 'removeExternalNode')
        cn.initialNode()
        tree = Tree()
        tree.add_node('root')
        listContours = []     
        listPrintContours = [] #for tesing
        for i in xrange(len(contours)):
            tempCnt = []
            cnt = contours[i]
            hier = hierarchy[0][i]
            area = cv2.contourArea(cnt)
            x, y, w, h = cv2.boundingRect(cnt)
            tempCnt.append(x)
            tempCnt.append(y)
            tempCnt.append(x + w)
            tempCnt.append(y + h)
            tempCnt.append(self.appPackageName)
            listContours.append(tempCnt)
            if cn.checkNodeInRegion(tempCnt[0:2],tempCnt[2:4]) == True:
                if hier[3] ==  -1 and area > 600 and self.removeRedundantNode(clickableXmlButtonList, tempCnt) == True:
                    #tree.add_node(str(tempCnt), 'root')
                    listPrintContours.append(tempCnt)
                    clickableButtonList.append(tempCnt)
                elif hier[3] != -1 and area > 600 and self.removeRedundantNode(clickableXmlButtonList, tempCnt) == True:
                    nodeParent = str(listContours[hier[3]])
                    if nodeParent != str(tempCnt):
                        #tree.add_node(str(tempCnt), nodeParent)
                        listPrintContours.append(tempCnt)
                        clickableButtonList.append(tempCnt)
        #tree.display('root')
        print 'remove small nodes and out of ROI nodes: ' + str(len(listPrintContours))
        #print clickableButtonList

        
        #draw xml
        for i, bounds in enumerate(clickableXmlButtonList):
            cv2.rectangle(drawBoundsImg, (int(bounds[0]), int(bounds[1])), (int(bounds[2]), int(bounds[3])), (255, 0, 0), 5)
            cv2.putText(drawBoundsImg,str(i),(int(bounds[0]),int(bounds[1])), cv2.FONT_HERSHEY_SIMPLEX, 1,(0,0,255),3)
        cv2.imwrite('12345.png', drawBoundsImg)        
        
        #draw contours
        for i, bounds in enumerate(listPrintContours):
            cv2.rectangle(drawBoundsImg, (int(bounds[0]), int(bounds[1])), (int(bounds[2]), int(bounds[3])), (0, 255, 0), 2)
            cv2.putText(drawBoundsImg,str(i),(int(bounds[0]),int(bounds[1])), cv2.FONT_HERSHEY_SIMPLEX, 1,(0,0,255),3)
        cv2.imwrite('12345.png', drawBoundsImg)

        #print xml + CV
        file = open('xmlcv.txt', 'w')
        file.write('**********xml bounds**********' + '\n')
        flag = False
        for bounds in clickableButtonList:
            if len(bounds) != 5:
                file.write(str(bounds) + '\n')
            elif len(bounds) == 5 and flag ==False:
                file.write('**********cv bounds**********' + '\n')
                file.write(str(bounds) + '\n')
                flag = True
            else:
                file.write(str(bounds) + '\n')
        file.close
               
        return clickableButtonList