def textDetect(img, original): """ Text detection using contours """ # Resize image small = resize(img, 2000) image = resize(original, 2000) # Finding contours mask = np.zeros(small.shape, np.uint8) im2, cnt, hierarchy = cv2.findContours(np.copy(small), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) #implt(img, 'gray') # Variables for contour index and words' bounding boxes index = 0 boundingBoxes = np.array([0,0,0,0]) bBoxes = [] # CCOMP hierarchy: [Next, Previous, First Child, Parent] # cv2.RETR_CCOMP - contours into 2 levels # Go through all contours in first level while (index >= 0): x,y,w,h = cv2.boundingRect(cnt[index]) # Get only the contour cv2.drawContours(mask, cnt, index, (255, 255, 255), cv2.FILLED) maskROI = mask[y:y+h, x:x+w] # Ratio of white pixels to area of bounding rectangle r = float(cv2.countNonZero(maskROI)) / (w * h) # Limits for text (white pixel ratio, width, height) # TODO Test h/w and w/h ratios if r > 0.1 and 1600 > w > 10 and 1600 > h > 10 and h/w < 3 and w/h < 10 and (60 // h) * w < 1000: bBoxes += [[x, y, w, h]] # Index of next contour index = hierarchy[0][index][0] # Group intersecting rectangles bBoxes = groupRectangles(bBoxes) i = 0 f = open("output/words/normal/bounding_boxes_normal.txt","w") for (x, y, w, h) in bBoxes: boundingBoxes = np.vstack((boundingBoxes, np.array([x, y, x+w, y+h]))) cv2.imwrite("output/words/normal/"+str(i)+".jpg",image[y:y+h, x:x+w]) f.write(str(i) + "\t => \t" + "("+str(x)+","+str(y)+")"+","+"("+str(x+w)+","+str(y+h)+")"+"\n") # cv2.rectangle(image, (x, y),(x+w,y+h), (0, 255, 0), 2) i = i+1 #implt(image, t='Bounding rectangles') # Recalculate coordinates to original scale bBoxes = boundingBoxes.dot(ratio(image, small.shape[0])).astype(np.int64) return bBoxes[1:]
def text_detect(img, original): """ Text detection using contours """ # Resize image small = resize(img, 2000) image = resize(original, 2000) # Finding contours mask = np.zeros(small.shape, np.uint8) cnt, hierarchy = cv2.findContours(np.copy(small), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) implt(img, 'gray') # Variables for contour index and words' bounding boxes index = 0 boxes = [] # CCOMP hierarchy: [Next, Previous, First Child, Parent] # cv2.RETR_CCOMP - contours into 2 levels # Go through all contours in first level while (index >= 0): x, y, w, h = cv2.boundingRect(cnt[index]) # Get only the contour cv2.drawContours(mask, cnt, index, (255, 255, 255), cv2.FILLED) maskROI = mask[y:y + h, x:x + w] # Ratio of white pixels to area of bounding rectangle r = cv2.countNonZero(maskROI) / (w * h) # Limits for text (white pixel ratio, width, height) # TODO Test h/w and w/h ratios if r > 0.1 and 2000 > w > 10 and 1600 > h > 10 and h / w < 3 and w / h < 10: boxes += [[x, y, w, h]] # Index of next contour index = hierarchy[0][index][0] # Group intersecting rectangles boxes = group_rectangles(boxes) bounding_boxes = np.array([0, 0, 0, 0]) for (x, y, w, h) in boxes: cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 8) print((x, y, w, h)) bounding_boxes = np.vstack( (bounding_boxes, np.array([x, y, x + w, y + h]))) implt(image, t='Bounding rectangles') # Recalculate coordinates to original scale boxes = bounding_boxes.dot(ratio(image, small.shape[0])).astype(np.int64) return boxes[1:]
def textDetectWatershed(thresh, original): """ Text detection using watershed algorithm """ # According to: http://docs.opencv.org/trunk/d3/db4/tutorial_py_watershed.html img = resize(original, 3000) thresh = resize(thresh, 3000) # noise removal kernel = np.ones((3,3),np.uint8) opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 3) # sure background area sure_bg = cv2.dilate(opening,kernel,iterations=3) # Finding sure foreground area dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5) ret, sure_fg = cv2.threshold(dist_transform,0.01*dist_transform.max(),255,0) # Finding unknown region sure_fg = np.uint8(sure_fg) # cv2.imshow("image",sure_fg) # cv2.waitKey(10) unknown = cv2.subtract(sure_bg,sure_fg) # Marker labelling ret, markers = cv2.connectedComponents(sure_fg) # Add one to all labels so that sure background is not 0, but 1 markers += 1 # Now, mark the region of unknown with zero markers[unknown == 255] = 0 markers = cv2.watershed(img, markers) #implt(markers, t='Markers') image = img.copy() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Creating result array boundingBoxes = np.array([0,0,0,0]) bBoxes = [] for mark in np.unique(markers): # mark == 0 --> background if mark == 0: continue # Draw it on mask and detect biggest contour mask = np.zeros(gray.shape, dtype="uint8") mask[markers == mark] = 255 cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] c = max(cnts, key=cv2.contourArea) # Draw a bounding rectangle if it contains text x,y,w,h = cv2.boundingRect(c) cv2.drawContours(mask, c, 0, (255, 255, 255), cv2.FILLED) maskROI = mask[y:y+h, x:x+w] # Ratio of white pixels to area of bounding rectangle r = float(cv2.countNonZero(maskROI)) / (w * h) # Limits for text # WORK ON THIS if r > 0.1 and 2000 > w > 15 and 1500 > h > 15: bBoxes += [[x, y, w, h]] # Group intersecting rectangles #bBoxes = groupRectangles(bBoxes) i = 0 f = open("./output/words/watershed/bounding_boxes_watershed.txt","w") for (x, y, w, h) in bBoxes: boundingBoxes = np.vstack((boundingBoxes, np.array([x, y, x+w, y+h]))) cv2.imwrite("./output/words/watershed/"+str(i)+".jpg",image[y:y+h, x:x+w]) f.write(str(i) + "\t => \t" + "("+str(x)+","+str(y)+")"+","+"("+str(x+w)+","+str(y+h)+")"+"\n") # cv2.rectangle(image, (x, y),(x+w,y+h), (0, 255, 0), 2) i = i+1 #implt(image) # Recalculate coordinates to original size bBoxes = boundingBoxes.dot(ratio(original, 3000)).astype(np.int64) return bBoxes[1:]
if (len(approx) == 4 and cv2.isContourConvex(approx) and maxArea < cv2.contourArea(approx) < MAX_COUNTOUR_AREA): maxArea = cv2.contourArea(approx) pageContour = approx[:, 0] pageContour = fourCornersSort(pageContour) return contourOffset(pageContour, (-5, -5)) pageContour = findPageContours(closedEdges, resize(image)) print("PAGE CONTOUR:") print(pageContour) implt(cv2.drawContours(resize(image), [pageContour], -1, (0, 255, 0), 3)) pageContour = pageContour.dot(ratio(image)) def edgesDet(img, minVal, maxVal): img = cv2.cvtColor(resize(img), cv2.COLOR_BGR2GRAY) img = cv2.bilateralFilter(img, 9, 75, 75) img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 4) implt(img, 'gray', 'Adaptive Threshold') img = cv2.medianBlur(img, 11) img = cv2.copyMakeBorder(img, 5, 5,
M = cv2.getPerspectiveTransform(s_points, t_points) return cv2.warpPerspective(img, M, (int(width), int(height))) if __name__ == "__main__": IMG = "hough_test" # Image name/number # Loading images and ploting it (converting to RGB from BGR) image = cv2.cvtColor(cv2.imread("image/%s.jpg" % IMG), cv2.COLOR_BGR2RGB) implt(image) # Edge detection () edges_image = edges_det(image, 200, 250) # Close gaps between edges (double page clouse => rectangle kernel) edges_image = cv2.morphologyEx(edges_image, cv2.MORPH_CLOSE, np.ones((5, 11))) implt(edges_image, 'gray', 'Edges') page_contour = find_page_contours(edges_image, resize(image)) print("PAGE CONTOUR:") print(page_contour) implt(cv2.drawContours(resize(image), [page_contour], -1, (0, 255, 0), 3)) # Recalculate to original scale page_contour = page_contour.dot(ratio(image)) newImage = persp_transform(image, page_contour) implt(newImage, t='Result')
def text_detect(img, original): """ Text detection using contours """ # Resize image small = resize(img, 2000) image = resize(original, 2000) # Finding contours mask = np.zeros(small.shape, np.uint8) im2, cnt, hierarchy = cv2.findContours(np.copy(small), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) # implt(img, 'gray') # Variables for contour index and words' bounding boxes index = 0 boxes = [] test_digits = np.array(np.zeros((1,784))) i = 0 # CCOMP hierarchy: [Next, Previous, First Child, Parent] # cv2.RETR_CCOMP - contours into 2 levels # Go through all contours in first level while (index >= 0): x,y,w,h = cv2.boundingRect(cnt[index]) # Get only the contour cv2.drawContours(mask, cnt, index, (255, 255, 255), cv2.FILLED) maskROI = mask[y:y+h, x:x+w] # Ratio of white pixels to area of bounding rectangle r = cv2.countNonZero(maskROI) / (w * h) # Limits for text (white pixel ratio, width, height) # TODO Test h/w and w/h ratios # if r > 0.1 and 2000 > w > 10 and 1600 > h > 10 and h/w < 3 and w/h < 10: if r > 0.1 and 40 > w > 1 and 1600 > h > 10 and (h/w < 3 or w/h < 10): boxes += [[x, y, w, h]] roi = image[y:y+h, x:x+w] digit = cv2.cvtColor(roi, cv2.COLOR_RGB2GRAY) digit, j = digit_preprocessing(digit) cv2.imwrite("../data/form/output{0}.jpg".format(i), digit) digit_row = np.resize(digit,(1,784)) test_digits = np.append(test_digits,digit_row,axis=0) i += 1 # Index of next contour index = hierarchy[0][index][0] # Group intersecting rectangles boxes = group_rectangles(boxes) bounding_boxes = np.array([0,0,0,0]) for (x, y, w, h) in boxes: cv2.rectangle(image, (x, y),(x+w,y+h), (0, 255, 0), 8) bounding_boxes = np.vstack((bounding_boxes, np.array([x, y, x+w, y+h]))) implt(image, t='Bounding rectangles') # Recalculate coordinates to original scale boxes = bounding_boxes.dot(ratio(image, small.shape[0])).astype(np.int64) return test_digits, boxes[1:]