def __filter_ws_rects(self, hr: Region): hcs = hr.get_hcs() if self.__debug: for i, hc in enumerate(hcs): color = [0, 0, 0] color[i % 3] = 255 for cc in hc: x, y, w, h = cc.get_rect() cv.rectangle(self.__src, (x, y), (x + w, y + h), tuple(color), -1) only_single_cc_chains = True for hc in hcs: if len(hc) > 1: only_single_cc_chains = False break if only_single_cc_chains: return ws_rects = WhiteSpaceFilter.__get_hcs_ws_rects(hcs) self.__filter_small_and_isolated_ws(hcs, ws_rects) for i in range(2): self.__filter_within_col_candidates(ws_rects, i) if self.__debug: iu.show_and_wait('Whitespace filtering (color coded)', self.__src)
def __label_regions(self): self.__img_contoured, self.__img_labeled = self.__region_refiner.label_regions( self.__img_resized, self.__ccs_dict) if self.__debug: iu.show_and_wait('Contoured', self.__img_contoured) iu.show_and_wait('Labeled', self.__img_labeled)
def __smooth_img(self): # self.__img = cv.GaussianBlur(self.__img, (KERNEL_SIZE, KERNEL_SIZE), 0) # self.__img = cv.medianBlur(self.__img, KERNEL_SIZE) # kernel = np.ones((KERNEL_SIZE, KERNEL_SIZE), np.float32) # kernel /= (KERNEL_SIZE ** 2) # self.__img = cv.filter2D(self.__img, -1, kernel) self.__img = cv.blur(self.__img, (KERNEL_SIZE, KERNEL_SIZE)) if self.__debug: iu.show_and_wait('Smoothed (Blurred) Image', self.__img)
def __get_bounding_box_text_img(self, c=0): text_lines = self.__extract_text_lines() blank = np.zeros(self.__img.shape[0:2], np.uint8) for text_line in text_lines: x, y, w, h = text_line cv.rectangle(blank, (x, y + c), (x + w, y + h - c), 255, -1) self.__img = blank if self.__debug: iu.show_and_wait('Bounding Box', self.__img) return self.__img
def __segment_paragraphs(self, text_blocks): new_hrs = [] for text_block in text_blocks: next_hrs = self.__segment_region_paragraphs(text_block) new_hrs.extend(next_hrs) if self.__debug: img_blocks = self.src.copy() for hr in new_hrs: x, y, w, h = hr.get_rect() cv.rectangle(img_blocks, (x, y), (x + w, y + h), (255, 0, 255), 4) iu.show_and_wait('Paragraphs', img_blocks) return new_hrs
def __filter_ws(self): kernel = np.ones((1, 5), np.uint8) self.__img = cv.morphologyEx(self.__img, cv.MORPH_CLOSE, kernel, iterations=4) if self.__debug: iu.show_and_wait('Horizontal Closing', self.__img) ws_filter = WhiteSpaceFilter(self.__img, self.src, self.__debug) hr = MllClassifier(self.__img).get_region() self.__img = ws_filter.filter_ws(hr) self.__get_bounding_box_text_img(1)
def __smooth_regions(self, hrs): ccs_text = [] for hr in hrs: ccs = self.__smooth_region(hr) ccs_text.extend(ccs) blank = np.zeros(self.__img.shape[:2], np.uint8) self.__img = cv.drawContours(blank, [cc.get_contour() for cc in ccs_text], -1, 255, -1) if self.__debug: iu.show_and_wait('Bounding Box (Smoothed)', self.__img) return ccs_text
def analyze_document(self): if self.__debug: iu.show_and_wait('Image', self.__src) preprocessed = self.__preprocess() self.__apply_heuristic_filter(preprocessed) self.__apply_mll_classifier() self.__segment_text() ccs_non_text, rect_ccs_non_text = self.__refine_non_text_elements() self.__classify_non_text_element(ccs_non_text, rect_ccs_non_text) self.__label_regions() self.__img_contoured_original_size = self.__rescale_img_to_original( self.__img_contoured) self.__img_labeled_original_size = self.__rescale_img_to_original( self.__img_labeled) self.__store_output_img()
def remove_intersected_regions(self, img_text, ccs_non_text): img_text = img_text.copy() ccs_non_text = ccs_non_text.copy() kernel = np.ones((3, 1), np.uint8) # dilation = cv.dilate(img_text, kernel) closing = cv.morphologyEx(img_text, cv.MORPH_CLOSE, kernel, iterations=4) ccs_text = get_connected_components(closing, external=True) img_text = np.zeros(img_text.shape, np.uint8) img_non_text = np.zeros(img_text.shape, np.uint8) cv.drawContours(img_text, [cc.get_contour() for cc in ccs_text], -1, 255, -1) cv.drawContours(img_non_text, [cc.get_contour() for cc in ccs_non_text], -1, 255, -1) ccs_non_text = get_connected_components(img_non_text, external=True) ccs_text_new = [] for cc_non_text in ccs_non_text.copy(): for cc_text in ccs_text: # if cc_text.contains(cc_non_text) or does_intersect(self.__img_shape, cc_text, cc_non_text): # if includes(img_shape, cc_text, cc_non_text): # if cc_text.contains(cc_non_text): if cc_text.get_rect_area() > cc_non_text.get_rect_area() and \ intersection_percentage(cc_text, cc_non_text) >= 0.9: x, y, w, h = cc_non_text.get_rect() cv.rectangle(img_text, (x, y), (x + w, y + h), 255, -1) ccs_text_new.append(cc_non_text) ccs_non_text.remove(cc_non_text) break ccs_non_text_new = [] for cc_text in ccs_text: for cc_non_text in ccs_non_text: # if cc_non_text.contains(cc_text) and cc_non_text.get_dens() > 0.02: if cc_non_text.get_rect_area() > cc_text.get_rect_area() and \ intersection_percentage(cc_non_text, cc_text) >= 0.9 and cc_non_text.get_dens() > 0.02: x, y, w, h = cc_text.get_rect() cv.rectangle(img_text, (x, y), (x + w, y + h), 0, -1) ccs_non_text_new.append(cc_text) break ccs_non_text.extend(ccs_non_text_new) if self.__debug: iu.show_and_wait('Intersections Grouping', img_text) kernel = np.ones((3, 3), np.uint8) img_text = cv.morphologyEx(img_text, cv.MORPH_CLOSE, kernel, iterations=4) if self.__debug: iu.show_and_wait('Intersections Grouping (Morph-Close)', img_text) ccs_text = get_connected_components(img_text, external=True) return ccs_text, ccs_non_text, ccs_text_new, ccs_non_text_new
def __get_text_blocks(self): ccs, self.__ccs_non_text, ccs_text_new, ccs_non_text_new = RegionRefiner( self.__debug).remove_intersected_regions(self.__img, self.__ccs_non_text) for cc_text_new in ccs_text_new: x, y, w, h = cc_text_new.get_rect() cv.rectangle(self.__img, (x, y + 3), (x + w, y + h - 3), 255, -1) for cc_non_text_new in ccs_non_text_new: x, y, w, h = cc_non_text_new.get_rect() cv.rectangle(self.__img, (x, y), (x + w, y + h), 0, -1) # text_blocks = [cc.get_rect() for cc in ccs] text_blocks = ccs.copy() if self.__debug: img_blocks = self.src.copy() for text_block in text_blocks: x, y, w, h = text_block.get_rect() cv.rectangle(img_blocks, (x, y), (x + w, y + h), (255, 0, 0), 4) iu.show_and_wait('Text Blocks', img_blocks) return text_blocks
def __binarize_img(self): self.__img = Binarizer(self.__img).binarize() if self.__debug: iu.show_and_wait('Binarized Image', self.__img)
def __img_to_grayscale(self): if len(self.__img.shape) == 3: self.__img = cv.cvtColor(self.__img, cv.COLOR_BGR2GRAY) if self.__debug: iu.show_and_wait('Grayscale Image', self.__img)