示例#1
0
def scikit_example_plot_label():
    image = data.coins()[50:-50, 50:-50]
    
    # apply threshold
    thresh = threshold_otsu(image)
    bw = closing(image > thresh, square(3))
    
    # remove artifacts connected to image border
    cleared = bw.copy()
    clear_border(cleared)
    
    # label image regions
    label_image = label(cleared)
    borders = np.logical_xor(bw, cleared)
    label_image[borders] = -1
    
    fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
    ax.imshow(label_image, cmap='jet')
    
    for region in regionprops(label_image, ['Area', 'BoundingBox']):
    
        # skip small images
        if region['Area'] < 100:
            continue
    
        # draw rectangle around segmented coins
        minr, minc, maxr, maxc = region['BoundingBox']
        rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
                                  fill=False, edgecolor='red', linewidth=2)
        ax.add_patch(rect)
    
    plt.show()
	def setROILED(self, im):
		im1 = im.copy()

		box = self.pupil_BOX

		x,y,w,h = box + [-20,-30, 40, 60]
		self.led_OFFSET = np.array([x,y])
		im2 = im[y:y+h, x:x+w]

		center_point = [e / 2 for e in im2.shape]

		for ledthreshold in xrange(210, 150, -2):

			ret, bw_im = cv2.threshold(im2, ledthreshold, 255, cv2.THRESH_BINARY)
			cleared = bw_im.copy()
			clear_border(cleared)
			label_img = label(cleared)

			props = regionprops(label_img)

			if len(props) < 2:
				continue
			elif len(props) >= 2:
				dist = [euclidean(center_point, e.centroid) for e in props]
				minDist_idx = [dist.index(e) for e in heapq.nsmallest(2, dist)]
				props[0], props[1] = props[minDist_idx[0]], props[minDist_idx[1]]

			if props[0].area > 27 and props[1].area > 27 and props[0].area < 60 and props[1].area < 60:
				return bw_im, props[0].centroid, props[1].centroid

		return None, None, None
 def applyMorphologicalCleaning(self, image):
 	"""
 	Applies a variety of morphological operations to improve the detection
 	of worms in the image.
 	Takes 0.030 s on MUSSORGSKY for a typical frame region
 	Takes 0.030 s in MATLAB too
 	"""
     # start with worm == 1
     image = image.copy()
     segmentation.clear_border(image)  # remove objects at edge (worm == 1)
     # fix defects in the thresholding by closing with a worm-width disk
     # worm == 1
     wormSE = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,
                                        (self.wormDiskRadius+1,
                                        	self.wormDiskRadius+1))
     imcl = cv2.morphologyEx(np.uint8(image), cv2.MORPH_CLOSE, wormSE)
     imcl = np.equal(imcl, 1)
     # fix defects by filling holes
     imholes = ndimage.binary_fill_holes(imcl)
     imcl = np.logical_or(imholes, imcl)
     # fix barely touching regions
     # majority with worm pixels == 1 (median filter same?)
     imcl = nf.median_filter(imcl, footprint=[[1, 1, 1],
                                              [1, 0, 1],
                                              [1, 1, 1]])
     # diag with worm pixels == 0
     imcl = np.logical_not(bwdiagfill(np.logical_not(imcl)))
     # open with worm pixels == 1
     openSE = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1))
     imcl = cv2.morphologyEx(np.uint8(imcl), cv2.MORPH_OPEN, openSE)
     return np.equal(imcl, 1)
def detect_edges(image_array):
    """ Detect edges in a given image
    Takes a numpy.array representing an image,
    apply filters and edge detection and return a numpy.array

    Parameters
    ----------
    image_array : ndarray (2D)
        Image data to be processed. Detect edges on this 2D array representing the image

    Returns
    -------
    edges : ndarray (2D)
        Edges of an image.
    """
    #Transform image into grayscale
    img = rgb2gray(image_array)
    #Remove some noise from the image
    img = denoise_tv_chambolle(img, weight=0.55)
    #Apply canny
    edges = filter.canny(img, sigma=3.2)
    #Clear the borders
    clear_border(edges, 15)
    #Dilate edges to make them more visible and connected
    edges = binary_dilation(edges, selem=diamond(3))
    return edges
示例#5
0
def roofRegion(edge):
    """Estimate region based on edges of roofRegion
    """
    # apply threshold
    thresh = threshold_otsu(image)
    bw = closing(image > thresh, square(3))

    # remove artifacts connected to image border
    cleared = bw.copy()
    clear_border(cleared)

    # label image regions
    label_image = label(cleared)
    borders = np.logical_xor(bw, cleared)
    label_image[borders] = -1
    image_label_overlay = label2rgb(label_image, image=image)

    fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
    ax.imshow(image_label_overlay)

    for region in regionprops(label_image):

        # skip small images
        if region.area < 100:
            continue

        # draw rectangle around segmented coins
        minr, minc, maxr, maxc = region.bbox
        rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
                                  fill=False, edgecolor='red', linewidth=2)
        ax.add_patch(rect)

    plt.show()
    def del_small(self,img,min_size):
        '''
            args :      -> 画像,1ch
            dst  :      -> 端に繋がってるのと小さいやつ除去した画像
            param:      -> 
        '''

        bounding_box = np.zeros_like(img)

        # 画像の端に繋がってるやつ削除
        cleared = img.copy()
        skseg.clear_border(cleared)

        # ラベリング
        labels, num = sk.label(cleared, return_num = True) # numが一個多い?
        
        # bounding boxの描画
        # for region in sk.regionprops(labels):
            
            # minr, minc, maxr, maxc = region.bbox

            # if region.area < min_size:
                # cleared[minr:maxr,minc:maxc][region.convex_image == True] =0 
                # num = num - 1
                
            # else:    
                # cv2.rectangle(bounding_box,(minc,minr),(maxc,maxr),255)
        bounding_box = 0

        return cleared, num, bounding_box
def test_clear_border_3d():
    image = np.array([
        [[0, 0, 0, 0],
         [0, 0, 0, 0],
         [0, 0, 0, 0],
         [1, 0, 0, 0]],
        [[0, 0, 0, 0],
         [0, 1, 1, 0],
         [0, 0, 1, 0],
         [0, 0, 0, 0]],
        [[0, 0, 0, 0],
         [0, 0, 0, 0],
         [0, 0, 0, 0],
         [0, 0, 0, 0]],
        ])
    # test default case
    result = clear_border(image.copy())
    ref = image.copy()
    ref[0, 3, 0] = 0
    assert_array_equal(result, ref)

    # test buffer
    result = clear_border(image.copy(), 1)
    assert_array_equal(result, np.zeros(result.shape))

    # test background value
    result = clear_border(image.copy(), buffer_size=1, bgval=2)
    assert_array_equal(result, 2 * np.ones_like(image))
def get_cells(image):
    '''
    Get cellls from the polygon.
    '''
    new_image=np.ones([3,image.shape[0],image.shape[1]],dtype=float)
    # apply threshold
    thresh = threshold_otsu(image)
    bw=image

    # remove artifacts connected to image border
    cleared = bw.copy()
    clear_border(cleared)

    # label image regions
    label_image = label(cleared)
    #skimage.measure.label
    #find_contours
    borders = np.logical_xor(bw, cleared)
    label_image[borders] = -1
    image_label_overlay = label2rgb(label_image, image=image)

    #extract the regions and get a polygon per region
    polygons=[]
    for i,region in enumerate(regionprops(label_image)):
        # skip small images
        if region.area < 100:
            continue
        #polygons.append(matplotlib.path.Path(region.coords))
        print (region.coords.shape)
        a=np.zeros(region.coords.shape)
        a[:,0]=region.coords[:,1]
        a[:,1]=region.coords[:,0]
        polygons.append(a)   
    return polygons
示例#9
0
文件: honeycomp.py 项目: rhoef/afw
    def __call__(self, image, window_size=10, threshold=0, fill_holes=True,
                 outline_smoothing=2, remove_borderobjects=True, size_min=1,
                 *args, **kw):

        thresh = threshold_adaptive(image, block_size=window_size,
                                    offset=-1*threshold)

        if outline_smoothing >= 1:
            thresh = outlineSmoothing(thresh, outline_smoothing)

        thresh = remove_small_objects(thresh, size_min)

        seeds = ndi.label(clear_border(~thresh))[0]
        thresh = ndi.binary_fill_holes(thresh)
        smask = seeds.astype(bool)

        # object don't touch border after outline smoothing
        if remove_borderobjects:
            thresh = clear_border(thresh)

        img = np.zeros(thresh.shape)
        img[~smask] = 1
        edt = ndi.morphology.distance_transform_edt(img)
        edt -= ndi.morphology.distance_transform_edt(seeds)

        labels = watershed(edt, seeds)
        labels[smask] = 0
        labels[~thresh] = 0

        return labels
示例#10
0
def segmentToRegions(image, num_of_ones, bw):
    #apply threshold
    struct = buildStruct(30, num_of_ones)
    if num_of_ones == 0:
        img_close = bw
    else:
        img_close = opening(bw, struct)
    # remove artifacts connected to image border
    cleared = img_close.copy()
    clear_border(cleared)
    # label image regions
    label_image = label(cleared)
    borders = np.logical_xor(img_close, cleared)
    label_image[borders] = -1
    #image_label_overlay = label2rgb(label_image, image=image)
    regions = regionprops(label_image)
    """
    fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
    ax.imshow(image_label_overlay)
    for region in regions:
        # skip small images
        if region.area < 10:
            continue
        # draw rectangle around segmented coins
        minr, minc, maxr, maxc = region.bbox

        rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
                                  fill=False, edgecolor='blue', linewidth=2)
        ax.add_patch(rect)
    """
    return regions
示例#11
0
def get_cells(image):
    '''
    Get cellls from the polygon.
    '''
    # apply threshold    
    thresh = threshold_otsu(image)
    binary = image > thresh
    bw=binary
    plt.imshow(bw)

    # Remove connected to image border
    cleared = bw.copy()
    clear_border(cleared)

    # label image regions
    label_image = skimage.measure.label(cleared)
    #find_contours
    borders = np.logical_xor(bw, cleared)
    label_image[borders] = -1
    image_label_overlay = label2rgb(label_image, image=image)

    #extract the regions and get a polygon per region
    polygons=[]
    for i,region in enumerate(regionprops(label_image)):
        # skip small images
        if region.area < 100:
            continue
        a=np.zeros([len(region.coords),2])
        #a=np.zeros(
        plt.imshow(bw)
        for i in range(len(region.coords)):
            a[i,:]=[region.coords[i][0],region.coords[i][1]]
        polygons.append(a)
    return polygons     
示例#12
0
def getRegions():
    """Geocode address and retreive image centered
    around lat/long"""
    address = request.args.get('address')
    results = Geocoder.geocode(address)
    lat, lng = results[0].coordinates
    zip_code = results[0].postal_code

    map_url = 'https://maps.googleapis.com/maps/api/staticmap?center={0},{1}&size=640x640&zoom=19&sensor=false&maptype=roadmap&&style=visibility:simplified|gamma:0.1'
    request_url = map_url.format(lat, lng)
    req = urllib.urlopen(request_url)
    img = io.imread(req.geturl(),flatten=True)
    labels, numobjects = ndimage.label(img)
    image = filter.canny(img, sigma=3)
    thresh = threshold_otsu(image)
    bw = closing(image > thresh, square(3))

    # remove artifacts connected to image border
    cleared = bw.copy()
    clear_border(cleared)

    # label image regions
    label_image = label(cleared)
    borders = np.logical_xor(bw, cleared)
    label_image[borders] = -1
    image_label_overlay = label2rgb(label_image, image=image)

    fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
    ax.imshow(image_label_overlay)
示例#13
0
def getArea(address):
    """Geocode address and retreive image centered
    around lat/long"""
    address = address
    results = Geocoder.geocode(address)
    lat, lng = results[0].coordinates
    zip_code = results[0].postal_code

    map_url = 'https://maps.googleapis.com/maps/api/staticmap?center={0},{1}&size=640x640&zoom=19&sensor=false&maptype=roadmap&&style=visibility:simplified|gamma:0.1'
    request_url = map_url.format(lat, lng)
    req = urllib.urlopen(request_url)
    img = io.imread(req.geturl(),flatten=True)
    labels, numobjects = ndimage.label(img)
    image = filter.canny(img, sigma=3)
    thresh = threshold_otsu(image)
    bw = closing(image > thresh, square(3))

    # remove artifacts connected to image border
    cleared = bw.copy()
    clear_border(cleared)

    # label image regions
    label_image = label(cleared)
    borders = np.logical_xor(bw, cleared)
    label_image[borders] = -1
    image_label_overlay = label2rgb(label_image, image=image)

    fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
    ax.imshow(image_label_overlay)
    dist = []
    rp = regionprops(label_image)
    rp = [x for x in rp if 100 < x.area <= 900]

    for region in rp:

        # skip small images
        #if region.area < 100:
        #    continue
        dist.append(sqrt( ( 320-region.centroid[0] )**2 + ( 320-region.centroid[1] )**2 ))
        # draw rectangle around segmented coins
        #minr, minc, maxr, maxc = region.bbox
        #rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
        #                      fill=False, edgecolor='red', linewidth=2)
        #ax.add_patch(rect)

    roof_index = dist.index(min(dist))
    minr, minc, maxr, maxc = rp[roof_index].bbox
    rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
                          fill=False, edgecolor='red', linewidth=2)
    ax.add_patch(rect)

    img = StringIO()
    fig.savefig(img)
    img.seek(0)
    session['roof_area'] = rp[roof_index].area
    roof_area = (rp[roof_index].area)*12
    return(roof_area)
def adaptivethresh_and_hough(image):
    '''
    image = square NDVI image of field
    
    Applies adaptive thresholding and cleaning on NDVI image to prepare for hough line transformation
    ''' 

    # apply adaptive opencv threshold
    th3 = cv2.adaptiveThreshold(image,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
                cv2.THRESH_BINARY,95,2)

    # Remove noise bij opening
    kernel = np.ones((3,3),np.uint8)
    opening = cv2.morphologyEx(th3, cv2.MORPH_OPEN, kernel)

    # close image using scikit
    #bw = closing(th3 > opening, square(14))

    # remove artifacts connected to image border
    cleared = opening.copy()
    clear_border(cleared)

    # label image regions
    crop_regions = label(cleared)

    # Remove noise by area
    region_size = np.bincount(crop_regions.ravel())
    region_mask = region_size > 200
    region_mask[0] = 0
    regions_cleaned = region_mask[crop_regions]

    # Convert image to CV image
    cv_image = img_as_ubyte(regions_cleaned)

    # Apply hough line transformation
    lines = cv2.HoughLinesP(cv_image,rho=1,theta=np.pi/180,threshold=200,lines=np.array([]),
                        minLineLength=100,maxLineGap=5) # TO DO: MAKE SURE ONLY 180 RANGE IS RETURNED and minlinelength automatic adjust
                        
    if not lines.any():
        print "Error: No Hough lines detected! Try to increase cropping area" # <- line not working, as lines is more than 1!
        sys.exit()
        
    else:
        for line in lines:
            x1,y1,x2,y2 = line[0]
            cv2.line(cv_image,(x1,y1),(x2,y2),(50,255,10),2)
     
    # Extract only the coordinates from NP array
    coordinates = lines[0:,0,]
    np.save('coordinates.npy', coordinates)
    np.savetxt('coordinates.txt', coordinates)
    cv2.imwrite('detected_lines.png', cv_image)
    
    return coordinates
示例#15
0
文件: panel.py 项目: A02l01/Navautron
	def parse_image(self):
		self.m_print("Parsing panel image",0)
		thresh = threshold_otsu(self.i_file)
		bw = closing(self.i_file > thresh, square(3))
		# remove artifacts connected to image border
		cleared = bw.copy()
		clear_border(cleared)
		# label image regions
		label_image = label(cleared)
		borders = np.logical_xor(bw, cleared)
		label_image[borders] = -1
		return label2rgb(label_image, image=self.i_file),label_image
def label_movie(movie, threshold, segmentation_meth, shape, size):
    labeled_stack = np.zeros_like(movie)
    for z, frame in enumerate(movie):
        im_max = frame.max()
        if im_max < threshold:
            labeled_stack[z] = np.zeros(frame.shape, dtype=np.int32)
        else:
            bw = segmentation_meth(frame > threshold, shape(size))
            cleared = bw.copy()
            clear_border(cleared)
            labeled_stack[z] = label(cleared)
    return labeled_stack
示例#17
0
def segmentLettersFromRow(row, image):
    letters_in_row = []
    for region in row:
        print("Row!!!!!!!!!!!!!!!!!!!a")
        minr, minc, maxr, maxc = region.bbox
        new_image = image[minr - 5:maxr + 5, minc - 5:maxc + 5]
        #new_image = image
        #new_image[0:len(image), 0:len(image[0])]
        #new_image[1:minr]
        thresh = threshold_otsu(new_image)
        new_image = image.copy()

        new_image[0:minr, 0:minc] = 0
        new_image[0:minr - 5, minc:maxc] = 0
        new_image[0:minr, maxc:len(image[0])] = 0

        new_image[minr:maxr, 0:minc] = 0
        new_image[minr:maxr, maxc + 5:len(image[0])] = 0

        new_image[maxr:len(image), 0:minc] = 0
        new_image[maxr + 5:len(image), minc: maxc] = 0
        new_image[maxr:len(image), maxc:len(image[0])] = 0

        bw = np.any(new_image > thresh, -1)
        #bw = ndimage.binary_opening(bw, structure= np.zeros((3,3))).astype(bw.dtype)
        # remove artifacts connected to image border
        cleared = bw.copy()
        clear_border(cleared)
        # label image regions
        label_image = label(cleared)
        borders = np.logical_xor(bw, cleared)
        label_image[borders] = -1
        image_label_overlay = label2rgb(label_image, image=new_image)
        #fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
        #ax.imshow(label_image)
        for letter in regionprops(label_image):
            if letter.area < 5:
                continue
            # draw rectangle around segmented coins
            #minr1, minc1, maxr1, maxc1 = letter.bbox
            #roi = image[ minr: maxr, minc:maxc]
            #plt.figure()
            #plt.imshow(roi)
            """
            rect = mpatches.Rectangle((minc1, minr1), maxc1 - minc1, maxr1 - minr1,
                                      fill=False, edgecolor='red', linewidth=2)
            """
            #ax.add_patch(rect)
            letters_in_row.append(letter)
    print "Finise"
    return letters_in_row
示例#18
0
def calLetters(image):
    # apply threshold
    thresh = threshold_otsu(image)
    bw = np.any(image > thresh, -1)
    #bw = ndimage.binary_opening(bw, structure= np.zeros((3,3))).astype(bw.dtype)
    # remove artifacts connected to image border
    cleared = bw.copy()
    clear_border(cleared)
    # label image regions
    label_image = label(cleared)
    borders = np.logical_xor(bw, cleared)
    label_image[borders] = -1
    #image_label_overlay = label2rgb(label_image, image=image)
    letters = regionprops(label_image)
    return letters
示例#19
0
文件: threshold.py 项目: rhoef/afw
    def __call__(
        self,
        image,
        window_size=10,
        threshold=0,
        fill_holes=True,
        remove_borderobjects=True,
        outline_smoothing=0,
        use_watershed=False,
        seeding_size=8,
        *args,
        **kw
    ):
        """Local adaptive threshold segmentation using a gaussian Kernel"""

        thresh = adaptive_threshold(image, window_size, threshold)

        if fill_holes:
            thresh = ndi.morphology.binary_fill_holes(thresh)

        # object don't touch border after outline smoothing
        if remove_borderobjects:
            thresh = clear_border(thresh)

        if outline_smoothing >= 1:
            thresh = outlineSmoothing(thresh, outline_smoothing)

        if use_watershed:
            label_image = watershed(thresh, seeding_size=seeding_size)
        else:
            label_image = ndi.label(thresh)[0]

        return label_image
示例#20
0
def calculate_min_distance(hsu,nhru,cluster_ids,lats,lons,clats,clons):
  radius = 6367.0
  # Minimum distance between HRUs

  # Get lat lon from the borders
  idx = (cluster_ids == hsu)
  idx = clear_border(idx,bgval=False)
  idx = find_boundaries(idx, mode='inner')
  bd_lats = lats[idx].flatten()
  bd_lons = lons[idx].flatten()

  if len(bd_lats) < 1 :
   idx = (cluster_ids == hsu)
   idx = find_boundaries(idx, mode='inner')
   bd_lats = lats[idx].flatten()
   bd_lons = lons[idx].flatten()

  # Get unique lat,lon values and sample 50 points
  points = set(zip(bd_lats,bd_lons))
  nsamp = 1#30
  if len(points) <= nsamp: nsamp = int(len(points)/2.)
  if len(points) <= 5: nsamp = len(points)

  points = random.sample(points, nsamp)
  bd_lats = np.array(list(zip(*points))[0])
  bd_lons = np.array(list(zip(*points))[1])

  distance = np.ones(nhru)*10000000.

  #Calculate the distance of a boundary to a centroid of each hru

  for lat, lon in zip(bd_lats,bd_lons):
    dlat = np.radians(lat-clats)
    dlon = np.radians(lon-clons)
    a = np.sin(dlat/2) * np.sin(dlat/2) + np.cos(np.radians(clats)) \
      * np.cos(np.radians(lat)) * np.sin(dlon/2) * np.sin(dlon/2)
    c = np.zeros((len(a)))
    for count in range(len(a)):
      c[count] = 2 * np.math.atan2(np.sqrt(a[count]), np.sqrt(1-a[count]))
    dist = radius * c
    distance[dist < distance] = dist[dist < distance]
#  for hrs in range(nhru):
#    if hrs == hsu:
#      distance[hrs] = 0.0
#    else:
#      clat = clats[hrs]
#      clon = clons[hrs]
#
#      for lat, lon in zip(bd_lats,bd_lons):
#        dlat = np.radians(lat-clat)
#        dlon = np.radians(lon-clon)
#        a = np.sin(dlat/2) * np.sin(dlat/2) + np.cos(np.radians(clat)) \
#          * np.cos(np.radians(lat)) * np.sin(dlon/2) * np.sin(dlon/2)
#        c = 2 * np.math.atan2(np.sqrt(a), np.sqrt(1-a))
#        dist = radius * c
#        if dist < distance[hrs]: distance[hrs] = dist
#      #print hsu, hrs, dist, distance[hrs] 

  #print hsu, distance
  return distance
示例#21
0
def get_segmented_lungs(im):

    binary = im < -320
    cleared = clear_border(binary) 
    cleared=morph(cleared,5)
    label_image = label(cleared)
  
    areas = [r.area for r in regionprops(label_image)]
    areas.sort()
    if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]:
                for coordinates in region.coords:
                       label_image[coordinates[0], coordinates[1]] = 0
    binary = label_image > 0  
    selem = disk(2)
    binary = binary_erosion(binary, selem)
 
    selem = disk(10)
    binary = binary_closing(binary, selem)
    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)
 
    get_high_vals = binary == 0
    im[get_high_vals] = 0
  
    binary = morphology.dilation(binary,np.ones([5,5]))
    return binary
    def clear_border_skimage(self, buffer_size=3, bgval=1):
        """clear the borders of the image using a belt of pixels definable in buffer_size and 
	asign a pixel value of bgval
	
	Parameters
        ----------
        buffer_size: int
	indicates the belt of pixels around the image border that should be considered to 
	eliminate touching objects (default is 3)
	
	bgvalue: int
	all touching objects are set to this value (default is 1)
	"""

        # perform algorithm
        image_inv = cv.bitwise_not(self.current_image)
        image = clear_border(image_inv, buffer_size=buffer_size, bgval=bgval)

        # update current image
        self.current_image = image

        # append function to logs
        self.logs.add_log('clear border with buffer size {} and bgval {} '
                          '-  skimage'.format(buffer_size, bgval))
        return image
示例#23
0
def remove_border_objects(vol):

    from skimage.segmentation import clear_border

    # remove objects intersecting with image border
    vol = clear_border(vol)
    return vol
示例#24
0
def test_clear_border_non_binary_3d():
    image3d = np.array(
        [[[1, 2, 3, 1, 2],
        [3, 3, 3, 4, 2],
        [3, 4, 3, 4, 2],
        [3, 3, 2, 1, 2]],
        [[1, 2, 3, 1, 2],
        [3, 3, 5, 4, 2],
        [3, 4, 5, 4, 2],
        [3, 3, 2, 1, 2]],
        [[1, 2, 3, 1, 2],
        [3, 3, 3, 4, 2],
        [3, 4, 3, 4, 2],
        [3, 3, 2, 1, 2]],
        ])

    result = clear_border(image3d)
    expected = np.array(
        [[[0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0]],
        [[0, 0, 0, 0, 0],
        [0, 0, 5, 0, 0],
        [0, 0, 5, 0, 0],
        [0, 0, 0, 0, 0]],
        [[0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0]],
        ])

    assert_array_equal(result, expected)
    assert_(not np.all(image3d == result))
示例#25
0
def get_segmented_lungs(im, plot=False):
    # Step 1: Convert into a binary image.
    binary = im < -400
    # Step 2: Remove the blobs connected to the border of the image.
    cleared = clear_border(binary)
    # Step 3: Label the image.
    label_image = label(cleared)
    # Step 4: Keep the labels with 2 largest areas.
    areas = [r.area for r in regionprops(label_image)]
    areas.sort()
    if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]:
                for coordinates in region.coords:
                       label_image[coordinates[0], coordinates[1]] = 0
    binary = label_image > 0
    # Step 5: Erosion operation with a disk of radius 2. This operation is seperate the lung nodules attached to the blood vessels.
    selem = disk(2)
    binary = binary_erosion(binary, selem)
    # Step 6: Closure operation with a disk of radius 10. This operation is    to keep nodules attached to the lung wall.
    selem = disk(10) # CHANGE BACK TO 10
    binary = binary_closing(binary, selem)
    # Step 7: Fill in the small holes inside the binary mask of lungs.
    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)
    # Step 8: Superimpose the binary mask on the input image.
    get_high_vals = binary == 0
    im[get_high_vals] = -2000
    return im, binary
示例#26
0
def test_clear_border_non_binary_inplace_3d():
    image3d = np.array(
        [[[1, 2, 3, 1, 2],
        [3, 3, 3, 4, 2],
        [3, 4, 3, 4, 2],
        [3, 3, 2, 1, 2]],
        [[1, 2, 3, 1, 2],
        [3, 3, 5, 4, 2],
        [3, 4, 5, 4, 2],
        [3, 3, 2, 1, 2]],
        [[1, 2, 3, 1, 2],
        [3, 3, 3, 4, 2],
        [3, 4, 3, 4, 2],
        [3, 3, 2, 1, 2]],
        ])

    result = clear_border(image3d, in_place=True)
    expected = np.array(
        [[[0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0]],
        [[0, 0, 0, 0, 0],
        [0, 0, 5, 0, 0],
        [0, 0, 5, 0, 0],
        [0, 0, 0, 0, 0]],
        [[0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0]],
        ])

    assert_array_equal(result, expected)
    assert_array_equal(image3d, result)
示例#27
0
	def ZOI_selection(self, eclick, erelease):
		x1, y1 = eclick.xdata, eclick.ydata
		x2, y2 = erelease.xdata, erelease.ydata
		xmin=round(min(x1,x2))
		xmax=round(max(x1,x2))
		ymin=round(min(y1,y2))
		ymax=round(max(y1,y2))
		# update dimension of the image:
		self.height = (ymax-ymin)
		self.width = (xmax-xmin)
		self.yoffset = ymin
		self.xoffset = xmin
		#print "1"
		###################################################################### camera INIT with ZOI selection
		if self.videoextenso['enabled']:
			# the following is to initialise the spot detection
			image=self.cam.getImage()
			#plt.imsave("/home/corentin/Bureau/image_originale.tiff",image)
			croped_image = image[self.yoffset:self.height+self.yoffset,self.xoffset:self.xoffset+self.width]
			image = croped_image
			#plt.imsave("/home/corentin/Bureau/image.tiff",image)
			image=rank.median(image,square(15)) # median filter to smooth the image and avoid little reflection that may appear as spots.
			self.thresh = threshold_otsu(image) # calculate most effective threshold
			bw= image>self.thresh 
			#print "1"
			#applying threshold
			if not (self.videoextenso['white_spot']):
				bw=(1-bw).astype(np.uint8)
			#still smoothing
			bw = dilation(bw,square(3))
			bw = erosion(bw,square(3))
			#plt.imsave("/home/corentin/Bureau/bw.tiff",bw)
			# Remove artifacts connected to image border
			cleared = bw.copy()
			clear_border(cleared)
			# Label image regions
			label_image = label(cleared)
			borders = np.logical_xor(bw, cleared)
			label_image[borders] = -1
			#plt.imsave("/home/corentin/Bureau/label_image.tiff",label_image)
			# Create the empty vectors for corners of each ZOI
			regions=regionprops(label_image)
			print [region.area for region in regions]
			#mean_area=np.mean[region.area for region in regions]
			regions=[region for region in regions if region.area>200]
def label_image_regions(image):
    #test--
    #new_image=np.zeros([3,image.shape[0],image.shape[1]],dtype=float)
    new_image=np.ones([3,image.shape[0],image.shape[1]],dtype=float)
    # apply threshold
    thresh = threshold_otsu(image)
    #close small holes with binary closing (skip)
    #bw = closing(image > thresh, square(3))
    bw=image

    # remove artifacts connected to image border
    cleared = bw.copy()
    clear_border(cleared)

    # label image regions
    label_image = label(cleared)
    borders = np.logical_xor(bw, cleared)
    label_image[borders] = -1
    image_label_overlay = label2rgb(label_image, image=image)

    fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6)) ##
    ax.imshow(image_label_overlay) ##
    
    rand_colors = get_random_colors(len(regionprops(label_image)))
    for i,region in enumerate(regionprops(label_image)):
        #pca_analysis(region)
        rand_color=rand_colors[i]
        # skip small images
        if region.area < 100:
            continue
        for coord in region.coords:
            new_image[:,coord[0],coord[1]]=rand_color

        # draw rectangle around segmented coins
        minr, minc, maxr, maxc = region.bbox
        rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
                              fill=False, edgecolor='red', linewidth=2)
        ax.add_patch(rect) ##
        ax.scatter(region.coords[:,1],region.coords[:,0]) ##
    plt.show()
    sys.exit()
    fig, ax = plt.subplots()
    rolled_image = np.rollaxis(new_image, 0, 3) 
    im = ax.imshow(rolled_image)
    plt.show()
示例#29
0
def get_cells(image):
    '''
    Get cellls from the polygon.
    '''
    new_image=np.ones([3,image.shape[0],image.shape[1]],dtype=float)
    # apply threshold
    thresh = threshold_otsu(image)
    binary = image > thresh
    bw=image


    # Remove connected to image border
    cleared = bw.copy()
    clear_border(cleared)


    #cleared = bw
    
    # label image regions
    label_image = label(cleared)
    #skimage.measure.label
    #find_contours
    borders = np.logical_xor(bw, cleared)
    label_image[borders] = -1
    image_label_overlay = label2rgb(label_image, image=image)

    # fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(5, 2))
    # print "====="
    # ax.imshow(label_image, cmap=plt.cm.gray)
    # plt.show()


    #extract the regions and get a polygon per region
    polygons=[]
    for i,region in enumerate(regionprops(label_image)):
        # skip small images
        if region.area < 100:
            continue
        #polygons.append(matplotlib.path.Path(region.coords))
        a=np.zeros(region.coords.shape)
        a[:,0]=region.coords[:,1]
        a[:,1]=region.coords[:,0]
        polygons.append(a)   
    return polygons
示例#30
0
def show(image, bw):
	
	# apply threshold
	# thresh = threshold_otsu(image)
	
	# remove artifacts connected to image border
	cleared = bw.copy()
	clear_border(cleared)

	# label image regions
	label_image = label(cleared)
	borders = np.logical_xor(bw, cleared)
	label_image[borders] = -1
	image_label_overlay = label2rgb(label_image, image=image)

	#fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
	io.imshow(image_label_overlay)
	io.show()
	return image_label_overlay
======================

Visualize segmentation contours on original grayscale image.
"""

from skimage import data, segmentation
# scikit-image has changed its API
try:
    from skimage import filters
except ImportError:
    from skimage import filter as filters
import matplotlib.pyplot as plt
import numpy as np

coins = data.coins()
mask = coins > filters.threshold_otsu(coins)
clean_border = segmentation.clear_border(mask).astype(np.int)

coins_edges = segmentation.mark_boundaries(coins, clean_border)

plt.figure(figsize=(8, 3.5))
plt.subplot(121)
plt.imshow(clean_border, cmap='gray')
plt.axis('off')
plt.subplot(122)
plt.imshow(coins_edges)
plt.axis('off')

plt.tight_layout()
plt.show()
import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from skimage import data, filters, segmentation, measure, morphology, color

# 加载并裁剪硬币图片
image = data.coins()[50:-50, 50:-50]

thresh = filters.threshold_otsu(image)  # 阈值分割
bw = morphology.closing(image > thresh, morphology.square(3))  # 闭运算

cleared = bw.copy()  # 复制
segmentation.clear_border(cleared)  # 清除与边界相连的目标物

label_image = measure.label(cleared)  # 连通区域标记
borders = np.logical_xor(bw, cleared)  # 异或
label_image[borders] = -1
image_label_overlay = color.label2rgb(label_image, image=image)  # 不同标记用不同颜色显示

fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(8, 6))
ax0.imshow(cleared, plt.cm.gray)
ax1.imshow(image_label_overlay)

for region in measure.regionprops(label_image):  # 循环得到每一个连通区域属性集

    # 忽略小区域
    if region.area < 100:
        continue

    # 绘制外包矩形
def fff(test_image):
    import numpy as np
    from skimage.io import imread
    from skimage.filters import threshold_otsu, laplace
    import matplotlib.pyplot as plt
    from skimage.filters import threshold_otsu
    from skimage.segmentation import clear_border
    from skimage.measure import label
    from skimage.measure import regionprops
    from skimage.color import label2rgb
    from skimage.color import rgb2gray
    from skimage import feature
    import copy
    from skimage import img_as_ubyte
    import cv
    import cv2
    from skimage.segmentation import clear_border
    from skimage.restoration import denoise_tv_chambolle
    x = imread(test_image)
    x = cv2.fastNlMeansDenoisingColored(x, None, 10, 10, 7, 21)
    x = denoise_tv_chambolle(x, weight=0.1, multichannel=True)
    z = copy.deepcopy(x)
    yy = copy.deepcopy(x)
    find = []
    f3d = []
    yy = rgb2gray(yy)
    imag = rgb2gray(x)
    global_thresh = threshold_otsu(imag)
    binary_global = imag > global_thresh
    print(binary_global)
    x = ((feature.canny(yy, sigma=2)))
    plt.imshow(x)
    plt.show()
    y = x.copy()
    clear_border(x)
    label_image = label(x)
    borders = np.logical_xor(x, y)
    label_image[borders] = -1
    image_label_overlay = label2rgb(label_image, image=imag)
    for region in regionprops(label_image):

        if region.area < 10:
            continue
        minr, minc, maxr, maxc = region.bbox
        if 1.5 * (maxc - minc) > (maxr - minr) or 6 * (maxc - minc) < (maxr -
                                                                       minr):
            continue
        try:
            find.append(copy.deepcopy(binary_global[(minr):maxr, minc:maxc]))
            f3d.append(copy.deepcopy(z[(minr):maxr, minc:maxc, :]))
            print(f3d[-1].shape)
        except Exception:
            pass
    width = 32
    height = 32
    ddd = []
    eee = []
    img_stack_sm = np.zeros((width, height, 3))
    print(len(find))
    for idx in range(len(find)):
        img = find[idx]
        img_sm = cv2.resize(img_as_ubyte(img), (width, height),
                            interpolation=cv2.INTER_CUBIC)
        img_stack_sm[:, :, 0] = copy.deepcopy(
            cv2.resize(f3d[idx][:, :, 0], (width, height),
                       interpolation=cv2.INTER_CUBIC))
        img_stack_sm[:, :, 1] = copy.deepcopy(
            cv2.resize(f3d[idx][:, :, 1], (width, height),
                       interpolation=cv2.INTER_CUBIC))
        img_stack_sm[:, :, 2] = copy.deepcopy(
            cv2.resize(f3d[idx][:, :, 2], (width, height),
                       interpolation=cv2.INTER_CUBIC))
        img_sm = denoise_tv_chambolle(img_sm, weight=0.1, multichannel=True)
        ddd.append(img_sm)
        eee.append(copy.deepcopy(img_stack_sm))
        #eee.append(img_m)
        #plt.imshow(ddd[-1])
        plt.imshow(eee[-1])
        plt.show()
    return eee, ddd


#fff('../xxx/20.jpg')
示例#34
0
    def cell_processing(self, individual_cell_bef, individual_cell_aft):# for each single cell
        self.regionimage_before_individualcell = individual_cell_bef
        self.regionimage_after_individualcell = individual_cell_aft
        self.cell_openingfactor = 1
        self.cell_closingfactor = 5
        
        # Get binary cell image baseed on expanded current region image
        thresh_regionbef = threshold_otsu(self.regionimage_before_individualcell)
        self.expanded_binary_region_bef = np.where(self.regionimage_before_individualcell >= thresh_regionbef, 1, 0)
        
        binarymask_bef = opening(self.expanded_binary_region_bef, square(self.cell_openingfactor))
        self.expanded_binary_region_bef = closing(binarymask_bef, square(self.cell_closingfactor))

        thresh_regionaft = threshold_otsu(self.regionimage_after_individualcell)
        self.expanded_binary_region_aft = np.where(self.regionimage_after_individualcell >= thresh_regionaft, 1, 0)
        
        binarymask_aft = opening(self.expanded_binary_region_aft, square(self.cell_openingfactor))
        self.expanded_binary_region_aft = closing(binarymask_aft, square(self.cell_closingfactor))
        
        plt.figure()
        plt.imshow(self.expanded_binary_region_bef, cmap = plt.cm.gray)       
        plt.show()        
        
        seed = np.copy(self.expanded_binary_region_bef)
        seed[1:-1, 1:-1] = self.expanded_binary_region_bef.max()
        mask = self.expanded_binary_region_bef

        filled = reconstruction(seed, mask, method='erosion')
        plt.figure()
        plt.imshow(filled, cmap = plt.cm.gray)       
        plt.show()   
        
        s=imageanalysistoolbox()
        contour_mask_bef = s.contour(self.expanded_binary_region_bef, self.regionimage_before_individualcell.copy(), self.contour_thres) # after here self.intensityimage_intensity is changed from contour labeled with number 5 to binary image
        contour_mask_of_intensity_bef = s.inwarddilationmask(contour_mask_bef ,self.expanded_binary_region_bef, self.contour_dilationparameter)   

        contourimage_intensity_aft = s.contour(self.expanded_binary_region_aft, self.regionimage_after_individualcell.copy(), self.contour_thres) # after here self.intensityimage_intensity is changed with contour labeled with number 5
        contour_mask_of_intensity_aft = s.inwarddilationmask(contourimage_intensity_aft ,self.expanded_binary_region_aft, self.contour_dilationparameter) 

        plt.figure()
        #plt.imshow(contour_mask_of_intensity_bef, cmap = plt.cm.gray)
        plt.imshow(self.regionimage_before_individualcell, cmap = plt.cm.gray)       
        plt.show()
        
        cleared = self.expanded_binary_region_bef.copy() # Necessary for region iteration
        clear_border(cleared)
        label_image = label(cleared)

        for sub_region in regionprops(label_image, self.regionimage_before_individualcell):
            
            if sub_region.area < 3:#int(np.size(self.regionimage_before_individualcell)*0.1):
                for i in range(len(sub_region.coords)):
                    #print(sub_region.coords[i])
                    contour_mask_of_intensity_bef[sub_region.coords[i][0], sub_region.coords[i][1]] = 0
                    
        cleared_1 = self.expanded_binary_region_aft.copy()
        clear_border(cleared_1)
        label_image_aft = label(cleared_1)
        
        for sub_region_aft in regionprops(label_image_aft, self.regionimage_after_individualcell):
      
            if sub_region_aft.area < 3:#int(np.size(self.regionimage_after_individualcell)*0.1):
                for j in range(len(sub_region_aft.coords)):
                    #print(sub_region_aft.coords[j])
                    contour_mask_of_intensity_aft[sub_region_aft.coords[j][0], sub_region_aft.coords[j][1]] = 0
            
        plt.figure()
        plt.imshow(contour_mask_of_intensity_bef, cmap = plt.cm.gray)
        plt.show()
示例#35
0
cells=img[:,:,0]  #Blue channel. Image equivalent to grey image.


pixels_to_um = 0.454 # 1 pixel = 454 nm (got this from the metadata of original image)

#Threshold image to binary using OTSU. ALl thresholded pixels will be set to 255
ret1, thresh = cv2.threshold(cells, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)


# Morphological operations to remove small noise - opening
#To remove holes we can use closing
kernel = np.ones((3,3),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)

from skimage.segmentation import clear_border
opening = clear_border(opening) #Remove edge touching grains
plt.imshow(opening, cmap='gray') #This is our image to be segmented further using watershed

#Check the total regions found before and after applying this. 

#STEP 1: Sude background 
#Now we know that the regions at the center of cells is for sure cells
#The region far away is background.
#We need to extract sure regions. For that erode a few times. 
#But we have cells touching, so erode alone will not work. 
#To separate touching objects, the best approach would be distance transform and then thresholding.

# let us start by identifying sure background area
# dilating pixes a few times increases cell boundary to background. 
# This way whatever is remaining for sure will be background. 
#The area in between sure background and foreground is our ambiguous area. 
示例#36
0
        img_oss = np.uint8(img_oss)
        img_oss_ant = np.where(img_oss < 1, 1, 0)
        img_oss = np.uint8(img_oss)
        img_oss_ant = np.uint8(img_oss_ant)
        img_oss_ant = np.where(img_oss_ant < 1, 1, 0)
        img_oss_ant = np.uint8(img_oss_ant)

        kernel1 = np.asarray([[1, 1, 1], [1, 1, 1], [1, 1, 1]], np.uint8)
        kernel2 = np.asarray([[0, 1, 1, 1, 1, 1, 0], [1, 1, 1, 1, 1, 1, 1],
                              [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1],
                              [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1],
                              [0, 1, 1, 1, 1, 1, 0]], np.uint8)

        img_oss_erode = cv2.erode(img_oss_ant, kernel1, iterations=2)

        img_oss = clear_border(img_oss_erode)

        M = cv2.moments(img_oss)

        cY = int(M["m10"] / M["m00"])
        cX = int(M["m01"] / M["m00"])
        img_oss_center = (cX, cY)
        img_oss[cX, cY] = 0

        img_si = img_res * img_oss
        img_si_ant = np.copy(img_si)
        img_si_ant_show = np.copy(img_si)

        img_si = img_si * img_oss_erode

        img_si_ant = np.uint8(img_si_ant)
示例#37
0
def extract_titlebar(image,
                     min_brightness=0.3,
                     ker_size=2,
                     seed_thresh=20,
                     min_seed_size=400,
                     precrop=None,
                     verbose=False):
    '''Extract the title bar from the image of a scanned (front, top face)
    card.'''
    if type(image) is str:
        img = imread(image, as_gray=True)
    else:
        img = image.copy()
    # Precrop
    if precrop is not None:
        xmin, ymin, xmax, ymax = precrop
        img = img[xmin:xmax, ymin:ymax]
    else:
        xmin, ymin = 0, 0
    # Basic equalization
    img -= img.min()
    img /= img.max()
    mean = img.mean()
    if mean < 0.66 * min_brightness:  # Dim card
        img = (min_brightness / mean * img).clip(0, 1)
    # Prepare watershed procedure
    ker = disk(ker_size)
    img = rank.median(img_as_ubyte(img), ker)  # despeckle
    grad = rank.gradient(img, ker)  # find edges
    seeds = grad < seed_thresh  # id low-gradient fields
    seeds = remove_small_objects(seeds, min_seed_size)  # seed larger fields
    seeds = ndimage.label(seeds)[0]  # mark pixels with labels
    labels = watershed(grad, seeds)  # grow labels from seeds
    # Winnow watershed regions into title candidates
    labels = clear_border(labels)  # toss out labels that hit image edge
    regions = [r for r in regionprops(labels) \
               if _maybe_title(r, xoff=xmin, yoff=ymin)]
    regions, labels = _merge_regions(regions, labels)
    regions = [r for r in regions if _maybe_title(r, xoff=xmin, yoff=ymin)]
    regions = _select_best_region(regions, verbose=verbose)

    assert len(regions) > 0  # We failed to find the title bar

    # With primary candidate selected, expand region horizontally
    # using other identified regions to get a best estimate of
    # horizontal extent
    region = regions[0]
    x1, y1, x2, y2 = region.bbox
    # Identify horizontally adjacent regions
    adjacents = set(labels[x1:x2, y1 - 1:y2 + 1].flatten())
    adjacents.remove(region.label)  # no self-ids
    try:
        adjacents.remove(0)  # don't expand into unidentified/bg regions
    except (KeyError):
        pass
    # Annex horizontally adjacent regions
    for lbl in adjacents:
        labels[x1:x2][labels[x1:x2] == lbl] = region.label
    # Reconstitute our expanded region
    region = [r for r in regionprops(labels) if r.label == region.label][0]
    x1, y1, x2, y2 = region.bbox
    bbox = (x1 + xmin, y1 + ymin, x2 + xmin, y2 + ymin)
    x1, y1 = region.centroid
    centroid = (x1 + xmin, y1 + ymin)
    ang = region.orientation
    title_bar = _crop_titlebar(image, bbox, ang, centroid, verbose=verbose)
    return title_bar
示例#38
0
def main():
    parser = argparse.ArgumentParser(
        description=
        'Image-file processing to identify total number of droplets',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('input_image', type=str, help='input image file')
    parser.add_argument('template_image', type=str, help='template image file')
    parser.add_argument(
        '--outfile',
        type=str,
        help='output image name.  Will default to input_image_processed.png')
    parser.add_argument(
        '--cutoff_area',
        type=int,
        help=
        'rectangle size. only detected rectangles above this size will be displayed'
    )
    parser.add_argument(
        '--include',
        action='store_true',
        dest="include_edge",
        help=
        'Include edge or boundary or border droplets; incomplete droplets found on the edge of the picture will be included too.'
    )
    parser.add_argument(
        "--exclude",
        action="store_false",
        dest="include_edge",
        help=
        'Exclude edge or boundary or border droplets; incomplete droplets found on the edge of the picture will be excluded.'
    )
    parser.add_argument(
        '--threshold',
        type=float,
        default=0.6,
        help=
        'thresholding parameter, tweak from 0 to 1 and visually examine results, depends on the image, default is 0.6'
    )

    args = parser.parse_args()

    if args.outfile == None:
        args.outfile = ''.join(
            [
                path.splitext(args.input_image)[0], "_border_",
                str(args.include_edge), '_processed'
            ]
        )  ## leaving out the file extension; adding it later just before writing out the image file

    filename = args.input_image
    rectsize = args.cutoff_area

    print "...."
    print "image file being processed..."
    print "..."

    from skimage import img_as_float
    image = io.imread(
        filename, flatten=True)  # conver 3d to 2d image by using flatten=True
    image = img_as_float(image)
    #io.imshow(image)   ## check the image
    #io.show()   ## check the image

    from skimage.color import rgb2gray
    img_gray = rgb2gray(image)
    #io.imshow(img_gray)   ## check the image
    #io.show()   ## check the image

    image = gaussian_filter(image, 1)
    seed = np.copy(image)
    seed[1:-1, 1:-1] = image.min()
    mask = image

    dilated = reconstruction(seed, mask, method='dilation')
    """    
    fig, (ax0, ax1, ax2) = plt.subplots(nrows=1,
                                        ncols=3,
                                        figsize=(8, 2.5),
                                        sharex=True,
                                        sharey=True)
    
    ax0.imshow(image, cmap='gray')
    ax0.set_title('original image')
    ax0.axis('off')
    ax0.set_adjustable('box-forced')
    
    ax1.imshow(dilated, vmin=image.min(), vmax=image.max(), cmap='gray')
    ax1.set_title('dilated')
    ax1.axis('off')
    ax1.set_adjustable('box-forced')
    
    ax2.imshow(image - dilated, cmap='gray')
    ax2.set_title('image - dilated')
    ax2.axis('off')
    ax2.set_adjustable('box-forced')
    
    fig.tight_layout()
    """

    print "...."
    print "background correction..."
    print "..."

    h = 0.4
    seed = image - h
    dilated = reconstruction(seed, mask, method='dilation')
    hdome = image - dilated
    #io.imshow(hdome)   ## check the image
    #io.show()   ## check the image
    """
    fig, (ax0, ax1, ax2) = plt.subplots(nrows=1, ncols=3, figsize=(8, 2.5))
    yslice = 197
    
    ax0.plot(mask[yslice], '0.5', label='mask')
    ax0.plot(seed[yslice], 'k', label='seed')
    ax0.plot(dilated[yslice], 'r', label='dilated')
    ax0.set_ylim(-0.2, 2)
    ax0.set_title('image slice')
    ax0.set_xticks([])
    ax0.legend()
    
    ax1.imshow(dilated, vmin=image.min(), vmax=image.max(), cmap='gray')
    ax1.axhline(yslice, color='r', alpha=0.4)
    ax1.set_title('dilated')
    ax1.axis('off')
    
    ax2.imshow(hdome, cmap='gray')
    ax2.axhline(yslice, color='r', alpha=0.4)
    ax2.set_title('image - dilated')
    ax2.axis('off')
    
    fig.tight_layout()
    plt.show()
    """

    print "...."
    print "edge detection..."
    print "..."

    im = hdome
    edges1 = feature.canny(image, sigma=3)
    edges2 = feature.canny(im, sigma=3)
    #io.imshow(edges1)   ## check the image
    #io.show()   ## check the image
    #io.imshow(edges2)   ## check the image
    #io.show()   ## check the image
    """
    # display results
    fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, figsize=(8, 3),
                                        sharex=True, sharey=True)
    ax1.imshow(im, cmap=plt.cm.gray)
    ax1.axis('off')
    ax1.set_title('Original image', fontsize=10)
    
    ax2.imshow(edges1, cmap=plt.cm.gray)
    ax2.axis('off')
    ax2.set_title('Canny filter on original image, $\sigma=3$', fontsize=10)
    
    ax3.imshow(edges2, cmap=plt.cm.gray)
    ax3.axis('off')
    ax3.set_title('Canny filter on background subtracted image, $\sigma=3$', fontsize=10)
    
    fig.tight_layout()
    plt.show()
    """

    #
    ### check how good are the original and processed images by selecting corresponding image here
    #
    image = image
    #image=edges1
    #image=edges2
    #image=hdome

    ## apply threshold
    thresh = threshold_otsu(image)
    bw = closing(image > thresh, square(2))
    #io.imshow(bw)   ## check the image
    #io.show()   ## check the image

    print "... are we including incomplete droplets at the edge of image?..."
    print ".............................................................", args.include_edge
    if args.include_edge is False:
        ## remove artifacts connected to image border
        cleared = clear_border(
            bw
        )  ## use this option to avoid the incomplete droplets at boundary/edge of picture frame
    else:
        cleared = bw  ## use this to use all droplets in the image; even incomplete ones at the boundary/edge of pciture frame

    #io.imshow(cleared)   ## check the image
    #io.show()   ## check the image

    # label image regions
    label_image = label(cleared)
    image_label_overlay = label2rgb(label_image, image=image)
    #io.imshow(image_label_overlay)   ## check the image
    #io.show()   ## check the image

    fig, ax = plt.subplots(figsize=(10, 6))
    #ax.imshow(label_image)
    ax.imshow(image_label_overlay)

    targetimagefile = args.input_image
    templateimagefile = args.template_image
    thresholdval = args.threshold

    pngoutfiles1 = []
    pngoutfiles2 = []
    pngoutfiles3 = []
    dropletID = []
    totalbeadsdetected = []
    rectareas = []
    droplet_count = 0
    outfile = 0
    for region in regionprops(label_image):
        # take regions with large enough areas; should correspond to droplets
        if region.area >= rectsize:
            # draw rectangle around segmented droplets
            droplet_count = droplet_count + 1
            minr, minc, maxr, maxc = region.bbox
            rect = mpatches.Rectangle((minc, minr),
                                      maxc - minc,
                                      maxr - minr,
                                      fill=False,
                                      edgecolor='yellow',
                                      linewidth=2)
            #print region.bbox
            """
            try:
                pad=100
                crop_image = image[minr-pad:maxr+pad, minc-pad:maxc+pad]  ## offset the bounding box in all directions; seems better this way based on visual examination
                padded="Yes"
            except ValueError:  #raised if this subtraction takes it out of bounds
                padded="No"
                crop_image = image[minr:maxr, minc:maxc]
            """

            #io.imshow(crop_image)   ## check the image
            #io.show()   ## check the image
            outfile = outfile + 1
            ## improve this and instead of passing file names of whole images to the findtemplate function
            ## pass the cropped image that already exists here
            ## for now, not changing too drastically on something that works
            ## slow tweaks ensuring what works functionally well doesnt break down
            pngfile1, pngfile2, pngfile3, beads = findtemplate(
                templateimagefile, targetimagefile, region.bbox, outfile,
                thresholdval)
            dropletID.append(droplet_count)
            totalbeadsdetected.append(beads)
            rectareas.append(
                region.area)  #area of rectangle that delineates the droplet
            pngoutfiles1.append(pngfile1)  #cropped-droplet image
            pngoutfiles2.append(pngfile2)  #beads-detected image
            pngoutfiles3.append(pngfile3)  #clusters-detected image
            ax.add_patch(rect)

    ax.set_axis_off()
    #plt.tight_layout()
    outfile = args.outfile + "_totaldroplets-" + str(droplet_count) + ".png"
    plt.savefig(outfile)
    #plt.show()      ## activate this if you want to examine how the processed images are turning out and stop/start with different input parameters; key one being --cutoff_area
    plt.close()
    print "...saved image file that delineates droplets with yellow-colored rectangles...."
    print outfile
    print "........................"

    totaldroplets = droplet_count
    print "...total droplets identified in the image:"
    print totaldroplets
    print "..."

    totalbeads = sum(totalbeadsdetected)
    print "...total beads identified in the image:"
    print totalbeads
    print "..."

    # for detailed checking of the results by eye-balling:
    #item_list=[('dropletID', dropletID), ('croppedArea',rectareas), ('dropletImage',pngoutfiles1), ('beadsdetectedImage',pngoutfiles2), ('clustersImage',pngoutfiles3), ('totalbeads', totalbeadsdetected)]
    #
    item_list = [('dropletID', dropletID),
                 ('beadsdetectedImage', pngoutfiles2),
                 ('totalbeads', totalbeadsdetected)]
    results = pd.DataFrame.from_items(item_list)
    outfile2 = ''.join([
        path.splitext(args.input_image)[0], '_totaldroplets-',
        str(totaldroplets), '_totalbeads-',
        str(totalbeads), '.csv'
    ])
    print "...writing out results file..."
    results.to_csv(outfile2, index=False)
    print "...results file written out as:", outfile2
    print "........................"

    ## quantify beads to plot distribution
    b = []
    for i in totalbeadsdetected:
        if i not in b:
            b.append(i)
    c = sorted(b)
    howmany = []
    for i in c:
        howmany.append(totalbeadsdetected.count(i))

    outfile3a = ''.join([
        path.splitext(args.input_image)[0], '_distribution_of_totaldroplets-',
        str(totaldroplets), '_totalbeads-',
        str(totalbeads), '.png'
    ])
    # plot the distribution of beads across droplets
    plt.hist(totalbeadsdetected)
    plt.plot(c, howmany, linewidth=4.0)
    plt.xlabel('Number of beads within a droplet')
    plt.ylabel('Total droplets with so many beads within...')
    plt.title('Distribution of beads within droplets')
    #plt.savefig(outfile3a)
    #plt.show()
    plt.close()
    print "....saved distribution histogram of number of beads across droplets..."
    print outfile3a
    print "........................"

    outfile3b = ''.join([
        path.splitext(args.input_image)[0],
        '_distribution_of_rectangleareas-total-',
        str(totaldroplets), '.png'
    ])
    # plot the distribution of areas that passed the --cutoff_area; should correspond to droplet identification
    plt.hist(rectareas)
    plt.xlabel('Rectangle area that passed the --cutoff_area of %d' % rectsize)
    plt.ylabel('Total')
    plt.title('Distribution of rectangle areas above the given --cutoff_area')
    #plt.savefig(outfile3b)
    #plt.show()
    plt.close()
    print "....saved distribution histogram of rectangle-areas that delineate the droplets..."
    print outfile3b
    print "........................"

    #item_list=[('beads', c), ('counts', howmany)]
    #results = pd.DataFrame.from_items(item_list)
    #print results

    res = dict(zip(c, howmany))
    temp1 = []
    temp2 = []
    #expanded
    for i in range(25):
        temp1.append(i)
        val = res.get(i)
        if val == None:
            temp2.append("0")
        else:
            temp2.append(val)

    header = path.splitext(args.input_image)[0]
    #item_list=[('beads', temp1), (header, temp2)]
    item_list = [(header, temp2)]
    results = pd.DataFrame.from_items(item_list)
    print results

    outfile4 = ''.join([
        path.splitext(args.input_image)[0], '_totaldroplets-',
        str(totaldroplets), '_totalbeads-',
        str(totalbeads), '_summary.csv'
    ])
    print "...writing out results file..."
    results.to_csv(outfile4, index=False)
    print "...results file written out as:", outfile4
示例#39
0
def extract_features(patches, gen_heatmaps=1):
    # each patch has an associated heatmap

    heatmaps = []

    # this gets the respective heatmaps (we first get a list of all the patches, and then get the heatmaps corresponding to them)
    os.chdir(
        '/data/dywang/Database/Proliferation/libs/stage03_deepFeatMaps/run')
    for patch in patches:
        patch_name = patch.split('/')[-1]

        part1 = patch_name.split('(')[0][:-1]
        num1 = patch_name.split('(')[1].split(',')[0].zfill(10)
        num2 = patch_name.split('(')[1].split(',')[1].split(')')[0].zfill(10)

        patch_name = part1 + '_level0_x' + num1 + '_y' + num2 + '.png'

        # where are the heatmaps stored?
        #prefix = '/data/dywang/Database/Proliferation/libs/stage03_deepFeatMaps/results/mitosis-full_07-07-16/'
        prefix = '/data/dywang/Database/Proliferation/evaluation/mitko-fcn-heatmaps-norm/'

        full_name = prefix + patch_name

        # only look at the patches that have a defined heatmap
        if os.path.exists(full_name):
            heatmaps.append(full_name)
        '''
        elif gen_heatmaps:
            print full_name
            # generate the respective heatmap
            list_file = 'tmp.lst'
            f = open(list_file, 'w')
            f.write('../../../libs/stage03_deepFeatMaps/results/patches_06-29-16/' + patch_name)
            f.close()
            
            subprocess.call("sh /data/dywang/Database/Proliferation/libs/stage03_deepFeatMaps/run/mitosis-subprocess.sh", shell=True)

            heatmaps.append(full_name)
        '''

    vector = []
    for threshold_decimal in [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]:
        ### FOR FULLY CONV HEATMAPS, DON'T SCALE THRESHOLD
        MANUAL_THRESHOLD = threshold_decimal  #int(255 * threshold_decimal)

        for heatmap in heatmaps[0:15]:  # use 15
            individual_vector = []

            ### FOR FULLY CONV HEATMAPS, CONVERT TO GRAYSCALE
            im = color.rgb2gray(imread(heatmap))

            #thresh = threshold_otsu(im)
            thresh = MANUAL_THRESHOLD

            ### FOR FULLY CONV HEATMAPS, IM < THRESH (INVERTED)
            # output heatmaps are inverted, so we need less than thresh
            bw = closing(im < thresh, square(3))

            # remove artifacts connected to image border
            cleared = bw.copy()
            clear_border(cleared)

            # label image regions
            label_image = label(cleared)
            borders = np.logical_xor(bw, cleared)
            label_image[borders] = -1

            num_mitoses = len(regionprops(label_image))

            white_pixels = count_nonblack_np(im)

            individual_vector.append(num_mitoses)
            individual_vector.append(white_pixels)

            vector.extend(individual_vector)
    return vector
示例#40
0
from skimage import data
from skimage.filters import threshold_otsu
from skimage.segmentation import clear_border
from skimage.measure import label
from skimage.morphology import closing, square, remove_small_objects
import numpy as np
import napari

image = data.coins()[50:-50, 50:-50]

# apply threshold
thresh = threshold_otsu(image)
bw = closing(image > thresh, square(4))

# remove artifacts connected to image border
cleared = remove_small_objects(clear_border(bw), 20)

# label image regions
label_image = label(cleared)

# initialise viewer with coins image
viewer = napari.view_image(image, name='coins', rgb=False)

# get the size of each coin (first element is background area)
label_areas = np.bincount(label_image.ravel())[1:]

# split coins into small or large
size_range = max(label_areas) - min(label_areas)
small_threshold = min(label_areas) + (size_range / 2)
coin_sizes = np.where(label_areas > small_threshold, 'large', 'small')
示例#41
0
    def get_intensity_properties(self, smallest_size, theMask, threshold, intensity_bef, intensty_aft, i, j, contour_thres, contour_dilationparameter, cell_region_opening, cell_region_closing):
        # remove artifacts connected to image border
        self.Labelmask = theMask # mask for general cell localization, so dosen't matter too much whose it is
        self.Imagbef = intensity_bef # Thresholded whole image
        self.Imageaft = intensty_aft        
        self.row_num = i
        self.column_num = j
        self.threshold = threshold
        self.contour_thres = contour_thres
        self.contour_dilationparameter = contour_dilationparameter
        self.cell_openingfactor = cell_region_opening#1
        self.cell_closingfactor = cell_region_closing#5
        
        cleared = self.Labelmask.copy()
        clear_border(cleared)
                # label image regions
        label_image = label(cleared)
        dtype = [('Row index', 'i4'), ('Column index', 'i4'), ('Mean intensity', float), ('Mean intensity in contour', float), ('Circularity', float), ('Contour soma ratio', float), ('Change', float)]
        
        region_mean_intensity_list = []
        region_circularit_list = []
        region_meanintensity_contour_list = []
        
        self.individual_cell_dic_bef = {}
        self.individual_cell_dic_aft = {}
        
        #Get 2 more pixels out of boundary box in case of cell movements
        #We need to add 2 rows and columns of 0 to the whole FOV in case cells detected at the edge
        expanded_image_container_bef = np.zeros((self.Imagbef.shape[0]+4, self.Imagbef.shape[1]+4))
        expanded_image_container_bef[2:self.Imagbef.shape[0]+2, 2:self.Imagbef.shape[1]+2] = self.Imagbef
        
        expanded_image_container_aft = np.zeros((self.Imageaft.shape[0]+4, self.Imageaft.shape[1]+4))
        expanded_image_container_aft[2:self.Imageaft.shape[0]+2, 2:self.Imageaft.shape[1]+2] = self.Imageaft
        
        loopmun = 0
        dirforcellprp={}
        for region in regionprops(label_image,intensity_image=self.Imagbef): # USE image before perfusion as template
            
            # skip small images
            if region.area > smallest_size:
                               
                # draw rectangle around segmented coins
                minr, minc, maxr, maxc = region.bbox
                #region_mean_intensity = region.mean_intensity #mean intensity of the region, 0 pixels in label are omitted.
                #allpixelnum = region.bbox_area
                #labeledpixelnum = region.area #number of pixels in region omitting 0.
                filledimg = region.filled_image 
                filledperimeter = perimeter(filledimg)
                regioncircularity = (4 * math.pi * region.filled_area) / (filledperimeter * filledperimeter) # region.perimeter will count in perimeters from the holes inside
                #Sliced_binary_region_image = region.image
                self.intensityimage_intensity = region.intensity_image # need a copy of this cause region will be altered by s.contour
                
                self.regionimage_before = expanded_image_container_bef[minr:maxr+4, minc:maxc+4] # Raw region image 
                self.regionimage_after = expanded_image_container_aft[minr:maxr+4, minc:maxc+4]
                
                self.regionimage_before_for_contour = self.regionimage_before.copy()
                self.regionimage_after_for_contour = self.regionimage_after.copy()
                
                self.individual_cell_dic_bef[str(loopmun)] = self.regionimage_before_for_contour # put each cell region into a dictionary
                self.individual_cell_dic_aft[str(loopmun)] = self.regionimage_after_for_contour
                '''
                plt.figure()
                plt.imshow(self.regionimage_before, cmap = plt.cm.gray) 
                plt.show() 
                '''
                #print(np.max(self.regionimage_before))
                # Get binary cell image baseed on expanded current region image
                thresh_regionbef = threshold_otsu(self.regionimage_before)
                self.expanded_binary_region_bef = np.where(self.regionimage_before >= thresh_regionbef, 1, 0)
                
                binarymask_bef = opening(self.expanded_binary_region_bef, square(self.cell_openingfactor))
                self.expanded_binary_region_bef = closing(binarymask_bef, square(self.cell_closingfactor))
        
                thresh_regionaft = threshold_otsu(self.regionimage_after)
                self.expanded_binary_region_aft = np.where(self.regionimage_after >= thresh_regionaft, 1, 0)
                
                binarymask_aft = opening(self.expanded_binary_region_aft, square(self.cell_openingfactor))
                self.expanded_binary_region_aft = closing(binarymask_aft, square(self.cell_closingfactor))
                '''
                print('Original raw image:')
                plt.figure()
                plt.imshow(self.regionimage_before, cmap = plt.cm.gray) 
                plt.show()  
                '''
                # fill in the holes
                seed_bef = np.copy(self.expanded_binary_region_bef)
                seed_bef[1:-1, 1:-1] = self.expanded_binary_region_bef.max()
                mask_bef = self.expanded_binary_region_bef
        
                self.filled_mask_bef = reconstruction(seed_bef, mask_bef, method='erosion')# The binary mask with filling holes
                
                seed_aft = np.copy(self.expanded_binary_region_aft)
                seed_aft[1:-1, 1:-1] = self.expanded_binary_region_aft.max()
                mask_aft = self.expanded_binary_region_aft
        
                self.filled_mask_aft = reconstruction(seed_aft, mask_aft, method='erosion')# fill in the holes
                
                filled_origin_image_intensity = self.regionimage_before*self.filled_mask_bef # Intensity image of cell with hole filled
                filled_mean_bef = np.mean(self.regionimage_before[np.where(self.filled_mask_bef == 1)]) # Mean pixel value of filled raw cell area
                
                # Find contour along filled image
                s=imageanalysistoolbox()
                contour_mask_bef = s.contour(self.filled_mask_bef, self.regionimage_before_for_contour.copy(), self.contour_thres) # after here self.intensityimage_intensity is changed from contour labeled with number 5 to binary image
                self.contour_mask_of_intensity_bef = s.inwarddilationmask(contour_mask_bef ,self.filled_mask_bef, self.contour_dilationparameter)   
            
                contourimage_intensity_aft = s.contour(self.filled_mask_aft, self.regionimage_after_for_contour.copy(), self.contour_thres) # after here self.intensityimage_intensity is changed with contour labeled with number 5
                self.contour_mask_of_intensity_aft = s.inwarddilationmask(contourimage_intensity_aft ,self.filled_mask_aft, self.contour_dilationparameter)

                contour_mean_bef = np.mean(self.regionimage_before[np.where(self.contour_mask_of_intensity_bef == 1)])
                contour_mean_aft = np.mean(self.regionimage_after[np.where(self.contour_mask_of_intensity_aft == 1)])  
                
                self.cell_soma_mask_bef = self.filled_mask_bef - self.contour_mask_of_intensity_bef
                
                contour_origin_image_intensity = self.regionimage_before*self.contour_mask_of_intensity_bef # Intensity image of cell contour
                soma_origin_image_intensity = self.regionimage_before*self.cell_soma_mask_bef # Intensity image of cell soma part

                soma_mean_bef = np.mean(self.regionimage_before[np.where(self.cell_soma_mask_bef == 1)])#Mean pixel value of soma area
                
                contour_soma_ratio = contour_mean_bef/soma_mean_bef
                contour_change_ratio = contour_mean_aft/contour_mean_bef

                plt.figure()
                plt.imshow(self.contour_mask_of_intensity_bef, cmap = plt.cm.gray)       
                plt.show()
                
                plt.figure()
                plt.imshow(self.contour_mask_of_intensity_aft, cmap = plt.cm.gray)       
                plt.show()
                '''
                '''
                print('Contour soma ratio: '+str(round(contour_soma_ratio, 3)))
                print('Contour image:')                                
                plt.figure()
                plt.imshow(contour_origin_image_intensity, cmap = plt.cm.gray)       
                plt.show()
                
                print('Soma image:')                                
                plt.figure()
                plt.imshow(soma_origin_image_intensity, cmap = plt.cm.gray)       
                plt.show()                

                #print(region_mean_intensity)
                region_mean_intensity_list.append(filled_mean_bef)# Mean intensity of filled image
                
                region_circularit_list.append(regioncircularity)
                region_meanintensity_contour_list.append(contour_mean_bef)                
                dirforcellprp[loopmun] = (self.row_num, self.column_num, filled_mean_bef, contour_mean_bef, regioncircularity, contour_soma_ratio, contour_change_ratio)
                
                loopmun = loopmun+1
        print('Total region number: {}'.format(loopmun))
        cell_properties = np.zeros(len(region_mean_intensity_list), dtype = dtype)
        for p in range(loopmun):
            cell_properties[p] = dirforcellprp[p]
            
        return cell_properties, self.expanded_binary_region_bef, contour_origin_image_intensity, self.intensityimage_intensity, contour_change_ratio                
示例#42
0
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage import segmentation
from skimage import morphology
from skimage import filter

coins = data.coins()

simple_threshold = coins > filter.threshold_otsu(coins)

adaptive_threshold = filter.threshold_adaptive(coins, 151)
filter_res = morphology.remove_small_objects(adaptive_threshold)
clear_image = segmentation.clear_border(filter_res)

plt.figure()
plt.subplot(221)
plt.imshow(coins, cmap='gray')
plt.title('Image d\'origine')
plt.axis('off')
plt.subplot(222)
plt.imshow(simple_threshold, cmap='gray')
plt.title('Simple seuillage')
plt.axis('off')
plt.subplot(223)
plt.imshow(adaptive_threshold, cmap='gray')
plt.title('Seuillage adaptatif')
plt.axis('off')
plt.subplot(224)
plt.imshow(clear_image, cmap='gray')
plt.title('Image nettoyee')
示例#43
0
def get_segmented_lungs(im, plot=False):
    '''
    This funtion segments the lungs from the given 2D slice.
    '''
    if plot == True:
        f, plots = plt.subplots(8, 1, figsize=(5, 40))
    '''
    Step 1: Convert into a binary image.
    '''
    binary = im < -320
    if plot == True:
        plots[0].axis('off')
        plots[0].set_title('binary image')
        plots[0].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 2: Remove the blobs connected to the border of the image.
    '''
    cleared = clear_border(binary)
    if plot == True:
        plots[1].axis('off')
        plots[1].set_title('after clear border')
        plots[1].imshow(cleared, cmap=plt.cm.bone)
    '''
    Step 3: Label the image.
    '''
    label_image = label(cleared)
    if plot == True:
        plots[2].axis('off')
        plots[2].set_title('found all connective graph')
        plots[2].imshow(label_image, cmap=plt.cm.bone)
    '''
    Step 4: Keep the labels with 2 largest areas.
    '''
    areas = [r.area for r in regionprops(label_image)]
    areas.sort()
    if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]:
                for coordinates in region.coords:
                    label_image[coordinates[0], coordinates[1]] = 0
    binary = label_image > 0
    if plot == True:
        plots[3].axis('off')
        plots[3].set_title(' Keep the labels with 2 largest areas')
        plots[3].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 5: Erosion operation with a disk of radius 2. This operation is
    seperate the lung nodules attached to the blood vessels.
    '''
    selem = disk(2)
    binary = binary_erosion(binary, selem)
    if plot == True:
        plots[4].axis('off')
        plots[4].set_title(
            'seperate the lung nodules attached to the blood vessels')
        plots[4].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 6: Closure operation with a disk of radius 10. This operation is
    to keep nodules attached to the lung wall.
    '''
    selem = disk(10)
    binary = binary_closing(binary, selem)
    if plot == True:
        plots[5].axis('off')
        plots[5].set_title('keep nodules attached to the lung wall')
        plots[5].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 7: Fill in the small holes inside the binary mask of lungs.
    '''
    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)
    if plot == True:
        plots[6].axis('off')
        plots[6].set_title(
            'Fill in the small holes inside the binary mask of lungs')
        plots[6].imshow(binary, cmap=plt.cm.bone)
    return binary
示例#44
0
for y in xrange(0, warped.shape[0], winY):
    for x in xrange(0, warped.shape[1], winX):

        window = warped[y:y + winY, x:x + winX]

        if window.shape[0] != winY or window.shape[1] != winX:
            continue

        clone = warped.copy()
        digit = cv2.resize(window, (28, 28))
        # cv2.imshow("digit", digit)
        # 90 works for sudoku3.jpg
        # increasing this number allows better readability
        _, digit2 = cv2.threshold(digit, 120, 255, cv2.THRESH_BINARY_INV)
        cv2.imshow("digit2", digit2)
        digit3 = clear_border(digit2)
        cv2.imshow("digit3", digit3)
        numpixel = cv2.countNonZero(digit3)
        _, digit4 = cv2.threshold(digit3, 0, 255, cv2.THRESH_BINARY_INV)
        cv2.imshow("digit4", digit4)
        # print(numpixel)
        if numpixel < 20:
            # print("0")
            label = 0
        else:
            # label = 1
            _, digit4 = cv2.threshold(digit4, 0, 255, cv2.THRESH_BINARY_INV)
            # digit4 = tf.keras.utils.normalize(digit4, axis=1)
            digit4 = digit4 / 255.0
            # print(digit4)
            array = model.predict(digit4.reshape(1, 28, 28, 1))
示例#45
0
    def detectCharacterCandidates(self, region):
        # apply a 4-point transform to extract the license plate
        plate = perspective.four_point_transform(self.image, region)

        # extract the Value component from the HSV color space and apply adaptive thresholding
        # to reveal the characters on the license plate
        V = cv2.split(cv2.cvtColor(plate, cv2.COLOR_BGR2HSV))[2]
        T = threshold_local(V, 19, offset=15, method="gaussian")
        thresh = (V > T).astype("uint8") * 255
        thresh = cv2.bitwise_not(thresh)

        # resize the license plate region to a canonical size
        plate = imutils.resize(plate, width=400)
        thresh = imutils.resize(thresh, width=400)

        # perform a connected components analysis and initialize the mask to store the locations
        # of the character candidates
        labels = measure.label(thresh, neighbors=8, background=0)
        charCandidates = np.zeros(thresh.shape, dtype="uint8")

        # loop over the unique components
        for label in np.unique(labels):
            # if this is the background label, ignore it
            if label == 0:
                continue

            # otherwise, construct the label mask to display only connected components for the
            # current label, then find contours in the label mask
            labelMask = np.zeros(thresh.shape, dtype="uint8")
            labelMask[labels == label] = 255
            cnts = cv2.findContours(labelMask, cv2.RETR_EXTERNAL,
                                    cv2.CHAIN_APPROX_SIMPLE)
            cnts = cnts[0] if imutils.is_cv2() else cnts[1]

            # ensure at least one contour was found in the mask
            if len(cnts) > 0:
                # grab the largest contour which corresponds to the component in the mask, then
                # grab the bounding box for the contour
                c = max(cnts, key=cv2.contourArea)
                (boxX, boxY, boxW, boxH) = cv2.boundingRect(c)

                # compute the aspect ratio, solidity, and height ratio for the component
                aspectRatio = boxW / float(boxH)
                solidity = cv2.contourArea(c) / float(boxW * boxH)
                heightRatio = boxH / float(plate.shape[0])

                # determine if the aspect ratio, solidity, and height of the contour pass
                # the rules tests
                keepAspectRatio = aspectRatio < 1.0
                keepSolidity = solidity > 0.15
                keepHeight = heightRatio > 0.4 and heightRatio < 0.95

                # check to see if the component passes all the tests
                if keepAspectRatio and keepSolidity and keepHeight:
                    # compute the convex hull of the contour and draw it on the character
                    # candidates mask
                    hull = cv2.convexHull(c)
                    cv2.drawContours(charCandidates, [hull], -1, 255, -1)

        # clear pixels that touch the borders of the character candidates mask and detect
        # contours in the candidates mask
        charCandidates = segmentation.clear_border(charCandidates)
        cnts = cv2.findContours(charCandidates.copy(), cv2.RETR_EXTERNAL,
                                cv2.CHAIN_APPROX_SIMPLE)
        cnts = cnts[0] if imutils.is_cv2() else cnts[1]

        # if there are more character candidates than the supplied number, then prune
        # the candidates
        if len(cnts) > self.numChars:
            (charCandidates, cnts) = self.pruneCandidates(charCandidates, cnts)

        # return the license plate region object containing the license plate, the thresholded
        # license plate, and the character candidates
        return LicensePlate(success=len(cnts) == self.numChars,
                            plate=plate,
                            thresh=thresh,
                            candidates=charCandidates)
示例#46
0
def seperate_lungs_and_pad(scan):

    # make total 256 slices fill in -1100 as exterme value
    segmented_scan = np.full((616, 512, 512), THRESHOLD_LOW)

    for i, image in enumerate(scan):

        # Ignore all slices later than 255 if required.
        if (i == 616):
            break

        # Creation of the internal Marker
        marker_internal = image < -400
        marker_internal = segmentation.clear_border(marker_internal)
        marker_internal_labels = measure.label(marker_internal)
        areas = [r.area for r in measure.regionprops(marker_internal_labels)]
        areas.sort()
        if len(areas) > 2:
            for region in measure.regionprops(marker_internal_labels):
                if region.area < areas[-2]:
                    for coordinates in region.coords:
                        marker_internal_labels[coordinates[0],
                                               coordinates[1]] = 0
        marker_internal = marker_internal_labels > 0
        #Creation of the external Marker
        external_a = ndimage.binary_dilation(marker_internal, iterations=10)
        external_b = ndimage.binary_dilation(marker_internal, iterations=55)
        marker_external = external_b ^ external_a
        #Creation of the Watershed Marker matrix
        marker_watershed = np.zeros((512, 512), dtype=np.int)
        marker_watershed += marker_internal * 255
        marker_watershed += marker_external * 128

        #Creation of the Sobel-Gradient
        sobel_filtered_dx = ndimage.sobel(image, 1)
        sobel_filtered_dy = ndimage.sobel(image, 0)
        sobel_gradient = np.hypot(sobel_filtered_dx, sobel_filtered_dy)
        sobel_gradient *= 255.0 / np.max(sobel_gradient)

        #Watershed algorithm
        watershed = morphology.watershed(sobel_gradient, marker_watershed)

        #Reducing the image created by the Watershed algorithm to its outline
        outline = ndimage.morphological_gradient(watershed, size=(3, 3))
        outline = outline.astype(bool)

        #Performing Black-Tophat Morphology for reinclusion
        #Creation of the disk-kernel and increasing its size a bit
        blackhat_struct = [[0, 0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0],
                           [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1],
                           [1, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 0],
                           [0, 0, 1, 1, 1, 0, 0]]
        blackhat_struct = ndimage.iterate_structure(blackhat_struct, 8)
        #Perform the Black-Hat
        outline += ndimage.black_tophat(outline, structure=blackhat_struct)

        #Use the internal marker and the Outline that was just created to generate the lungfilter
        lungfilter = np.bitwise_or(marker_internal, outline)
        #Close holes in the lungfilter
        #fill_holes is not used here, since in some slices the heart would be reincluded by accident
        lungfilter = ndimage.morphology.binary_closing(lungfilter,
                                                       structure=np.ones(
                                                           (5, 5)),
                                                       iterations=3)

        #Apply the lungfilter (note the filtered areas being assigned 30 HU)
        segmented_scan[i] = np.where(lungfilter == 1, image, 30 * np.ones(
            (512, 512)))

    return segmented_scan
示例#47
0
skprime = skeleton_th=skeletonize(removed)
lprime = np.sum(skprime)
w= aprime/lprime

# now that the noise has been removed, get a more representative value for average width of the edges in pixels

# sum binary map to get total area of edges
aprime = np.sum(removed)

# skeletonize and sum the skeleton to get total length of edges
skprime = skeleton_th=skeletonize(removed)
lprime = np.sum(skprime)
w= aprime/lprime

# clear the objects connected to the image border (in this case just the outside white rim)
clean_border = segmentation.clear_border(removed)

# label objects in the cleared image
all_labels, n = label(clean_border, return_num=True)

# one instance of closing to connect up lines that weren't completely crossing
# note: closing is dilation followed by erosion
# recall maxdim is the maximum of the length and width of the image (in pixels)
# maxdim*0.0020 is not an arbitrary value. Empirically, this value handles pen/pencil and marker sketches appropriately.
# Characterizes the human perception of a break in the sketch depending on the field of view.
eroded = closing(clean_border, disk(maxdim*0.0020))

# skeletonize and dilate to get final boundaries
edges = skeleton_th=skeletonize(eroded)
openedsk = ~dilation(edges,disk(1))
示例#48
0
from skimage import io, color, measure
from skimage.segmentation import clear_border

#Reading the image
img = cv2.imread("homes.jpg")
img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#Thresholdig our image
ret, thresh = cv2.threshold(img1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

#CLeaning
kernel = np.ones((5, 5), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)

#Clear border
opening = clear_border(opening)

#background
sure_bg = cv2.dilate(opening, kernel, iterations=1)
#foreground
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 3)

ret2, sure_fg = cv2.threshold(dist_transform, 0.2 * dist_transform.max(), 255,
                              0)
sure_fg = np.uint8(sure_fg)

unknown = cv2.subtract(sure_bg, sure_fg)

#define markers for watershed
ret3, markers = cv2.connectedComponents(sure_fg)
markers = markers + 10
示例#49
0
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from scipy.misc import imread, imresize
from skimage.segmentation import clear_border
from skimage.morphology import label
from skimage.measure import regionprops
from skimage.transform import resize

image = imread('./ocr/testing/alchemist2.png', 1)

#apply threshold in order to make the image binary
bw = image < 120

# remove artifacts connected to image border
cleared = bw.copy()
clear_border(cleared)

# label image regions
label_image = label(cleared, neighbors=8)
borders = np.logical_xor(bw, cleared)
label_image[borders] = -1

fig = plt.figure()
ax = fig.add_subplot(131)
ax.imshow(bw, cmap='jet')

order = []

for region in regionprops(label_image):
    minr, minc, maxr, maxc = region.bbox
    if maxr - minr > len(image) / 150:
def peak_candidates(xic_2d,
                    coordinates,
                    frame_pad=50,
                    scan_pad=100,
                    npeaks=3,
                    fout=None):
    xic_2d_max = xic_2d.max()
    im_gray = xic_2d / xic_2d_max
    #thresh = threshold_otsu(im_gray)
    #print('thresh:',thresh)

    local_peaks = []
    max_frames, max_scans = xic_2d.shape

    for i, j in coordinates:
        _min_frame = max(0, i - frame_pad)
        _max_frame = min(i + frame_pad, max_frames)
        _min_scan = max(0, j - scan_pad)
        _max_scan = min(j + scan_pad, max_scans)

        image = im_gray[_min_frame:_max_frame, _min_scan:_max_scan]

        #         plt.close('all')
        #         detected_peaks = detect_peaks(image)
        #         plt.subplot(1,2,1)
        #         plt.imshow(image)
        #         plt.subplot(1,2,2)
        #         plt.imshow(detected_peaks)
        #         plt.show()

        # apply threshold @TODO
        bw = closing(image > 0, square(3))

        # remove artifacts connected to image border
        cleared = clear_border(bw)

        # label image regions
        label_image = label(cleared)
        #print(np.unique(label_image))

        peak_areas = []
        background_mad = 0
        for l in range(label_image.max() + 1):
            idxs = np.where(label_image == l)
            peak_areas.append(xic_2d_max * np.sum(image[idxs]))
            if l == 0:
                background_mad = mad(xic_2d_max * image[idxs])  # background
                background_std = np.std(xic_2d_max * image[idxs],
                                        ddof=1)  # background
        sorted_idx = np.argsort(peak_areas)

        print('median absolute deviation in background area:', background_mad)
        print('standard deviation in background area:', background_std)

        areas = np.bincount(label_image.flatten())
        #         print('areas:', areas)
        #         sorted_idx = np.argsort(areas)
        #print('index:', sorted_idx[::-1][0:npeaks+1])

        peaks = []
        peak_region_top_right = []
        peak_region_xsize = []
        peak_region_ysize = []
        for kk in sorted_idx[::-1][0:npeaks + 1]:
            print('areas[kk]:', kk, areas[kk])
            print('peak areas[kk]:', kk, peak_areas[kk])

            if kk == 0: continue
            if areas[kk] < 5: continue  # too small: noise
            if peak_areas[kk] < 1: continue  # too small: background

            idxs = np.where(label_image == kk)

            apex_intensity = xic_2d_max * image[idxs].max()

            print('max intensity in peak areas[kk]:', kk, apex_intensity)

            peak_region_top_right.append((idxs[1].min(), idxs[0].min()))
            peak_region_xsize.append(idxs[1].max() - idxs[1].min() + 1)
            peak_region_ysize.append(idxs[0].max() - idxs[0].min() + 1)

            subimg = image[idxs[0].min():idxs[0].max() + 1,
                           idxs[1].min():idxs[1].max() + 1]

            lc_chrom = subimg.sum(axis=1).reshape((-1, 1))
            dt_chrom = subimg.sum(axis=0).reshape((-1, 1))

            lcidx = np.argmax(lc_chrom)
            dtidx = np.argmax(dt_chrom)

            print(idxs[0].min(), lcidx, idxs[1].min(), dtidx)
            peak_lc_idx = idxs[0].min() + lcidx
            peak_dt_idx = idxs[1].min() + dtidx
            peaks.append((peak_lc_idx, peak_dt_idx))

            local_peaks.append({
                'frame_idx': peak_lc_idx + _min_frame,
                'scan_idx': peak_dt_idx + _min_scan,
                'start_frame': idxs[0].min() + _min_frame,
                'end_frame': idxs[0].max() + _min_frame,
                'start_scan': idxs[1].min() + _min_scan,
                'end_scan': idxs[1].max() + _min_scan,
                'peak_area': peak_areas[kk],
                'background_mad': background_mad,
                'background_std': background_std,
                'apex_intensity': apex_intensity
            })

            if len(peaks) >= npeaks: break
        peaks = np.array(peaks)

        if peaks.shape[0] == 0: continue  #

        print('label_image:', label_image.shape)
        image_label_overlay = label2rgb(label_image, image=image)
        print('image_label_overlay:', image_label_overlay.shape)

        lc_chrom = image.sum(axis=1).reshape((-1, 1))
        dt_chrom = image.sum(axis=0).reshape((-1, 1))

        ##############################################
        plt.close('all')
        plt.figure(figsize=(10, 6))
        ax_dt = plt.subplot2grid((3, 8), (0, 0), colspan=7)
        ax_xic = plt.subplot2grid((3, 8), (1, 0), colspan=7, rowspan=2)
        ax_lc = plt.subplot2grid((3, 8), (1, 7), rowspan=2)

        ax_xic.imshow(image_label_overlay)
        ax_xic.scatter(peaks[:, 1], peaks[:, 0], c='r')

        for (p0, p1), w, h in zip(peak_region_top_right, peak_region_xsize,
                                  peak_region_ysize):
            print(p0 + _min_scan, p1 + _min_frame, w, h)
            # Add the patch to the Axes
            ax_xic.add_patch(
                patches.Rectangle((p0, p1),
                                  w,
                                  h,
                                  linewidth=4,
                                  edgecolor='r',
                                  facecolor='none'))

        ax_xic.set_yticks(
            np.arange(0, _max_frame - _min_frame,
                      (_max_frame - _min_frame) // 3))
        ax_xic.set_xticks(
            np.arange(0, _max_scan - _min_scan, (_max_scan - _min_scan) // 10))
        ax_xic.set_xticklabels(np.array(ax_xic.get_xticks()) + _min_scan)
        ax_xic.set_yticklabels(np.array(ax_xic.get_yticks()) + _min_frame)

        base = ax_lc.transData
        rot = Affine2D().rotate_deg(270)

        ax_lc.plot(range(_min_frame, _max_frame),
                   lc_chrom,
                   transform=rot + base)
        ax_lc.scatter(peaks[:, 0] + _min_frame,
                      lc_chrom[peaks[:, 0]],
                      c='r',
                      transform=rot + base)

        ax_dt.plot(range(_min_scan, _max_scan), dt_chrom)
        ax_dt.scatter(peaks[:, 1] + _min_scan, dt_chrom[peaks[:, 1]], c='r')

        plt.tight_layout()
        if fout is not None:
            plt.savefig(fout + "_frame={0}_scan={1}.png".format(
                peaks[0, 0] + _min_frame, peaks[0, 1] + _min_scan))
        else:
            plt.show()
        ##############################################

#         # image_max is the dilation of im with a 20*20 structuring element
#         # It is used within peak_local_max function
#         image_max = ndi.maximum_filter(image, size=5, mode='constant')

#         # Comparison between image_max and im to find the coordinates of local maxima
#         coordinates = peak_local_max(image, min_distance=3, num_peaks=2)

#         # display results
#         fig, axes = plt.subplots(1, 3, figsize=(8, 3), sharex=True, sharey=True)
#         ax = axes.ravel()
#         ax[0].imshow(image)
#         # ax[0].matshow(im, norm=LogNorm(vmin=10, vmax=500))
#         ax[0].axis('off')
#         ax[0].set_title('Original')

#         ax[1].imshow(image_max, cmap=plt.cm.gray)
#         ax[1].axis('off')
#         ax[1].set_title('Maximum filter')

#         ax[2].imshow(image, cmap=plt.cm.gray)
#         ax[2].autoscale(False)
#         ax[2].plot(coordinates[:, 1], coordinates[:, 0], 'r.')
#         for p0,w,h in zip(peak_region_top_right, peak_region_xsize, peak_region_ysize):
#             print(p0,w,h)
#             # Add the patch to the Axes
#             ax[2].add_patch(patches.Rectangle(p0,w,h,linewidth=4,edgecolor='r',facecolor='none'))

#         ax[2].axis('off')
#         ax[2].set_title('Peak local max')

#         plt.show()
    return local_peaks
示例#51
0
def get_segmented_lungs(im, plot=False):
    '''
    This funtion segments the lungs from the given 2D slice.
    '''
    # if plot == True:
    #     f, plots = plt.subplots(4, 2, figsize=(5, 40))
    '''
    Step 1: Convert into a binary image.
    '''
    binary = im < -600
    # if plot == True:
    #     plots[0][0].axis('off')
    #     plots[0][0].set_title('binary image')
    #     plots[0][0].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 2: Remove the blobs connected to the border of the image.
    '''
    cleared = clear_border(binary)
    # if plot == True:
    #     plots[0][1].axis('off')
    #     plots[0][1].set_title('after clear border')
    #     plots[0][1].imshow(cleared, cmap=plt.cm.bone)
    '''
    Step 3: Label the image.
    '''
    label_image = label(cleared)
    # if plot == True:
    #     plots[1][0].axis('off')
    #     plots[1][0].set_title('found all connective graph')
    #     plots[1][0].imshow(label_image, cmap=plt.cm.bone)
    '''
    Step 4: Keep the labels with 2 largest areas.
    '''
    areas = [r.area for r in regionprops(label_image)]
    areas.sort()
    if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]:
                for coordinates in region.coords:
                    label_image[coordinates[0], coordinates[1]] = 0
    binary = label_image > 0
    # if plot == True:
    #     plots[1][1].axis('off')
    #     plots[1][1].set_title(' Keep the labels with 2 largest areas')
    #     plots[1][1].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 5: Erosion operation with a disk of radius 2. This operation is
    seperate the lung nodules attached to the blood vessels.
    '''
    selem = disk(2)
    binary = binary_erosion(binary, selem)
    # if plot == True:
    #     plots[2][0].axis('off')
    #     plots[2][0].set_title('seperate the lung nodules attached to the blood vessels')
    #     plots[2][0].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 6: Closure operation with a disk of radius 10. This operation is
    to keep nodules attached to the lung wall.
    '''
    selem = disk(10)
    binary = binary_closing(binary, selem)
    # if plot == True:
    #     plots[2][1].axis('off')
    #     plots[2][1].set_title('keep nodules attached to the lung wall')
    #     plots[2][1].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 7: Fill in the small holes inside the binary mask of lungs.
    '''
    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)
    # if plot == True:
    #     plots[3][0].axis('off')
    #     plots[3][0].set_title('Fill in the small holes inside the binary mask of lungs')
    #     plots[3][0].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 8: Superimpose the binary mask on the input image.
    '''
    sum = 0

    for r in regionprops(label_image):
        sum = sum + r.area
    proportion = sum / (512 * 512)

    im = (255 / 1800 * im + 1200 * 255 / 1800)
    get_high_vals = binary == 0
    im[get_high_vals] = 170
    im = np.rint(im)
    # if plot == True:
    #     plots[3][1].axis('off')
    #     plots[3][1].set_title('Superimpose the binary mask on the input image')
    #     plots[3][1].imshow(im, cmap=plt.cm.bone)
    return im, proportion
示例#52
0
    local_max = peak_local_max(distance,
                               indices=False,
                               footprint=np.ones((1, 1)))
    """
    ndi.label():
    Label features in an array. An array-like object to be labeled. 
    Any non-zero values in input are counted as features and zero values are considered the background.
    """
    markers = ndi.label(local_max)[0]
    watershed_img = watershed(distance,
                              markers=markers,
                              mask=filled_contours_img)
    cleared_img = opening(watershed_img, selem=disk(2))

    #remove artifacts connected to image border
    final_mask = clear_border(cleared_img)

    #####################################################################

    # step 4: label image regions, label the object in the mask

    from skimage.measure import label, regionprops
    from skimage.color import label2rgb

    #1. label mask with different colors
    color_label_img = label(final_mask)
    # to make the background transparent, pass the value of `bg_label`,
    # and leave `bg_color` as `None` and `kind` as `overlay`
    image_label_overlay = label2rgb(color_label_img, bg_label=0)

    #2. label the mask with integer
            x1 = 31
            x2 = 32
        if a == 24:
            x1 = 32
            x2 = 32
        if a == 25:
            x1 = 33
            x2 = 22
        for i in range(1, x2 + 1):
            im = 'rST0000' + str(a) + ' (' + str(x1) + ')_%d' % i
            path_raw = 't2w/prostate_t2w_' + fold + '_lr_low/' + nb + '_net_G_val/images/input/' + im + '.png'
            path_mask_ori = 't2w/prostate_t2w_' + fold + '_lr_low/' + nb + '_net_G_val/images/target/' + im + '.png'
            path_mask_pred = 't2w/prostate_t2w_' + fold + '_lr_low/' + nb + '_net_G_val/images/output/' + im + '.png'

            raw = cv2.imread(path_raw)
            mask_ori = cv2.imread(path_mask_ori)
            mask_pred = cv2.imread(path_mask_pred)

            mask_ori1 = cv2.imread(path_mask_ori, 0)
            mask_pred1 = cv2.imread(path_mask_pred, 0)

            mask_pred_bin = gray2binary(mask_pred1)
            cleared_bin = clear_border(mask_pred_bin)
            labels, num = label(cleared_bin, return_num=True)
            mask_return_bin = keep_biggest_label(labels, num)
            mask_return_gray = binary2gray(mask_return_bin)

            cv2.imwrite(
                't2w/prostate_t2w_' + fold + '_lr_low/' + nb +
                '_net_G_val/images/post/' + im + '.png', mask_return_gray)
示例#54
0
def reading(imageSource):
    global predictions_test
    im = cv2.imread(imageSource, 0)
    img = cv2.getRectSubPix(im, (320, 240), (150, 150))
    thresh = 136
    im_bw = cv2.threshold(img, thresh, 255, cv2.THRESH_BINARY)[1]

    ret, im_inv = cv2.threshold(im_bw, thresh, 255, cv2.THRESH_BINARY_INV)
    cleared = clear_border(im_bw)

    label_image = label(cleared)

    areas = [r.area for r in regionprops(label_image)]
    areas.sort()
    if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]:
                for coordinates in region.coords:
                    label_image[coordinates[0], coordinates[1]] = 0
    binary = label_image > 0

    selem = disk(2)
    binary = binary_erosion(binary, selem)
    selem = disk(10)
    binary = binary_closing(binary, selem)

    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)

    get_high_vals = binary == 0
    img[get_high_vals] = 0

    contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL,
                                           cv2.CHAIN_APPROX_SIMPLE)

    numOfContours = len(contours)  #number of contours

    area = []
    perimeter = []
    count = 0
    for count in range(numOfContours):
        cv2.drawContours(img, contours, -1, (20, 255, 60), 1)  #draw contours
        cnt = contours[count]
        area.append(cv2.contourArea(cnt))
        peri = cv2.arcLength(cnt, True)
        perimeter.append(peri)
        #print(area)

        count += 1
        #print(contours)

    #print(numOfContours)
    if len(area) == 0:
        a = 0
        p = 0
        e = 0
        d = 0
    else:

        a = max(area)

        for i in range(numOfContours):
            if area[i] == a:
                k = i
        if a < 20:
            e = 1
        else:
            cnt = contours[k]
            ellipse = cv2.fitEllipse(cnt)
            (center, axes, orientation) = ellipse
            majoraxis_length = max(axes)
            minoraxis_length = min(axes)
            e = minoraxis_length / majoraxis_length
        p = perimeter[k]
        d = np.sqrt(4 * a / np.pi)
    im_inv = clear_border(im_inv)
    contours, hierarchy = cv2.findContours(im_inv, cv2.RETR_EXTERNAL,
                                           cv2.CHAIN_APPROX_SIMPLE)
    ar = []
    count = 0
    numOfContour = len(contours)
    for count in range(numOfContour):
        cv2.drawContours(im_inv, contours, -1, (20, 255, 60),
                         1)  #draw contours
        cnt = contours[count]
        ar.append(cv2.contourArea(cnt))
        #print(area)

        count += 1
        #print(contours)

    #print(numOfContour)
    if ar == []:
        area = 0
    else:
        area = sum(ar)

    csvTitle = [[
        'NoduleArea', 'NoduleContour', 'Perimeter', 'Eccentricity', 'Diameter',
        'LungArea', 'LungContour'
    ]]
    csvData = []
    csvData.append([a, numOfContours, p, e, d, area, numOfContour])
    with open('new.csv', 'w') as csvFile:
        writer = csv.writer(csvFile)
        writer.writerows(csvTitle)
        writer.writerows(csvData)

    d = pd.read_csv("new.csv")
    d_new = pd.read_csv("new.csv", na_values=['?'])

    d_new.dropna(inplace=True)

    X_test = d_new[['NoduleArea', 'Perimeter', 'Diameter', 'Eccentricity']]

    predictions_test = svc.predict(X_test)
    if predictions_test == 0:
        print("Cancer not detected")
    if predictions_test == 1:
        print("Cancer detecetd \n Stage:1")
    if predictions_test == 2:
        print("Cancer detected \n Stage:2")
    if predictions_test == 3:
        print("Cancer detected \n Stage:3")
示例#55
0
from skimage.color import label2rgb, rgb2gray
from skimage.transform import downscale_local_mean

im_file = io.imread("photo.bmp")
#image = data.coins()[50:-50, 50:-50]
# image = scaled[:, :, 0]
im_gray = rgb2gray(im_file)
image = downscale_local_mean(im_gray, (10, 10))
# io.imsave("photo.png", image)

# apply threshold
thresh = threshold_otsu(image)
bw = closing(image > thresh, square(5))

# remove artifacts connected to image border
cleared = clear_border(bw)

# label image regions
label_image = label(bw)
image_label_overlay = label2rgb(label_image, image=image)

fig, ax = plt.subplots(figsize=(10, 6))
ax.imshow(image)  #_label_overlay)

for region in regionprops(label_image):
    # take regions with large enough areas
    if region.area >= 100:
        # draw rectangle around segmented coins
        minr, minc, maxr, maxc = region.bbox
        rect = mpatches.Rectangle((minc, minr),
                                  maxc - minc,
示例#56
0
def detect(frame):

    font = cv2.FONT_HERSHEY_SIMPLEX  #设置显示字体类型,正常大小无衬线字体
    cimg = frame
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)  #BGR转HSV

    # color range
    lower_red1 = np.array([0, 100, 100])  #定义在HSV空间中红色的范围
    upper_red1 = np.array([10, 255, 255])
    lower_red2 = np.array([160, 100, 100])  #定义在HSV空间中红色的范围
    upper_red2 = np.array([180, 255, 255])
    lower_green = np.array([40, 50, 50])  #定义在HSV空间中绿色的范围
    upper_green = np.array([90, 255, 255])
    lower_yellow = np.array([15, 150, 150])  #定义在HSV空间中黄色的范围
    upper_yellow = np.array([35, 255, 255])
    #根据以上定义的红绿黄颜色方位得到个颜色交通灯部分
    mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
    mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
    mask_g = cv2.inRange(hsv, lower_green, upper_green)
    mask_y = cv2.inRange(hsv, lower_yellow, upper_yellow)
    mask_r = cv2.add(mask1, mask2)

    #定义结构元素,形态学开运算
    element = cv2.getStructuringElement(cv2.MORPH_CROSS,
                                        (1, 1))  #定义MORPH_CROSS比MORPH_RECT效果好
    #开运算
    opened_r = cv2.morphologyEx(mask_r, cv2.MORPH_OPEN, element)
    opened_g = cv2.morphologyEx(mask_g, cv2.MORPH_OPEN, element)
    opened_y = cv2.morphologyEx(mask_y, cv2.MORPH_OPEN, element)

    ################检测红色交通灯########################
    segmentation.clear_border(opened_r)  #清除与边界相连的目标物
    label_image_r = measure.label(opened_r)  #连通区域标记
    borders_r = np.logical_xor(mask_r, opened_r)  #异或
    label_image_r[borders_r] = -1
    for region_r in measure.regionprops(label_image_r):  #循环得到每一个连通区域属性集
        #忽略小区域和大面积
        if region_r.convex_area < 120 or region_r.area > 2000:
            continue
        #绘制外包矩形
        area = region_r.area  #连通域面积,区域内像素点总数
        eccentricity = region_r.eccentricity  #连通域离心率
        convex_area = region_r.convex_area  #凸包内像素总数
        minr, minc, maxr, maxc = region_r.bbox  #边界外连接
        perimeter = region_r.perimeter  #区域周长
        radius = max(maxr - minr, maxc - minc) / 2  #连通域外接矩形长轴的一半
        centroid = region_r.centroid  #质心坐标
        x = int(centroid[0])
        y = int(centroid[1])
        rect = mpatches.Rectangle((minc, minr),
                                  maxc - minc,
                                  maxr - minr,
                                  fill=False,
                                  edgecolor='red',
                                  linewidth=2)

        if perimeter == 0:
            circularity = 1
        else:
            circularity = 4 * 3.141592 * area / (perimeter * perimeter)
            circum_circularity = 4 * 3.141592 * convex_area / (
                4 * 3.1592 * 3.1592 * radius * radius)

        if eccentricity <= 0.4 or circularity >= 0.7 or circum_circularity >= 0.73:
            cv2.circle(cimg, (y, x), radius, (0, 0, 255), 3)
            cv2.putText(cimg, 'RED', (y, x), font, 1, (0, 0, 255), 2)
            return "RED", cimg
        else:
            continue

    ################检测绿色交通灯########################
    segmentation.clear_border(opened_g)  #清除与边界相连的目标物
    label_image_g = measure.label(opened_g)  #连通区域标记
    borders_g = np.logical_xor(mask_g, opened_g)  #异或
    label_image_g[borders_g] = -1
    for region_g in measure.regionprops(label_image_g):  #循环得到每一个连通区域属性集
        if region_g.convex_area < 130 or region_g.area > 2000:
            continue
        area = region_g.area  #连通域面积
        eccentricity = region_g.eccentricity  #连通域离心率
        convex_area = region_g.convex_area  #凸包内像素总数
        minr, minc, maxr, maxc = region_g.bbox  #边界外连接
        radius = max(maxr - minr, maxc - minc) / 2  #连通域外接矩形长轴的一半
        centroid = region_g.centroid  #质心坐标
        perimeter = region_g.perimeter  #区域周长
        x = int(centroid[0])
        y = int(centroid[1])
        rect = mpatches.Rectangle((minc, minr),
                                  maxc - minc,
                                  maxr - minr,
                                  fill=False,
                                  edgecolor='red',
                                  linewidth=2)

        if perimeter == 0:
            circularity = 1
        else:
            circularity = 4 * 3.141592 * area / (perimeter * perimeter)
            circum_circularity = 4 * 3.141592 * convex_area / (
                4 * 3.1592 * 3.1592 * radius * radius)

        if eccentricity <= 0.4 or circularity >= 0.7 or circum_circularity >= 0.8:
            cv2.circle(cimg, (y, x), radius, (0, 255, 0), 3)
            cv2.putText(cimg, 'GREEN', (y, x), font, 1, (0, 255, 0), 2)
            return "GREEN", cimg
        else:
            continue

    ################检测黄色交通灯########################
    segmentation.clear_border(opened_y)  #清除与边界相连的目标物
    label_image_y = measure.label(opened_y)  #连通区域标记
    borders_y = np.logical_xor(mask_y, opened_y)  #异或
    label_image_y[borders_y] = -1
    for region_y in measure.regionprops(label_image_y):  #循环得到每一个连通区域属性集
        if region_y.convex_area < 130 or region_y.area > 2000:
            continue
        area = region_y.area  #连通域面积
        eccentricity = region_y.eccentricity  #连通域离心率
        convex_area = region_y.convex_area  #凸包内像素总数
        minr, minc, maxr, maxc = region_y.bbox  #边界外连接
        radius = max(maxr - minr, maxc - minc) / 2  #连通域外接矩形长轴的一半
        centroid = region_y.centroid  #质心坐标
        perimeter = region_y.perimeter  #区域周长
        x = int(centroid[0])
        y = int(centroid[1])
        rect = mpatches.Rectangle((minc, minr),
                                  maxc - minc,
                                  maxr - minr,
                                  fill=False,
                                  edgecolor='red',
                                  linewidth=2)

        if perimeter == 0:
            circularity = 1
        else:
            circularity = 4 * 3.141592 * area / (perimeter * perimeter)
            circum_circularity = 4 * 3.141592 * convex_area / (
                4 * 3.1592 * 3.1592 * radius * radius)

        if eccentricity <= 0.4 or circularity >= 0.7 or circum_circularity >= 0.8:
            cv2.circle(cimg, (y, x), radius, (0, 255, 255), 3)
            cv2.putText(cimg, 'YELLOW', (y, x), font, 1, (0, 255, 255), 2)
            return "YELLOW", cimg
        else:
            continue
    return "NONE", frame
    (minVal, maxVal) = (np.min(gradX), np.max(gradX))
    gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))
    gradX = gradX.astype("uint8")

    # apply a closing operation using the rectangular kernel to help
    # close gaps in between rounting and account digits, then apply
    # Otsu's thresholding method to binarize the image
    gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
    thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY
                           | cv2.THRESH_OTSU)[1]  # initial code line
    # thresh = cv2.threshold(gradX, 0, 255, cv2.CV_8UC1)[1]
    # thresh = cv2.threshold(gradX, 0, 255, cv2.CV_32SC1)[1]

    # remove any pixels that are touching the borders of the image (this
    # simply helps us in the next step when we prune contours)
    thresh = clear_border(thresh)

    # find contours in the thresholded image, then initialize the
    # list of group locations
    # groupCnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    groupCnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                                 cv2.CHAIN_APPROX_SIMPLE)

    # ------ code modification on line 164-107, initial line is 104 ------ # 18-05-2020
    # groupCnts = groupCnts[0] if imutils.is_cv2() else groupCnts[1]
    groupCnts = groupCnts[0]  #if imutils.is_cv2() else groupCnts[1]
    # OR
    # groupCnts = groupCnts[1] if imutils.is_cv3() else groupCnts[0]
    # -------------------------------------------------------------------- #

    groupLocs = []
示例#58
0
image = img_as_ubyte(rgb2gray(io.imread("images/cast_iron1.tif")))
plt.imshow(image, cmap='gray')
scale = 0.6  #microns/pixel

#plt.hist(blue_channel.flat, bins=100, range=(0,150))  #.flat returns the flattened numpy array (1D)

from skimage.filters import threshold_otsu
threshold = threshold_otsu(image)

#Generate thresholded image
thresholded_img = image < threshold
plt.imshow(thresholded_img)

#Remove edge touching regions
from skimage.segmentation import clear_border
edge_touching_removed = clear_border(thresholded_img)
plt.imshow(edge_touching_removed)

#Label connected regions of an integer array using measure.label
#Labels each connected entity as one object
#Connectivity = Maximum number of orthogonal hops to consider a pixel/voxel as a neighbor.
#If None, a full connectivity of input.ndim is used, number of dimensions of the image
#For 2D image it would be 2

label_image = measure.label(edge_touching_removed, connectivity=image.ndim)

plt.imshow(label_image)
#Return an RGB image where color-coded labels are painted over the image.
#Using label2rgb

image_label_overlay = label2rgb(label_image, image=image)
示例#59
0
def split_page(src_image, min_page_no):
    image = io.imread(src_image, 0)
    bw = binarisation(image)
    image_height, image_width = bw.shape
    bw = (1 - bw).astype('ubyte')
    bw = clear_border(bw)
    label_image = label(bw, connectivity=2)
    #image_label_overlay = label2rgb(label_image, image=image)

    minr = 0
    minc = 0
    maxr = 0
    maxc = 0
    regions = []
    vol_regions = []
    #fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
    for region in regionprops(label_image):
        minr, minc, maxr, maxc = region.bbox
        w = maxc - minc
        h = maxr - minr
        if h > 1000 and h < 1700 and w > 100 and w < 300:
            #print minr, minc, maxr, maxc
            vol_regions.append((minr, minc, maxr, maxc))
        if minc < 200 and maxc > (image_width - 200):
            continue
        if (maxr - minr) < 1300:
            continue
        if (maxc - minc) < 800:
            continue
        regions.append((minr, minc, maxr, maxc))
        print minr, minc, maxr, maxc
        #rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
        #                          fill=False, edgecolor='red', linewidth=1)
        #ax.add_patch(rect)
    count = len(regions)
    regions.sort(key=itemgetter(1))
    #print 'count: ', count
    # if count >= 2: # 将距离很近的相邻两个框合并
    #     pop_index = []
    #     for i in range(count - 1):
    #         if (abs(regions[i + 1][1] - regions[i][1]) < 120) or (abs(regions[i + 1][3] - regions[i][3]) < 120):
    #             pop_index.append(i)
    #             minr = min(regions[i][0], regions[i + 1][0])
    #             minc = min(regions[i][1], regions[i + 1][1])
    #             maxr = max(regions[i][2], regions[i + 1][2])
    #             maxc = min(regions[i][3], regions[i + 1][3])
    #             regions[i + 1] = (minr, minc, maxr, maxc)
    #     if pop_index:
    #         new_regions = []
    #         for i in range(count):
    #             if i not in pop_index:
    #                 new_regions.append(regions[i])
    #         regions = new_regions

    merged_regions = []
    count = len(regions)
    print count
    minr = 0
    minc = 0
    maxr = 0
    maxc = 0
    for i in range(count):
        if i == 0:
            minr, minc, maxr, maxc = regions[i]
        else:
            if abs(regions[i][1] - minc) < 300:
                minr = min(regions[i][0], minr)
                minc = min(regions[i][1], minc)
                maxr = max(regions[i][2], maxr)
                maxc = max(regions[i][3], maxc)
            else:
                merged_regions.append((minr, minc, maxr, maxc))
                print minr, minc, maxr, maxc
                minr, minc, maxr, maxc = regions[i]
    if maxr != 0:
        merged_regions.append((minr, minc, maxr, maxc))
        print minr, minc, maxr, maxc
    regions = merged_regions
    count = len(regions)

    #print 'count: ', count
    save_count = 0
    if count >= 2:
        for i in range(1, -1, -1):
            minr, minc, maxr, maxc = regions[i]
            #print minr, minc, maxr, maxc
            page_no = min_page_no + (1 - i)
            page_image = image[minr:maxr + 1, minc:maxc + 1]
            page_binary_image = bw[minr:maxr + 1, minc:maxc + 1]
            angle = deskew_page(page_image, page_binary_image)
            if angle != 0.0:
                image_new = rotate(page_image, angle, mode='edge')
                page_image = (image_new * 255).astype('ubyte')
            io.imsave('%03d.jpg' % page_no, page_image)
            save_count = save_count + 1
    elif count == 1:
        print 'vol_regions: ', len(vol_regions)
        minr, minc, maxr, maxc = regions[0]
        c_center = (minc + maxc) / 2
        if c_center < image_width / 2:  # left part
            #print 'left part'
            page_no = min_page_no
            if vol_regions:
                vol_center = (vol_regions[0][1] + vol_regions[0][3]) / 2
                if vol_center > image_width / 2:
                    page_image = image[minr:maxr + 1,
                                       maxc + 100:image_width - 20]
                    page_binary_image = bw[minr:maxr + 1,
                                           maxc + 100:image_width - 20]
                    angle = deskew_page(page_image, page_binary_image)
                    if angle != 0.0:
                        image_new = rotate(page_image, angle, mode='edge')
                        page_image = (image_new * 255).astype('ubyte')
                    io.imsave('%03d.jpg' % page_no, page_image)
                    page_no = page_no + 1
                    save_count = save_count + 1
            page_image = image[minr:maxr + 1, minc:maxc + 1]
            io.imsave('%03d.jpg' % page_no, page_image)
            save_count = save_count + 1
        else:
            #print 'right part'
            page_image = image[minr:maxr + 1, minc:maxc + 1]
            page_binary_image = bw[minr:maxr + 1, minc:maxc + 1]
            angle = deskew_page(page_image, page_binary_image)
            if angle != 0.0:
                image_new = rotate(page_image, angle, mode='edge')
                page_image = (image_new * 255).astype('ubyte')
            io.imsave('%03d.jpg' % min_page_no, page_image)
            save_count = save_count + 1

            if vol_regions:
                vol_center = (vol_regions[0][1] + vol_regions[0][3]) / 2
                if vol_center < image_width / 2:
                    page_image = image[minr:maxr + 1, 20:minc - 100]
                    page_binary_image = bw[minr:maxr + 1, 20:minc - 100]
                    angle = deskew_page(page_image, page_binary_image)
                    if angle != 0.0:
                        image_new = rotate(page_image, angle, mode='edge')
                        page_image = (image_new * 255).astype('ubyte')
                    io.imsave('%03d.jpg' % (min_page_no + 1), page_image)
                    save_count = save_count + 1
    else:  # count == 0
        for region in regionprops(label_image):
            minr, minc, maxr, maxc = region.bbox
            if (maxr - minr) < 1000:
                continue
            regions.append((minr, minc, maxr, maxc))
        if len(regions) > 0:
            minr, minc, maxr, maxc = regions[0]
            c_center = (minc + maxc) / 2
            if c_center < image_width / 2:
                page_image = image[20:image_height - 20,
                                   20:image_width / 2 - 20]
                page_binary_image = bw[20:image_height - 20,
                                       20:image_width / 2 - 20]
                angle = deskew_page(page_image, page_binary_image)
                if angle != 0.0:
                    image_new = rotate(page_image, angle, mode='edge')
                    page_image = (image_new * 255).astype('ubyte')
                io.imsave('%03d.jpg' % min_page_no, page_image)
                save_count = save_count + 1
            else:
                page_image = image[20:image_height - 20,
                                   image_width / 2 + 20:image_width - 20]
                page_binary_image = bw[20:image_height - 20,
                                       image_width / 2 + 20:image_width - 20]
                angle = deskew_page(page_image, page_binary_image)
                if angle != 0.0:
                    image_new = rotate(page_image, angle, mode='edge')
                    page_image = (image_new * 255).astype('ubyte')
                io.imsave('%03d.jpg' % min_page_no, page_image)
                save_count = save_count + 1
    return save_count
示例#60
0
def extract_digit(cell, debug=False):
    # apply automatic thresholding to the cell and then clear any
    # connected borders that touch the border of the cell
    thresh = cv2.threshold(cell, 0, 255,
                           cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]

    # This is new!
    # resize the picture, bolden the digit and eliminate border
    # SCALE_FACTOR = 1
    # scaled_height = int(thresh.shape[0] * SCALE_FACTOR)
    # scaled_width = int(thresh.shape[1] * SCALE_FACTOR)
    # top_pad = int((scaled_height - thresh.shape[0]) / 2)
    # left_pad = int((scaled_width - thresh.shape[1]) / 2)
    # big_mask = np.zeros((scaled_height, scaled_width), dtype="uint8")
    # big_mask = cv2.resize(thresh, big_mask.shape)
    # thresh = big_mask[top_pad:top_pad + thresh.shape[0], left_pad:left_pad + thresh.shape[1]]
    thresh = clear_border(thresh)

    # check to see if we are visualizing the cell thresholding step
    if debug:
        cv2.imshow("Cell Thresh", thresh)
        cv2.waitKey(0)

    # find contours in the thresholded cell
    cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                            cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)

    # if no contours were found than this is an empty cell
    if len(cnts) == 0:
        return None

    # otherwise, find the largest contour in the cell and create a
    # mask for the contour
    # c = max(cnts, key=cv2.contourArea)
    # mask = np.zeros(thresh.shape, dtype="uint8")
    # cv2.drawContours(mask, [c], -1, 255, -1)

    # otherwise, find contours large enough in the cell and create a
    # mask for the contour
    mask = np.zeros(thresh.shape, dtype="uint8")
    cv2.drawContours(mask, cnts, -1, 255, -1)

    # if debug:
    #     cv2.imshow("Mask", mask)
    #     cv2.waitKey(0)

    # compute the percentage of masked pixels relative to the total
    # area of the image
    (h, w) = thresh.shape
    percent_filled = cv2.countNonZero(mask) / float(w * h)

    # if less than 1% of the mask is filled then we are looking at
    # noise and can safely ignore the contour
    if percent_filled < 0.01:
        return None

    # apply the mask to the thresholded cell
    digit = cv2.bitwise_and(thresh, thresh, mask=mask)
    # digit = cv2.bitwise_and(thresh, thresh)

    # check to see if we should visualize the masking step
    if debug:
        cv2.imshow("Digit", digit)
        cv2.waitKey(0)

    # return the digit to the calling function
    return digit