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 medial_points(thresh, filepath = '.'): #leggo l'immagine e la trasformo in 0 o 255 (th, im_bw) = cv2.threshold(thresh, 240, 255, cv2.THRESH_BINARY_INV) #plt.imshow(cv2.cvtColor(im_bw,cv2.COLOR_GRAY2RGB)) #plt.show() #points = punti dei muri points = [] for y in xrange(0,im_bw.shape[1]): for x in xrange(im_bw.shape[0]): if im_bw[x, y] == (0): points.append([y,x]) points = np.asarray(points) #distance transform # distanceMap = ndimage.distance_transform_edt(im_bw) # plt.title('8.distance map') # plt.imshow(distanceMap) # plt.show() #disegno distance transforme distanceMap = dsg.disegna_distance_transform(im_bw, filepath = filepath)#plot #medial axis sulla distance transform skel, distance = medial_axis(distanceMap, return_distance=True) #elimino parte delle imprecisioni della skeletonization b3 = m.thin(skel, m.endpoints('homotopic'), 15) #elimino i punti isolati del medial axis, sono rumore for riga in xrange(b3.shape[0]): for col in xrange(b3.shape[1]): if b3[riga][col]==True and isolato(b3,riga,col): b3[riga][col]=False #disegno medial axis # plt.title('9.medial axis') # plt.plot(points[:,0],points[:,1],'.') # plt.imshow(b3,cmap='Greys') # plt.show() #disegno medial axis dsg.disegna_medial_axis(points, b3, filepath = filepath) punti_medial = [] #salvo in una lista i punti che fanno parte del medial axis for riga in xrange(b3.shape[0]): for col in xrange(b3.shape[1]): if (b3[riga][col]==True): punti_medial.append((col,riga)) punti_medial = np.asarray(punti_medial) flip_vertici(punti_medial,b3.shape[0]-1) return punti_medial
def process(self, im): #single pixel restructure element elem = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]]) print "starting img process.. binarizing" b1 = im > 205 #binarize print "removing single pixels" #remove single pixels singpix = mahotas.morph.hitmiss(b1, elem) b1 = (b1 - singpix) > 0 print "closing holes" b1 = m.close_holes(b1) print "thinning" #b2 = m.thin(b1) #thin b2 = self.shitthin(b1) #thin print "pruning" b3 = m.thin(b2, m.endpoints('homotopic'), 8) #remove single pixels singpix = mahotas.morph.hitmiss(b3, elem) b3 = b3 - singpix b3 = b3 > 0 struct = np.ndarray((4, 3, 3), dtype=np.uint8) struct[0, :, :] = [[1, 2, 1], [0, 1, 0], [0, 1, 0]] for i in range(1, 4): print "gen %i structure.." % (i) struct[i, :, :] = np.rot90(struct[0], i) #struct = struct == 1 print "using struct for branch summing:" print struct b4 = np.zeros((301, 398), dtype=bool) for i in range(0, 4): b4 = b4 | mahotas.morph.hitmiss(b3, struct[i]) b4 = b4 > 0 imgout = m.overlay(b1, b2, b4) mahotas.imsave("thresh.png", imgout) return b4
def process(self, im): # single pixel restructure element elem = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]]) print "starting img process.. binarizing" b1 = im > 205 # binarize print "removing single pixels" # remove single pixels singpix = mahotas.morph.hitmiss(b1, elem) b1 = (b1 - singpix) > 0 print "closing holes" b1 = m.close_holes(b1) print "thinning" # b2 = m.thin(b1) #thin b2 = self.shitthin(b1) # thin print "pruning" b3 = m.thin(b2, m.endpoints("homotopic"), 8) # remove single pixels singpix = mahotas.morph.hitmiss(b3, elem) b3 = b3 - singpix b3 = b3 > 0 struct = np.ndarray((4, 3, 3), dtype=np.uint8) struct[0, :, :] = [[1, 2, 1], [0, 1, 0], [0, 1, 0]] for i in range(1, 4): print "gen %i structure.." % (i) struct[i, :, :] = np.rot90(struct[0], i) # struct = struct == 1 print "using struct for branch summing:" print struct b4 = np.zeros((301, 398), dtype=bool) for i in range(0, 4): b4 = b4 | mahotas.morph.hitmiss(b3, struct[i]) b4 = b4 > 0 imgout = m.overlay(b1, b2, b4) mahotas.imsave("thresh.png", imgout) return b4
def critical_points(metricMap): ''' ottengo i critical points dal medial axis ''' if cv2.__version__[0] == '3': flag = cv2.IMREAD_GRAYSCALE elif cv2.__version__[0] == '2': flag = cv2.CV_LOAD_IMAGE_GRAYSCALE else: raise EnvironmentError( 'Opencv Version Error. You should have OpenCv 2.* or 3.*') im_gray = cv2.imread(metricMap, flag) #leggo l'immagine e la trasformo in 0 o 255 (thresh, im_bw) = cv2.threshold(im_gray, 240, 255, cv2.THRESH_BINARY_INV) (th, im_bw) = cv2.threshold(im_bw, 240, 255, cv2.THRESH_BINARY_INV) #points = punti dei muri points = [] for y in xrange(0, im_bw.shape[1]): for x in xrange(im_bw.shape[0]): if im_bw[x, y] == (0): points.append([y, x]) points = np.asarray(points) #distance map distanceMap = get_distance_transforme(im_bw) #medial axis sulla distance transform skel, distance = medial_axis(distanceMap, return_distance=True) #elimino parte delle imprecisioni della skeletonization #b3 = m.thin(skel, m.endpoints('homotopic'), 15) b3 = m.thin(skel, m.endpoints('homotopic'), 500) #--- import copy b4 = copy.copy(b3) #ottengo solo critical points #critical_points = [] for riga in xrange(b4.shape[0]): for col in xrange(b4.shape[1]): if b4[riga][col] == True: #controllo se in un intorno di quel punto c'è una frontiera #creo intorno del pixel start_x = riga - 17 #15 end_x = riga + 17 start_y = col - 17 end_y = col + 17 count = 0 for x in xrange(start_x, end_x): for y in xrange(start_y, end_y): if im_bw[x, y] <= ( 200 ): #se almeno una componente rgb di un pixel nell'introno del pixel cha fa parte del medial axis e' un pixel della frontiera count += 1 if count <= 5: b4[riga][col] = False # else: # #è un critical_points # critical_points.append([riga, col]) critical_points = [] #salvo in una lista i critical points che fanno parte del medial axis for riga in xrange(b4.shape[0]): for col in xrange(b4.shape[1]): if (b4[riga][col] == True): critical_points.append((col, riga)) critical_points = np.asarray(critical_points) flip_vertici(critical_points, b4.shape[0] - 1) #------ return distanceMap, points, b3, b4, critical_points
import pymorph as m import mahotas from numpy import where, reshape image = mahotas.imread('B.png') # Load image b1 = image[:,:,0] < 100 # Make a binary image from the thresholded red channel b2 = m.erode(b1, m.sedisk(4)) # Erode to enhance contrast of the bridge b3 = m.open(b2,m.sedisk(4)) # Remove the bridge b4 = b2-b3 # Bridge plus small noise b5 = m.areaopen(b4,1000) # Remove small areas leaving only a thinned bridge b6 = m.dilate(b3)*b5 # Extend the non-bridge area slightly and get intersection with the bridge. #b6 is image of end of bridge, now find single points b7 = m.thin(b6, m.endpoints('homotopic')) # Narrow regions to single points. labelled = m.label(b7) # Label endpoints. x1, y1 = reshape(where(labelled == 1),(1,2))[0] x2, y2 = reshape(where(labelled == 2),(1,2))[0] outputimage = m.overlay(b1, m.dilate(b7,m.sedisk(5))) mahotas.imsave('output.png', outputimage)
def medial_points(thresh): #leggo l'immagine e la trasformo in 0 o 255 (th, im_bw) = cv2.threshold(thresh, 240, 255, cv2.THRESH_BINARY_INV) #plt.imshow(cv2.cvtColor(im_bw,cv2.COLOR_GRAY2RGB)) #plt.show() #points = punti dei muri points = [] for y in xrange(0, im_bw.shape[1]): for x in xrange(im_bw.shape[0]): if im_bw[x, y] == (0): points.append([y, x]) points = np.asarray(points) #distance transform # distanceMap = ndimage.distance_transform_edt(im_bw) # plt.title('8.distance map') # plt.imshow(distanceMap) # plt.show() #disegno distance transforme #distanceMap = dsg.disegna_distance_transform(im_bw, filepath = filepath)#plot distanceMap = get_distance_transforme(im_bw) #medial axis sulla distance transform skel, distance = medial_axis(distanceMap, return_distance=True) #elimino parte delle imprecisioni della skeletonization #b3 = m.thin(skel, m.endpoints('homotopic'), 15) b3 = m.thin(skel, m.endpoints('homotopic'), 500) ''' #------ import copy b4 = copy.copy(b3) #ottengo solo critical points #critical_points = [] for riga in xrange(b4.shape[0]): for col in xrange(b4.shape[1]): if b4[riga][col]==True: #controllo se in un intorno di quel punto c'è una frontiera #creo intorno del pixel start_x = riga-17 #15 end_x = riga+17 start_y = col-17 end_y = col+17 count = 0 for x in xrange(start_x,end_x): for y in xrange(start_y, end_y): if im_bw[x, y] <= (200): #se almeno una componente rgb di un pixel nell'introno del pixel cha fa parte del medial axis e' un pixel della frontiera count+=1 if count <= 5: b4[riga][col]=False # else: # #è un critical_points # critical_points.append([riga, col]) critical_points = [] #salvo in una lista i critical points che fanno parte del medial axis for riga in xrange(b4.shape[0]): for col in xrange(b4.shape[1]): if (b4[riga][col]==True): critical_points.append((col,riga)) critical_points = np.asarray(critical_points) flip_vertici(critical_points,b4.shape[0]-1) #------ ''' #elimino i punti isolati del medial axis, sono rumore for riga in xrange(b3.shape[0]): for col in xrange(b3.shape[1]): if b3[riga][col] == True and isolato(b3, riga, col): b3[riga][col] = False #disegno medial axis # plt.title('9.medial axis') # plt.plot(points[:,0],points[:,1],'.') # plt.imshow(b3,cmap='Greys') # plt.show() #disegno medial axis #dsg.disegna_medial_axis(points, b3, filepath = filepath)#quiiiiiiiii punti_medial = [] #salvo in una lista i punti che fanno parte del medial axis for riga in xrange(b3.shape[0]): for col in xrange(b3.shape[1]): if (b3[riga][col] == True): punti_medial.append((col, riga)) punti_medial = np.asarray(punti_medial) flip_vertici(punti_medial, b3.shape[0] - 1) return punti_medial, distanceMap, points, b3, distance
def region_prop(fig, subfig): # Inspired by: # http://stackoverflow.com/a/9059648/621449 c = subfig # set up the 'FilledImage' bit of regionprops. FilledImage = np.zeros(fig.shape[0:2]).astype('uint8') # set up the 'ConvexImage' bit of regionprops. ConvexImage = np.zeros(fig.shape[0:2]).astype('uint8') # calculate some things useful later: m = cv2.moments(c) # ** regionprops ** Area = m['m00'] Perimeter = cv2.arcLength(c,True) # bounding box: x,y,width,height BoundingBox = cv2.boundingRect(c) # centroid = m10/m00, m01/m00 (x,y) Centroid = ( m['m10']/m['m00'],m['m01']/m['m00'] ) # EquivDiameter: diameter of circle with same area as region EquivDiameter = np.sqrt(4*Area/np.pi) # Extent: ratio of area of region to area of bounding box Extent = Area/(BoundingBox[2]*BoundingBox[3]) # FilledImage: draw the region on in white cv2.drawContours( FilledImage, [c], 0, color=255, thickness=-1 ) # calculate indices of that region.. regionMask = (FilledImage==255) # FilledArea: number of pixels filled in FilledImage FilledArea = np.sum(regionMask) # PixelIdxList : indices of region. # (np.array of xvals, np.array of yvals) PixelIdxList = regionMask.nonzero() # CONVEX HULL stuff # convex hull vertices ConvexHull = cv2.convexHull(c) ConvexArea = cv2.contourArea(ConvexHull) # Solidity := Area/ConvexArea Solidity = Area/ConvexArea # convexImage -- draw on ConvexImage cv2.drawContours( ConvexImage, [ConvexHull], -1, color=255, thickness=-1 ) # ELLIPSE - determine best-fitting ellipse. centre,axes,angle = cv2.fitEllipse(c) MAJ = np.argmax(axes) # this is MAJor axis, 1 or 0 MIN = 1-MAJ # 0 or 1, minor axis # Note: axes length is 2*radius in that dimension MajorAxisLength = axes[MAJ] MinorAxisLength = axes[MIN] Eccentricity = np.sqrt(1-(axes[MIN]/axes[MAJ])**2) Orientation = angle EllipseCentre = centre # x,y Test = FilledImage.astype('uint8') mf = cv2.moments(Test) CentroidFilled = ( mf['m10']/mf['m00'],mf['m01']/mf['m00'] ) # # ** if an image is supplied with the fig: # # Max/Min Intensity (only meaningful for a one-channel img..) # MaxIntensity = np.max(img[regionMask]) # MinIntensity = np.min(img[regionMask]) # # Mean Intensity # MeanIntensity = np.mean(img[regionMask],axis=0) # # pixel value # PixelValues = img[regionMask] x0, y0, dx, dy = BoundingBox x1, y1 = x0 + dx, y0 + dy Image = fig[y0:y1, x0:x1] FilledImageFit = FilledImage[y0:y1, x0:x1] OImage = fig[y0-1:y1+1, x0-1:x1+1] NumPixels = Image.sum() Fillity = (NumPixels+0.0)/FilledArea crx, cry = (CentroidFilled[0]-x0, CentroidFilled[1]-y0) dxc = crx-(x1-x0)/2.0 dyc = cry-(y1-y0)/2.0 CentLength = math.sqrt(dxc*dxc + dyc*dyc) e = lambda fig: pymorph.erode(fig) d = lambda fig: pymorph.dilate(fig) o = lambda fig: pymorph.open(fig) c = lambda fig: pymorph.close(fig) a = lambda fun, n: reduce(lambda f1, f2: lambda x: f1(f2(x)), [fun]*n, lambda x: x) Thin = pymorph.thin(OImage) if num_holes(Image) >= 2: Inner = removeOuter(Thin) Inner = (a(d,7))(Inner>0) Outer = OImage > Inner ret = dict((k,v) for k, v in locals().iteritems() if k[0].isupper()) return ret