def _get_line_filter(segment_size, variation): """Computes the filters that can be used to enhance vertical lines in an Image. Args: segment_size: Size of the segment variatoin: Variation in horizontal axes if user wants not exact vertical lines. Returns: filters saved in 3D matrices, each 3rd dimension includes a filter """ smalldisk = pymorph.sedisk(1); bigdisk = pymorph.sedisk(2); horizontal_filter = numpy.zeros((variation*2+1, variation*2+1, segment_size)) horizontal_surrounding = numpy.zeros((variation*2+1, variation*2+1, segment_size)) index = -1 # Generates the filters for each direction of lines for variation_index in range(-variation, variation + 1): index = index + 1; points = bresenham(variation + variation_index,0, variation - variation_index, segment_size - 1) tmp = numpy.zeros((variation*2+1)*segment_size).reshape((variation*2+1, segment_size)) for point_ind in range(0, len(points)): tup_point = points[point_ind] tmp[tup_point[0], tup_point[1]] = 1 tmp_filter = pymorph.dilate(pymorph.binary(tmp), smalldisk) tmp_surrounding = pymorph.subm(pymorph.dilate(pymorph.binary(tmp), bigdisk) , \ pymorph.dilate(pymorph.binary(tmp), smalldisk)) horizontal_filter[index,:,:] = tmp_filter horizontal_surrounding[index,:,:] = tmp_surrounding return horizontal_filter, horizontal_surrounding
def crp_rsz_bin(img_file, crop_size=150, resize_size=40, bin_k=60, show_plot=True): img = Image.open(img_file) plt.subplot(141) plt.imshow(img) width, height = img.size # Get dimensions left = (width - crop_size)/2 top = (height - crop_size)/2 right = (width + crop_size)/2 bottom = (height + crop_size)/2 img = img.crop((left, top, right, bottom)) plt.subplot(142) plt.imshow(img) img = img.resize((resize_size,resize_size), Image.ANTIALIAS) img.save('_img.jpg') img= misc.imread('_img.jpg', flatten=1) plt.subplot(143) plt.imshow(img) img = img.astype(np.uint8) img = MM.binary(img,k=bin_k) img = np.asarray(img, dtype='int') plt.subplot(144) plt.imshow(img) if show_plot: plt.show() return img
def test_close_holes_simple(): H = pymorph.binary([ [0,0,0,0,0,0], [0,1,1,1,1,0], [0,1,0,0,1,0], [0,1,1,1,1,0], [0,0,0,0,0,0], ]) Hclosed = pymorph.close_holes(H) assert np.all(Hclosed == pymorph.binary([ [0,0,0,0,0,0], [0,1,1,1,1,0], [0,1,1,1,1,0], [0,1,1,1,1,0], [0,0,0,0,0,0], ]))
def ThinImage(imgPath): img = Image.open(imgPath).convert('L') imgArray = numpy.asarray(img) imgBinary = pymorph.neg(pymorph.binary(imgArray)) img = pymorph.thin(imgBinary) iPrune = pymorph.thin(img,pymorph.endpoints('homotopic'),10) Image.fromarray(pymorph.gray(pymorph.neg(iPrune))).save('thinned.png','PNG') print "Saving"
def thinning(img, iters=-1, theta=45): """ thinning morphological operation """ # convert to binary assert len(img.shape) == 2 bin_img = pymorph.binary(img) result = pymorph.thin(bin_img, n=iters, theta=theta) return pymorph.gray(result)
def skelm(img, mask=None): """skeleton operation """ assert len(img.shape) == 2 bin_img = pymorph.binary(img) if mask == None: result = pymorph.skelm(bin_img) else: result = pymorph.skelm(bin_img, mask) return pymorph.gray(result)
def _get_grid_img(self, crop_img, elem_contour): cnt = Contour(elem_contour) halfbox = cnt.shrinkbox(100).astype("f") square = self._square_coordinates(cnt.side) trans = cv2.getPerspectiveTransform(halfbox, square) box = cv2.warpPerspective(crop_img, trans, (cnt.side, cnt.side)) _, thresh = cv2.threshold(box, 127, 255, 0) binary = pm.binary(thresh) box = binary.astype(int) * 255 box = pm.edgeoff(box) box = mh.croptobbox(box) return box
def _get_line_filter(segment_size, variation): """Computes the filters that can be used to enhance vertical lines in an Image. Args: segment_size: Size of the segment variatoin: Variation in horizontal axes if user wants not exact vertical lines. Returns: filters saved in 3D matrices, each 3rd dimension includes a filter """ smalldisk = pymorph.sedisk(1) bigdisk = pymorph.sedisk(2) horizontal_filter = numpy.zeros( (variation * 2 + 1, variation * 2 + 1, segment_size)) horizontal_surrounding = numpy.zeros( (variation * 2 + 1, variation * 2 + 1, segment_size)) index = -1 # Generates the filters for each direction of lines for variation_index in range(-variation, variation + 1): index = index + 1 points = bresenham(variation + variation_index, 0, variation - variation_index, segment_size - 1) tmp = numpy.zeros((variation * 2 + 1) * segment_size).reshape( (variation * 2 + 1, segment_size)) for point_ind in range(0, len(points)): tup_point = points[point_ind] tmp[tup_point[0], tup_point[1]] = 1 tmp_filter = pymorph.dilate(pymorph.binary(tmp), smalldisk) tmp_surrounding = pymorph.subm(pymorph.dilate(pymorph.binary(tmp), bigdisk) , \ pymorph.dilate(pymorph.binary(tmp), smalldisk)) horizontal_filter[index, :, :] = tmp_filter horizontal_surrounding[index, :, :] = tmp_surrounding return horizontal_filter, horizontal_surrounding
def _getLineFilter(self, segmentSize, variation): smallDisk = pymorph.sedisk(1); bigDisk = pymorph.sedisk(2); horizontal_filter = numpy.zeros((variation*2+1,variation*2+1,segmentSize)) horizontal_surrounding = numpy.zeros((variation*2+1,variation*2+1,segmentSize)) index = -1 for i in range(-variation,variation+1): index = index + 1; # find the line between selected points points = bresenham(variation+i,0,variation-i,segmentSize-1) tmp = numpy.zeros((variation*2+1)*segmentSize).reshape((variation*2+1, segmentSize)) for l in range(0, len(points)): tup_point = points[l] tmp[tup_point[0], tup_point[1]] = 1 tmp_filter = pymorph.dilate(pymorph.binary(tmp), smallDisk) tmp_surrounding = pymorph.subm(pymorph.dilate(pymorph.binary(tmp), bigDisk) , pymorph.dilate(pymorph.binary(tmp), smallDisk)) horizontal_filter[index,:,:] = tmp_filter horizontal_surrounding[index,:,:] = tmp_surrounding return horizontal_filter, horizontal_surrounding
def find_most_connected_crossings(crossings, column, region_length): ###may cause a problem in here if column is not scalar # if np.isscalar(column): # bw_region = np.abs(crossings-column) <= region_length # else: # bw_region = np.abs() crossings0 = crossings.copy() BW_region = np.array(np.abs(crossings0 - column) <= region_length, dtype=bool) ##warning: RuntimeWarning: invalid value encountered in absolute Search_region = pymorph.cdilate(pymorph.binary(BW_region), pymorph.binary(np.isfinite(crossings0))) Search_region = np.array(Search_region, dtype=bool) crossings0[np.bitwise_not(Search_region)] = np.NAN finite_crossing = np.isfinite(crossings0) if np.sum(np.isfinite(crossings0), 1).all() <= 1: return crossings0 ##Label each connected trail of crossings Cross_label = measure.label(finite_crossing) Cross_LabelNum = np.zeros(Cross_label.shape) if np.max(Cross_label) == 1: crossings0[Cross_label==1] = np.NAN else: #count the number of crossings per trail for templabel in xrange(1, np.max(Cross_label) +1): Cross_LabelNum[Cross_label==templabel] = np.count_nonzero(Cross_label[Cross_label==templabel]) BW_region = Cross_LabelNum == np.tile(np.max(Cross_LabelNum, 1), (1, Cross_LabelNum.shape[1])) crossings0[np.bitwise_not(BW_region)] = np.NAN return crossings0
def image_to_puzzle(self, img): """ Applys OCR to image and returns a dictionary predicted puzzle grid elements. Parameters ---------- img : ndarray Any integer image type Returns ------- dict(key, value) : string, string key is the grid_id where grid rows are letters A-I and columns are numbers 1-9. e.g. A1 A2 A3 | A4 A5 A6 | A7 A8 A9 B1 B2 B4 | B4 B5 B6 | B7 B8 B9 C1 ... """ crop_img, crop_contour = self._crop_to_puzzle_area(img) grid_elems = self._generate_grid_elements(crop_contour) puzzle = {} for elem_id, elem_contour in grid_elems.items(): elem_img = self._get_grid_img(crop_img, elem_contour) if reduce(lambda x, y: x*y, elem_img.shape) < 500: puzzle[elem_id] = "0" continue elem_img = pm.binary(elem_img).astype("float32") elem_img = self._MNIST_preprocess(elem_img) if elem_img is None: puzzle[elem_id] = "0" continue features = self.feature_alg.get_features(elem_img) guess = self.ocr_alg.predict(features) puzzle[elem_id] = str(guess[0]) return puzzle
otpf.write('1 1 0'+'*'+str(ix)+' '+str(jx)+'\n') cur_cords = (ix, jx) # Converting the input image to binary based on Otsu's thresholding im_gray = cv2.imread('ztemp.png', cv2.CV_LOAD_IMAGE_GRAYSCALE) (thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # Creating thinning elements telem1 = pymorph.homothin() telem2a = np.array([[False, False, False], [True, True, False], [False, True, False]]) telem2b = np.array([[False, True, True], [False, False, True], [False, False, False]]) telem2 = (telem2a, telem2b) # Thinning the binary image thin_img = skeletor(pymorph.binary(255-im_bw), telem1, telem2) # Creating pruning elements prunera = np.array([[False, True, False], [True, True, True], [False, True, False]]) prunerb = np.array([[False, False, False], [False, False, False], [False, False, False]]) prunere = (prunera, prunerb) # Pruning the thinned image thin_img2 = pruner(thin_img, prunere) # Saving the final pruned and thinned image cv2.imwrite('skeleton.png', thin_img2) # Performing hybrid DFS of the image dfs(thin_img2)
def alternative_solution(self, a, orientation='coronal', linethickness=10, outimg=False): ''' Paramenters ----------- a: original image in graylevel ''' H, W = a.shape if orientation == 'coronal': # UL = mm.limits(a)[1] # upper limit UL = 255 b = 1 - iacircle(a.shape, H / 3, (1.4 * H / 3, W / 2)) # Circle b = b[0:70, W / 2 - 80:W / 2 + 80] # Rectangle # if outimg: # b_ = 0 * a; b_[0:70, W / 2 - 80:W / 2 + 80] = UL * b # b_ only for presentation # b_[:, W / 2 - linethickness / 2:W / 2 + linethickness / 2] = UL # b_ only for presentation c = a + 0 c[:, W / 2 - linethickness / 2:W / 2 + linethickness / 2] = UL c[0:70, W / 2 - 80:W / 2 + 80] = (1 - b) * c[0:70, W / 2 - 80:W / 2 + 80] + b * UL c[0:40, W / 2 - 70:W / 2 + 70] = UL d = mm.open(c, mm.img2se(mm.binary(np.ones((20, 10))))) e = mm.close(d, mm.seline(5)) f = mm.close_holes(e) g = mm.subm(f, d) h = mm.close_holes(g) i = mm.areaopen(h, 1000) j1, j2 = iaotsu(i) # j = i > j1 ret, j = cv2.threshold(cv2.GaussianBlur(i, (7, 7), 0), j1, 255, cv2.THRESH_BINARY) k = mm.open(j, mm.seline(20, 90)) l = mm.areaopen(k, 1000) # m = mm.label(l) res = np.vstack( [np.hstack([c, d, e, f, g]), np.hstack([h, i, j, k, l])]) cv2.imshow('Result', res) cv2.waitKey(0) cv2.destroyAllWindows() ################################ # l_ = mm.blob(k,'AREA','IMAGE') # l = l_ == max(ravel(l_)) # m = mm.open(l, mm.sedisk(3)) # VERIFICAR O MELHOR ELEMENTO ESTRUTURANTE AQUI # n = mm.label(m) if outimg: if not os.path.isdir('outimg'): os.mkdir('outimg') def N(x): # y = uint8(ianormalize(x, (0, 255)) + 0.5) y = (ianormalize(x, (0, 255)) + 0.5).astype(np.uint8) return y adwrite('outimg/a.png', N(a)) adwrite('outimg/b.png', N(b_)) adwrite('outimg/c.png', N(c)) adwrite('outimg/d.png', N(d)) adwrite('outimg/e.png', N(e)) adwrite('outimg/f.png', N(f)) adwrite('outimg/g.png', N(g)) adwrite('outimg/h.png', N(h)) adwrite('outimg/i.png', N(i)) adwrite('outimg/j.png', N(j)) adwrite('outimg/k.png', N(k)) adwrite('outimg/l.png', N(l)) adwrite('outimg/m.png', N(m)) # adwrite('outimg/n.png', N(n)) return m else: b = mm.areaopen(a, 500) c = mm.close(b, mm.sebox(3)) d = mm.close_holes(c) e = mm.subm(d, c) f = mm.areaopen(e, 1000) # g = f > 5 ret, g = cv2.threshold(cv2.GaussianBlur(f, (5, 5), 0), 3, 255, cv2.THRESH_BINARY) # ret, g = cv2.threshold( # cv2.GaussianBlur(f, (7, 7), 0), # 5, 255, # cv2.THRESH_BINARY_INV) h = mm.asf(g, 'CO', mm.sedisk(5)) i = mm.close_holes(h) res = np.vstack( [np.hstack([a, b, c, d, e]), np.hstack([f, g, h, i, a])]) cv2.imshow('Result', res) cv2.waitKey(0) cv2.destroyAllWindows() if outimg: if not os.path.isdir('outimg'): os.mkdir('outimg') def N(x): y = (ianormalize(x, (0, 255)) + 0.5).astype(np.uint8) return y adwrite('outimg/a.png', N(a)) adwrite('outimg/b.png', N(b)) adwrite('outimg/c.png', N(c)) adwrite('outimg/d.png', N(d)) adwrite('outimg/e.png', N(e)) adwrite('outimg/f.png', N(f)) adwrite('outimg/g.png', N(g)) adwrite('outimg/h.png', N(h)) adwrite('outimg/i.png', N(i)) return i