Example #1
0
 def draw(self):
     if self.markers is not None:
         self.result[:] = self.markers
         cv2.watershed(self.img, self.result)
         img = MARKER_COLORS[self.result]
         self.draw_image(img, self.result_artist, draw=False)
         self.draw_image(self.img)
def segment_on_dt(a, img, gray):
    border = cv2.dilate(img, None, iterations=5)
    border = border - cv2.erode(border, None)


    dt = cv2.distanceTransform(img,cv2.DIST_L2,5)
    plt.subplot(3,3,4)
    plt.imshow(dt),plt.title('dt'),plt.xticks([]), plt.yticks([])

    dt = ((dt - dt.min()) / (dt.max() - dt.min()) * 255).astype(np.uint8)
    _, dt2 = cv2.threshold(dt, 0, 255, cv2.THRESH_BINARY)
    dt2 = cv2.erode(dt2, None, iterations=2)
    # dt2 = cv2.adaptiveThreshold(dt, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 5, 2)
    # dt1 = peak_local_max(gray, indices=False, min_distance=10, labels=img, threshold_abs=5)
    # dt2 = peak_local_max(dt, indices=False, min_distance=5, labels=img, threshold_abs=0)
    lbl, ncc = label(dt2)

    plt.subplot(3,3,5)
    plt.imshow(dt2),plt.title('localMax'),plt.xticks([]), plt.yticks([])
    # plt.subplot(3,3,6)
    # plt.imshow(ncc),plt.title('ncc'),plt.xticks([]), plt.yticks([])

    lbl = lbl * (255/ncc)
    # Completing the markers now.
    lbl[border == 255] = 255

    lbl = lbl.astype(np.int32)
    cv2.watershed(a, lbl)

    lbl[lbl == -1] = 0
    lbl = lbl.astype(np.uint8)

    plt.subplot(3,3,6)
    plt.imshow(lbl),plt.title('lbl_out'),plt.xticks([]), plt.yticks([])
    return 255 - lbl
    def watershed(self,image, marker):
        """
        Applies opencv's watershed method iteratively to an input image. An initial marker containing
        preliminary information on which pixels are foreground serves as additional input.
        The initial marker can be based on user input (color-picking), or can be constructed
        with an automatic marker strategy. The marker decides from which pixels the flooding
        in the watershed method may start. Finally, the marker is used to obtain a mask
        classifying every pixel into foreground or background.

        Args:
            image: An input image which is not altered
            marker: A marer suitable for use with opencv's grabcut
            iterations: The number of iterations grabcut may update the marker

        Returns:
             A mask image classifying every pixel into foreground or background
        """

        if len(marker.shape) == 3:
            marker = marker[:,:,0]

        # convert the marker to the format watershed expects
        marker = np.int32(marker)

        # Use watershed to decide how to label the yet undecided regions.
        # This may produce may foreground areas labeld with different integers.
        cv2.watershed(image, marker)

        # Obtain the final mask by thresholding. Different foreground regions have different positive values.
        # We are only intrested in global foreground so we set all of them to be white, i.e. 255.
        mask_watershed = cv2.convertScaleAbs(marker)

        return mask_watershed
Example #4
0
def watershed(image, grayed, edges, min_ratio, max_count):
    """ Applies watershed algorithm to 'image' with markers derived
        from 'edges'
    Args:
        image: original image
        grayed: grayed and optionally blurred version of 'image'
        edges: a binary image
        min_ratio: only contours in 'edges' with an area bigger are used as
                   markers
        max_count: maximum number of segments to derive
    Returns segments, markers, count
    """

    markers = edges.copy()
    _, markers1, _ = extract_segments(
        grayed,
        markers,
        min_ratio=min_ratio,
        max_count=max_count
    )
    markers32 = numpy.int32(markers1)
    cv2.watershed(image, markers32)
    watersheded = cv2.convertScaleAbs(markers32)
    _, edges = cv2.threshold(
        watersheded,
        1,
        255,
        cv2.THRESH_BINARY_INV
    )
    segments, markers, count = extract_segments(
        grayed,
        edges
    )
    return segments, markers, count
 def subtract_back(self,frm):
     #dst=self.__back__-self.__foreground__
     temp=np.zeros((config.height,config.width),np.uint8)
     
     self.__foreground__=cv2.blur(self.__foreground__,(3,3))
     dst=cv2.absdiff(self.__back__,self.__foreground__)
     
     #dst=cv2.adaptiveThreshold(dst,255,cv.CV_THRESH_BINARY,cv.CV_ADAPTIVE_THRESH_GAUSSIAN_C,5,10)
     val,dst=cv2.threshold(dst,0,255,cv.CV_THRESH_BINARY+cv.CV_THRESH_OTSU)
     
     fg=cv2.erode(dst,None,iterations=1)
     bg=cv2.dilate(dst,None,iterations=4)
     
     _,bg=cv2.threshold(bg,1,128,1)
     
     mark=cv2.add(fg,bg)
     mark32=np.int32(mark)
     #dst.copy(temp)
     
     #seq=cv.FindContours(cv.fromarray(dst),self.mem,cv.CV_RETR_EXTERNAL,cv.CV_CHAIN_APPROX_SIMPLE)
     #cntr,h=cv2.findContours(dst,cv.CV_RETR_EXTERNAL,cv.CV_CHAIN_APPROX_SIMPLE)
     #print cntr,h
     #cv.DrawContours(cv.fromarray(temp),seq,(255,255,255),(255,255,255),1,cv.CV_FILLED)
     cv2.watershed(frm, mark32)
     self.final_mask=cv2.convertScaleAbs(mark32)
def segment_on_dt(a, img):
    '''
    find foreground
    '''
    fg=cv2.dilate(img,None, iterations=5)
    fg=fg-cv2.erode(fg, None)
    dt=cv2.distanceTransform(img, 2, 3)
    
    dt=((dt-dt.min())/(dt.max()-dt.min())*255).astype(np.uint8)
   
    _, dt=cv2.threshold(dt, 0, 255, cv2.THRESH_BINARY)
    lbl, ncc=label(dt)
    lbl=lbl*(255/ncc)
    '''
    Completing the markers now
    '''
    lbl[fg==255]=255
    
    lbl=lbl.astype(np.int32)
    cv2.watershed(a, lbl)
    
    lbl[lbl==-1]=0
    lbl=lbl.astype(np.uint8)
    
    return 255-lbl
def segment_watershed(img):
    gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh=cv2.threshold(gray, 0,255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    '''
    foreground region
    '''
    fg=cv2.erode(thresh,None, iterations=2)
    '''
    background region
    '''
    bg=cv2.dilate(thresh, None,iterations=3)
    ret, bg=cv2.threshold(bg,1,128,1)
    '''
    add both fg and bg
    '''
    marker=cv2.add(fg, bg)
    '''
    convert into 32SC1
    '''
    marker32=np.int32(marker)
    '''
    apply watershed
    '''
    cv2.watershed(img, marker32)
    m=cv2.convertScaleAbs(marker32)
    '''
    threshold it properly to get the mask and perform bitwise_and with the input image
    '''
    ret, thresh=cv2.threshold(m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    result=cv2.bitwise_and(img, img,mask=thresh)
    return result
 def watershed(self):
     m = self.markers.copy()
     cv2.watershed(self.img, m)
     overlay = self.colors[np.maximum(m, 0)]
     cv2.imshow('over', overlay)
     vis = cv2.addWeighted(self.img, 0.5, overlay, 0.5, 0.0, dtype=cv2.CV_8UC3)
     cv2.imshow('watershed', vis)
 def detect_shirt2(self):
     self.hsv=cv2.cvtColor(self.norm_rgb,cv.CV_BGR2HSV)
     self.hue,s,_=cv2.split(self.hsv)
     
     _,self.dst=cv2.threshold(self.hue,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
     self.fg=cv2.erode(self.dst,None,iterations=3)
     self.bg=cv2.dilate(self.dst,None,iterations=1)
     _,self.bg=cv2.threshold(self.bg,1,128,1)
     mark=cv2.add(self.fg,self.bg)
     mark32=np.int32(mark)
     cv2.watershed(self.norm_rgb,mark32)
     
     m=cv2.convertScaleAbs(mark32)
     _,m=cv2.threshold(m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
     
     cntr,h=cv2.findContours(m,cv.CV_RETR_EXTERNAL,cv.CV_CHAIN_APPROX_SIMPLE)
     print len(cntr)
     #print cntr[0].shape
     #cntr[1].dtype=np.float32
     #ret=cv2.contourArea(np.array(cntr[1]))
     #print ret
     #cntr[0].dtype=np.uint8
     cv2.drawContours(m,cntr,-1,(255,255,255),3)
     cv2.imshow("mask_fg",self.fg)
     cv2.imshow("mask_bg",self.bg)
     cv2.imshow("mark",m)
Example #10
0
 def watershed(self):
     m = self.markers.copy()
     cv2.watershed(self.img,m)
     self.img[m == -1] = [255,0,0]
     overlay = self.colors[np.maximum(m, 0)]
     vis = cv2.addWeighted(self.img, 0.5, overlay, 0.5, 0.0, dtype=cv2.CV_8UC3)
     self.DisplayandSave('watershed', vis)
    def process(self, args):
        """
        Use the Watershed algorithm from the opencv package
        to the selected color channels of the current image.

        Args:
            | *args* : a list containing image array and Graph object
        """
        # convert image to grayscale and threshold it with the best threshold
        # value usinf otsu binarization
        image = args[0]
        im_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        ret, thresh = cv2.threshold(im_gray, 0, 255,
                                    cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        # erode will be used to create the foreground region (marked with 255)
        fg = cv2.erode(thresh, None, iterations=self.fgiter)
        # dilate will be used to reduce the background region. Black region
        # will be set to 128 and is marked as background
        bgt = cv2.dilate(thresh, None, iterations=self.bgiter)
        ret, bg = cv2.threshold(bgt, 1, 128, 1)
        # create marker with foreground and background region
        marker = cv2.add(fg, bg)
        marker32 = np.int32(marker)
        # use watershed and convert result back
        cv2.watershed(image, marker32)
        m = cv2.convertScaleAbs(marker32)
        # threshold to get the mask
        ret, thresh = cv2.threshold(m, 0, 255,
                                    cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        self.result['img'] = cv2.bitwise_and(image, image, mask=thresh)
Example #12
0
def get_fish_contour(data, cal):
    color_image = cv2.cvtColor(data.array, cv2.COLOR_GRAY2BGR)

    delta_image(data, cal)
    threshold_by_type(data)
    erode(data)
    distance_transform(data)
    threshold_by_type(data, otsu=False, thresh=5)

    markers = data.array.copy()
    dilate(data, iterations=7)
    border = data.array.copy()
    border = border - cv2.erode(border, None)

    markers, num_blobs = ndimage.measurements.label(markers)
    markers[border == 255] = 255

    markers = markers.astype(np.int32)
    cv2.watershed(image=color_image, markers=markers)
    markers[markers == -1] = 0
    markers = 255 - markers.astype(np.uint8)

    image = FFImage(markers, meta=data.meta, log=data.log)

    annotate_hu_moments(image)

    image.meta['timestamp'] = time.time()

    return image.meta
Example #13
0
def segment_on_dt(img):
    #http://stackoverflow.com/questions/11294859/how-to-define-the-markers-for-watershed-in-opencv
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)    
    _, img_bin = cv2.threshold(img_gray, 0, 255,cv2.THRESH_OTSU)
    img_bin = cv2.morphologyEx(img_bin, cv2.MORPH_OPEN,numpy.ones((3, 3), dtype=int))
    border = cv2.dilate(img_bin, None, iterations=5)
    border = border - cv2.erode(border, None)

    dt = cv2.distanceTransform(img_bin, 2, 3)
    dt = ((dt - dt.min()) / (dt.max() - dt.min()) * 255).astype(numpy.uint8)
    _, dt = cv2.threshold(dt, 180, 255, cv2.THRESH_BINARY)
    lbl, ncc = label(dt)
    lbl = lbl * (255/ncc)
    # Completing the markers now. 
    lbl[border == 255] = 255

    lbl = lbl.astype(numpy.int32)
    cv2.watershed(img, lbl)

    lbl[lbl == -1] = 0
    lbl = lbl.astype(numpy.uint8)
    result = 255 - lbl
    result[result != 255] = 0
    result = cv2.dilate(result, None)
    img[result == 255] = (0, 0, 255)
    return img
    def remove_pectoral(self, img, breast_mask, high_int_threshold=.8, 
                        morph_kn_size=3, n_morph_op=7, sm_kn_size=25):
        '''Remove the pectoral muscle region from an input image

        Args:
            img (2D array): input image as a numpy 2D array.
            breast_mask (2D array):
            high_int_threshold ([int]): a global threshold for high intensity 
                    regions such as the pectoral muscle. Default is 200.
            morph_kn_size ([int]): kernel size for morphological operations 
                    such as erosions and dilations. Default is 3.
            n_morph_op ([int]): number of morphological operations. Default is 7.
            sm_kn_size ([int]): kernel size for final smoothing (i.e. opening). 
                    Default is 25.
        Returns:
            an output image with pectoral muscle region removed as a numpy 
            2D array.
        Notes: this has not been tested on .dcm files yet. It may not work!!!
        '''
        # Enhance contrast and then thresholding.
        img_equ = cv2.equalizeHist(img)
        if high_int_threshold < 1.:
            high_th = int(img.max()*high_int_threshold)
        else:
            high_th = int(high_int_threshold)
        maxval = self.max_pix_val(img.dtype)
        _, img_bin = cv2.threshold(img_equ, high_th, 
                                   maxval=maxval, type=cv2.THRESH_BINARY)
        pect_marker_img = np.zeros(img_bin.shape, dtype=np.int32)
        # Sure foreground (shall be pectoral).
        pect_mask_init = self.select_largest_obj(img_bin, lab_val=maxval, 
                                                 fill_holes=True, 
                                                 smooth_boundary=False)
        kernel_ = np.ones((morph_kn_size, morph_kn_size), dtype=np.uint8)
        pect_mask_eroded = cv2.erode(pect_mask_init, kernel_, 
                                     iterations=n_morph_op)
        pect_marker_img[pect_mask_eroded > 0] = 255
        # Sure background - breast.
        pect_mask_dilated = cv2.dilate(pect_mask_init, kernel_, 
                                       iterations=n_morph_op)
        pect_marker_img[pect_mask_dilated == 0] = 128
        # Sure background - pure background.
        pect_marker_img[breast_mask == 0] = 64
        # Watershed segmentation.
        img_equ_3c = cv2.cvtColor(img_equ, cv2.COLOR_GRAY2BGR)
        cv2.watershed(img_equ_3c, pect_marker_img)
        img_equ_3c[pect_marker_img == -1] = (0, 0, 255)
        # Extract only the breast and smooth.
        breast_only_mask = pect_marker_img.copy()
        breast_only_mask[breast_only_mask == -1] = 0
        breast_only_mask = breast_only_mask.astype(np.uint8)
        breast_only_mask[breast_only_mask != 128] = 0
        breast_only_mask[breast_only_mask == 128] = 255
        kernel_ = np.ones((sm_kn_size, sm_kn_size), dtype=np.uint8)
        breast_only_mask = cv2.morphologyEx(breast_only_mask, cv2.MORPH_OPEN, 
                                            kernel_)
        img_breast_only = cv2.bitwise_and(img_equ, breast_only_mask)

        return (img_breast_only, img_equ_3c)
Example #15
0
    def split(self):
        """Split the region according to the normalized cut criterion.

        Returns
        -------
        list of CutRegion
            The regions created by splitting.
        float
            The normalized cut cost.
        """
        if not cv2_available:
            raise ImportError('OpenCV >= 2.4.8 required')
        tmp_im = np.zeros(self.shape[0] * self.shape[1])
        tmp_im[self.indices] = 1
        labeled_array, num_features = ndimage.label(tmp_im.reshape(self.shape))
        if num_features > 1:
            labeled_array = labeled_array.reshape(-1)[self.indices]
            segments = []
            for i in range(1, num_features + 1):
                idx = np.nonzero(labeled_array == i)[0]
                segments.append(CutRegion(self.affinity_matrix[idx, :][:, idx],
                                          self.indices[idx], self.shape))
            return segments, 0.0

        C = normcut_vectors(self.affinity_matrix, 1)
        im = C[:, -2]
        im -= im.min()
        im /= im.max()
        markers = -np.ones(self.shape[0] * self.shape[1]).astype('uint16')
        markers[self.indices] = 0
        markers[self.indices[im < 0.02]] = 1
        markers[self.indices[im > 0.98]] = 2
        markers = markers.reshape(self.shape)
        vis2 = 0.5 * np.ones(self.shape[0] * self.shape[1])
        vis2[self.indices] = im
        vis2 *= (2 ** 8 - 1)
        vis2 = cv2.cvtColor(np.uint8(vis2.reshape(self.shape)),
                            cv2.COLOR_GRAY2BGR)
        markers = np.int32(markers)
        cv2.watershed(vis2, markers)
        cut = ndimage.morphology.binary_dilation(markers == 2).reshape(-1)[
            self.indices]
        cut[im > 0.98] = True
        cost = self._normalized_cut_cost(cut)
        for thresh in np.linspace(0, 1, 20)[1:-1]:
            tmp_cut = im > thresh
            tmp_cost = self._normalized_cut_cost(tmp_cut)
            if tmp_cost < cost:
                cost = tmp_cost
                cut = tmp_cut
        a = cut.nonzero()[0]
        a = cut.nonzero()[0]
        b = np.logical_not(cut).nonzero()[0]

        return (
            [CutRegion(self.affinity_matrix[x, :][:, x], self.indices[x],
                       self.shape) for x in [a, b] if len(x)],
            self._normalized_cut_cost(cut)
        )
Example #16
0
def watershed(image, marker):
    m = marker.copy()
    cv2.watershed(image, m)
    m[m != 1] = 0
    m *= 255
    points = cv2.findNonZero(m.astype(np.uint8))
    bound_rect = cv2.boundingRect(points)
    # x, y, w, h = bound_rect
    return bound_rect
Example #17
0
def watershed(img, marker, device, debug):
  # Uses the watershed algorithm to detect boundry of objects
  # Needs a marker file which specifies area which is object (white), background (grey), unknown area (black)
  # img = image to perform watershed on needs to be 3D (i.e. np.shape = x,y,z not np.shape = x,y)
  # marker = a 32-bit image file that specifies what areas are what (2D, np.shape = x,y)
  cv2.watershed(img, marker)
  device += 1
  if debug:
    print_image(marker, str(device) + 'watershed_img' + '.png')
  return device, marker
Example #18
0
def segment_watershed(image, window=None):
    """Segments an image using watershed technique.

    Parameters
    ----------
    image : (M, N, 3) array
        Image to process.
    window : tuple, (x, y, w, h)
        Optional subwindow in image.

    Returns
    -------
    (rects, display) : list, (M, N, 3) array
        Region results and visualization image.
    """
    import cv2
    import numpy as np

    if window:
        subimage = np.array(image)
        x, y, w, h = window
        image = subimage[y:y + h, x:x + w]
    rects, display = segment_edges(image, variance_threshold=100,
                                   size_filter=0)
    h, w = image.shape[:2]
    initial = np.zeros((h, w), np.int32)
    for i, rect in enumerate(rects):
        cv2.drawContours(initial, [rect[4]], -1, 1, -1)
    display = np.zeros(initial.shape, dtype=np.uint8)

    segment_rects = []
    for i, rect in enumerate(rects):
        regions = np.zeros(initial.shape, dtype=np.uint8)
        cv2.drawContours(regions, [rect[4]], -1, 2, -1)
        regions = cv2.erode(regions, None)
        regions = cv2.erode(regions, None)
        markers = initial.copy()
        markers[regions == 2] = 2
        cv2.watershed(image, markers)
        display[markers == 2] = 255
        contours, hierarchy = _find_contours(regions.copy(),
                                             cv2.RETR_EXTERNAL,
                                             cv2.CHAIN_APPROX_SIMPLE)
        segment_rects.extend([cv2.boundingRect(c) for c in contours])

    if window:
        new_rects = []
        for rect in segment_rects:
            dx, dy = 0, 0
            new_rect = (rect[0] + x - dx, rect[1] + y - dy,
                        rect[2] + 2 * dx, rect[3] + 2 * dy)
            new_rects.append(new_rect)
        segment_rects = new_rects
    return segment_rects, np.dstack(3 * [display])
Example #19
0
def segment_on_dt(img):
    dt = cv2.distanceTransform(img, 2, 3) # L2 norm, 3x3 mask
    dt = ((dt - dt.min()) / (dt.max() - dt.min()) * 255).astype(numpy.uint8)
    dt = cv2.threshold(dt, 100, 255, cv2.THRESH_BINARY)[1]
    lbl, ncc = label(dt)

    lbl[img == 0] = lbl.max() + 1
    lbl = lbl.astype(numpy.int32)
    cv2.watershed(cv2.cvtColor(img, cv2.COLOR_GRAY2BGR), lbl)
    lbl[lbl == -1] = 0
    return lbl
def get_keys_from_markers(img, markers_list):
 
    #make the markers in the format required by the algorithm
    h, w = img.shape[:2]
    markers_array = np.zeros((h, w), np.int32)
    boundary = 0
    for i, mark in enumerate(markers_list):
 
        markers_array[mark[1]][mark[0]] = i+1
        boundary +=1
    cv2.watershed(img, markers_array)
    return markers_array, boundary
Example #21
0
  def remove_bg(self):

    gray = cv2.cvtColor(self.img,cv2.COLOR_BGR2GRAY)
    ret,thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    fg = cv2.erode(thresh,None,iterations = 2)
    bgt = cv2.dilate(thresh,None,iterations = 3)
    ret,bg = cv2.threshold(bgt,1,128,1)
    marker = cv2.add(fg,bg)
    marker32 = np.int32(marker)
    cv2.watershed(self.img,marker32)
    m = cv2.convertScaleAbs(marker32)
    self.nobg_img = cv2.threshold(m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
    return self.nobg_img
 def method2(self, image):
     gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
     ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)
     fg = cv2.erode(thresh,None,iterations = 2)        
     bgt = cv2.dilate(thresh,None,iterations = 3)
     ret,bg = cv2.threshold(bgt,1,128,1)
     marker = cv2.add(fg,bg)
     marker32 = np.int32(marker)
     cv2.watershed(image,marker32)
     m = cv2.convertScaleAbs(marker32)
     ret,thresh = cv2.threshold(m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
     res = cv2.bitwise_and(image,image,mask = thresh)        
     return res
Example #23
0
def find_optic_disc_watershed(img, P):
    """
    Find optic disk in image using a watershed method.

    :param img: BGR image
    :param P: gray image
    :return: optic_disc, Crs, markers, watershed
    """
    assert img is not None and P is not None
    #fore = cv2.cvtColor(P,cv2.COLOR_GRAY2BGR)
    # create watershed
    data_min, data_body_left, data_body, data_max_left = retina_markers_thresh(
        P)
    watershed = np.zeros_like(P).astype("int32")
    mk_back, mk_body, mk_flare = 1, 2, 3
    # background FIXMED use P.min() and aproaching to local maxima
    watershed[P <= data_min] = mk_back
    watershed[np.bitwise_and(P > data_body_left, P <
                             data_body)] = mk_body  # main body
    # find bright objects
    flares_thresh = (P >= data_max_left).astype(np.uint8)
    contours, hierarchy = findContours(
        flares_thresh.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    mks_flare = []
    for i, cnt in enumerate(contours):
        index = mk_flare + i
        mks_flare.append(index)
        # Flares. this can be used approaching
        watershed[contours2mask(cnt, shape=watershed.shape)] = index
        # to local maxima, but brightest areas are almost
        # always saturated so no need to use it
    markers = watershed.copy()
    # apply watershed to watershed
    # FIXME perhaps the function should be cv2.floodFill?
    cv2.watershed(img, watershed)

    # different classification algorithms could be used using watershed
    contours_flares = []
    for mk_flare in mks_flare:
        brightest = np.uint8(watershed == mk_flare)
        contours, hierarchy = findContours(
            brightest, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
        contours_flares.extend(contours)
    Crs = [(i, j) for i, j in [(convexityRatio(cnt), cnt)
                               for cnt in contours_flares] if i != 0]  # convexity ratios
    Crs.sort(reverse=True, key=lambda x: x[0])
    candidate = Crs[-1]
    ellipse = cv2.fitEllipse(candidate[1])
    optic_disc = np.zeros_like(P)
    cv2.ellipse(optic_disc, ellipse, 1, -1)  # get elliptical ROI
    return optic_disc, Crs, markers, watershed
Example #24
0
def WATERSHED(Input_Image):
    '''
    Description:    Computes watershed segmentation,based on mathematical morphology and flooding of regions from markers.

    source:         openCV 
    
    parameters:     Input_Image : ndarray
                    Input image
    
                   marker: float
                
    return:         Segment_mask : ndarray (cols, rows)
                    Integer mask indicating segment labels.
    '''   
    # read the input image
    img = cv2.imread(Input_Image)
    
    # convert to grayscale
    g1 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    # smooth the image 
    g = cv2.medianBlur(g1,5)

    # Apply adaptive threshold
    thresh1 = cv2.adaptiveThreshold(g,255,1,1,11,2)
    thresh_color = cv2.cvtColor(thresh1,cv2.COLOR_GRAY2BGR)

    # Apply  dilation and erosion 
    bgt = cv2.dilate(thresh1,None,iterations = 3)
    fg = cv2.erode(bgt,None,iterations = 2)
    
    #thresholding on the background
    ret,bg = cv2.threshold(bgt,1,128,1)
    
    #adding results
    marker = cv2.add(fg,bg)
    
    #moving markers to 32 bit signed single channel
    marker32 = np.int32(marker)
    
    #segmenting
    cv2.watershed(img,marker32)
    m = cv2.convertScaleAbs(marker32)

    ret,thresh = cv2.threshold(m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    res = cv2.bitwise_and(img,img,mask = thresh)
    segments_watershed = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)
    print("watershed number of segments: %d" % len(np.unique(segments_watershed)))
    segments_watershed = segments_watershed.astype(np.int32)
    #print ('segments_watershed datatype',segments_watershed.dtype )
    return segments_watershed
def watershed(img, fg_marker):
    fg_marker = cv2.dilate(fg_marker, None, iterations=5)
    r, bg_marker = cv2.threshold(cv2.bitwise_not(cv2.dilate(fg_marker, None, iterations=10)), 30, 125, cv2.THRESH_BINARY)
    marker = cv2.add(fg_marker, bg_marker, dtype=cv2.CV_32SC1)
    cv2.imwrite('step7-markers.png', marker)

    color = numpy.zeros((480, 640, 3), numpy.uint8)
    color[:,:,0] = img
    color[:,:,1] = img
    color[:,:,2] = img
    cv2.watershed(color, marker)

    cv2.imwrite('step7-watersheds.png', marker)
    return marker
def watershed_segmentation(bbox, image, rgb_proposal_mask, depth_proposal_mask, bbox_not_moved, watershed_last_frame_seed_mask):
    # segmentation
    watershed_mask_seed = create_watershed_seed(bbox, rgb_proposal_mask, bbox_not_moved, watershed_last_frame_seed_mask)
    watershed_bg_mask = rgb_proposal_mask + depth_proposal_mask

    # set the background to 1 the luggage pixel to the values found before
    # the unknown pixel are still 0
    #watershed_mask_seed = np.where(watershed_bg_mask == 0, 1, watershed_mask_seed)
    watershed_mask_seed += 1
    # apply watershed - result overwrite in mask
    cv2.watershed(image, watershed_mask_seed)

    # OUTPUT MASK FOR FURTHER STUDY
    return np.where(watershed_mask_seed == 1, 0, 1)
def watershed(img, thresh):
    # noise removal
    kernel = np.ones((3,3), np.uint8)
    opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 4)

    # sure background area
    sure_bg = cv2.dilate(opening,kernel,iterations=3)

    #sure_bg = cv2.morphologyEx(sure_bg, cv2.MORPH_TOPHAT, kernel)

    # Finding sure foreground area
    dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
    ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)

    # Finding unknown region
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg,sure_fg)

    # Marker labelling
    ret, markers = cv2.connectedComponents(sure_fg)

    # Add one to all labels so that sure background is not 0, but 1
    markers = markers+1

    # Now, mark the region of unknown with zero
    markers[unknown==255] = 0
    '''
    imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    imgray = cv2.GaussianBlur(imgray, (5, 5), 0)
    img = cv2.Canny(imgray,200,500)
    '''
    markers = cv2.watershed(img,markers)
    img[markers == -1] = [255,0,0]

    return sure_bg, sure_fg
Example #28
0
def water(img, thresh):
    kernel = np.ones((3,3),np.uint8)
    opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)

    # sure background area
    sure_bg = cv2.dilate(opening,kernel,iterations=3)

    # Finding sure foreground area
    dist_transform = cv2.distanceTransform(opening,2,5)
    ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)

    # Finding unknown region
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg,sure_fg)

    # Marker labelling
    ret, markers = cv2.connectedComponents(sure_fg)

    # Add one to all labels so that sure background is not 0, but 1
    markers += 1

    # Now, mark the region of unknown with zero
    markers[unknown==255] = 0

    markers = cv2.watershed(img,markers)
    img[markers == -1] = [255,0,0]
    return sure_fg, sure_bg, markers, img
Example #29
0
def Segmentation(image):
    height, width = image.shape[0], image.shape[1]
    temperatureImg = getTemperatureImg(image)
    averTemperature = temperatureImg.sum() / (height * width)
    data = cv2.calcHist([temperatureImg], [0], None, [256], [0, 255])
    threshold = OSTU(data)
    _, img = cv2.threshold(temperatureImg, 1.2 * threshold, 255, cv2.THRESH_BINARY)
    fg = cv2.erode(img, None, iterations = 5)
    _, img = cv2.threshold(temperatureImg, 0.8 * threshold, 255, cv2.THRESH_BINARY)
    _, bg = cv2.threshold(cv2.dilate(img, None, iterations = 3), 1, 128, cv2.THRESH_BINARY_INV)
    marker = cv2.add(fg, bg)
    markers = np.int32(marker)
    # in markers 255 is colorfulcolor, 128 is other, -1 is boundary
    tpImg = np.rollaxis(np.array([temperatureImg] * 3), 0, 3)
    cv2.watershed(np.array(tpImg, dtype='uint8'), markers)
    return (markers, temperatureImg)
Example #30
0
def watershed2(seem, img):

    if (img.dtype != np.uint8):
        img = img * 255
        img = np.uint8(img)
    ut.imgDes(img)
    img = cv.medianBlur(img, 3)

    rows, cols = img.shape[:2];

    if np.size(img.shape) < 3:
        img_a = cv.cvtColor(img, cv.COLOR_GRAY2RGB)
    else:
        img_a = img
    print ('ddd')
    ut.imgDes(img_a)
    ret, markers = cv.connectedComponents(seem)
    markers = markers + 1
    markers[seem == 0] = 0
    markers = cv.watershed(img_a, markers)
    markers[img==0] = 0



    return  markers
Example #31
0
        cv2.circle(markedImg, pt, 9, (colorMark), -1)
        cv2.circle(scene, pt, 9, colorPallet[colorMark], -1)
        changedMark = True


changedMark = False
colorPallet = getColorPallet(10)
cv2.namedWindow("img", cv2.WINDOW_AUTOSIZE)
cv2.setMouseCallback("img", creatRoots)

colorMark = 0
while True:
    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break
    elif chr(key).isdigit():
        colorMark = eval(chr(key))
        print(chr(key), colorMark)

    if changedMark:
        copied_markedImg = markedImg.copy()
        cv2.watershed(srcImg, copied_markedImg)
        segments = np.zeros_like(srcImg, np.uint8)
        for clrIndex in range(len(colorPallet)):
            segments[copied_markedImg == (clrIndex)] = colorPallet[clrIndex]

    cv2.imshow("img", scene)
    cv2.imshow("segments", segments)

cv2.destroyAllWindows()
Example #32
0
def post_process(q=-5):
    nc_logits = np.squeeze(
        np.squeeze(
            np.load(r'E:\MoNUSAC\MyModel\prediction\nc_logits.npy',
                    allow_pickle=True)))
    nc_target = np.squeeze(
        np.squeeze(
            np.load(r'E:\MoNUSAC\MyModel\prediction\nc_target.npy',
                    allow_pickle=True)))
    np_logits = np.squeeze(
        np.squeeze(
            np.load(r'E:\MoNUSAC\MyModel\prediction\np_logits.npy',
                    allow_pickle=True)))
    hv_logits = np.squeeze(
        np.load(r'E:\MoNUSAC\MyModel\prediction\hv_logits.npy',
                allow_pickle=True))
    image = np.squeeze(
        np.load(r'E:\MoNUSAC\MyModel\prediction\image.npy', allow_pickle=True))
    image = image.transpose((1, 2, 0))
    image2 = image.copy()
    image2 += 60 * cv2.merge([
        np.where(nc_target == 1, 1, 0),
        np.where(nc_target == 2, 2, 0) + np.where(nc_target == 4, 4, 0),
        np.where(nc_target == 3, 3, 0) + np.where(nc_target == 4, 4, 0)
    ])
    cv2.imshow('target', image2)
    # cv2.imshow('h',np.squeeze(hv_logits[0,...]).astype(np.float))
    h, v = cv2.Sobel(np.squeeze(hv_logits[0, :, :]),
                     ddepth=-1,
                     dx=1,
                     dy=0,
                     ksize=3), cv2.Sobel(np.squeeze(hv_logits[1, :, :]),
                                         ddepth=-1,
                                         dx=0,
                                         dy=1,
                                         ksize=3)
    # show_('h',h)
    # show_('v',v)
    # cv2.imshow('H', h.astype(np.float))
    # cv2.imshow('V', v.astype(np.float))
    Sm = np.where(h < v, h, v)
    t = np.argmax(np_logits, axis=0)
    # t=np_logits
    # cv2.imshow('sm', Sm.astype(np.float))
    # show_('Sm',Sm)

    tmp = t - np.where(Sm < q, 1, 0)
    tmp = np.where(tmp > 0, 1, 0)

    # cv2.imshow('tmp',tmp.astype(np.uint8)*255)
    sure_bg = 1 - t
    sure_fg = tmp
    unkown = 1 - sure_bg - sure_fg
    _, markers = cv2.connectedComponents(sure_fg.astype(np.uint8))
    markers = markers + 1
    markers[sure_bg == 1] = 0
    # cv2.imshow('mark',markers.astype(np.uint8))
    img = cv2.distanceTransform(t.astype(np.uint8), cv2.DIST_L2,
                                cv2.DIST_MASK_3)
    img = (np.max(img) - img) / (np.max(img) - np.min(img)) * 255
    img = img.astype(np.uint8)
    img = cv2.merge([img, img, img])
    # cv2.imshow('img',img)
    markers = cv2.watershed(img, markers)
    m = np.zeros((256, 256))
    nc_logits = np.argmax(nc_logits, axis=0)
    for i in np.unique(markers).tolist():
        if i > 2:
            temp = markers.copy()
            temp = np.where(temp == i, 1, 0)
            temp = temp * nc_logits
            maxs = 0
            maxc = 0
            for j in np.unique(temp).tolist():
                if j > 0:
                    temp2 = np.where(temp == j, 1, 0)
                    s = np.sum(temp2)
                    if s > maxs:
                        maxs = s
                        maxc = j
            m += np.where(markers == i, maxc, 0)

    image += 60 * cv2.merge([
        np.where(m == 1, 1, 0),
        np.where(m == 2, 2, 0) + np.where(m == 4, 4, 0),
        np.where(m == 3, 3, 0) + np.where(m == 4, 4, 0)
    ])
    image[markers == -1] = [0, 0, 255]
    cv2.imshow('img', image)
    cv2.waitKey(0)
Example #33
0
def boundary_refinement_watershed(X, Y_pred, erode=True, save_marks_dir=None):
    """Apply watershed to the given predictions with the goal of refine the 
       boundaries of the artifacts.

       Based on https://docs.opencv.org/master/d3/db4/tutorial_py_watershed.html.

       Parameters
       ----------
       X : 4D Numpy array
           Original data to guide the watershed. E.g. ``(img_number, x, y, channels)``.

       Y_pred : 4D Numpy array
           Predicted data to refine the boundaries. E.g. ``(img_number, x, y, channels)``.

       erode : bool, optional
           To extract the sure foreground eroding the artifacts instead of doing 
           with distanceTransform.  

       save_marks_dir : str, optional
           Directory to save the markers used to make the watershed. Useful for 
           debugging. 

       Returns
       -------
       Array : 4D Numpy array
           Refined boundaries of the predictions. E.g. ``(img_number, x, y, channels)``.
        
       Examples
       --------
        
       +-----------------------------------------+-----------------------------------------+
       | .. figure:: img/FIBSEM_test_0.png       | .. figure:: img/FIBSEM_test_0_gt.png    |
       |   :width: 80%                           |   :width: 80%                           |
       |   :align: center                        |   :align: center                        |
       |                                         |                                         |
       |   Original image                        |   Ground truth                          |
       +-----------------------------------------+-----------------------------------------+
       | .. figure:: img/FIBSEM_test_0_pred.png  | .. figure:: img/FIBSEM_test_0_wa.png    |
       |   :width: 80%                           |   :width: 80%                           |
       |   :align: center                        |   :align: center                        |
       |                                         |                                         |
       |   Predicted image                       |   Watershed ouput                       |
       +-----------------------------------------+-----------------------------------------+

       The marks used to guide the watershed is this example are these:

        .. image:: img/watershed2_marks_test0.png
          :width: 70% 
          :align: center 
    """

    if save_marks_dir is not None:
        os.makedirs(save_marks_dir, exist_ok=True)

    watershed_predictions = np.zeros(Y_pred.shape[:3])
    kernel = np.ones((3, 3), np.uint8)
    d = len(str(X.shape[0]))

    for i in tqdm(range(X.shape[0])):
        im = cv2.cvtColor(X[i, ...] * 255, cv2.COLOR_GRAY2RGB)
        pred = Y_pred[i, ..., 0]

        # sure background area
        sure_bg = cv2.dilate(pred, kernel, iterations=3)
        sure_bg = np.uint8(sure_bg)

        # Finding sure foreground area
        if erode:
            sure_fg = cv2.erode(pred, kernel, iterations=3)
        else:
            dist_transform = cv2.distanceTransform(a, cv2.DIST_L2, 5)
            ret, sure_fg = cv2.threshold(dist_transform,
                                         0.7 * dist_transform.max(), 255, 0)
        sure_fg = np.uint8(sure_fg)

        # Finding unknown region
        unknown_reg = cv2.subtract(sure_bg, sure_fg)

        # Marker labelling
        ret, markers = cv2.connectedComponents(sure_fg)

        # Add one to all labels so that sure background is not 0, but 1
        markers = markers + 1

        # Now, mark the region of unknown with zero
        markers[unknown_reg == 1] = 0

        if save_marks_dir is not None:
            f = os.path.join(save_marks_dir,
                             "mark_" + str(i).zfill(d) + ".png")
            cv2.imwrite(f, markers)

        markers = cv2.watershed((im).astype(np.uint8), markers)

        watershed_predictions[i] = markers

    # Label all artifacts into 1 and the background with 0
    watershed_predictions[watershed_predictions == 1] = 0
    watershed_predictions[watershed_predictions > 1] = 1
    watershed_predictions[watershed_predictions == -1] = 0

    return np.expand_dims(watershed_predictions, -1)
Example #34
0
cv2.namedWindow('Road Image')
cv2.setMouseCallback('Road Image', mouse_callback)

while True:
    cv2.imshow('Watershed Segments', segments)
    cv2.imshow('Road Image', road_copy)

    k = cv2.waitKey(1)
    if k == 27:
        break

    elif k == ord('c'):
        road_copy = road.copy()
        marker_image = np.zeros(road.shape[:2], dtype=np.int32)
        segments = np.zeros(road.shape, dtype=np.uint8)

    elif k > 0 and chr(k).isdigit():
        current_marker = int(chr(k))

    if marks_updated:
        marker_image_copy = marker_image.copy()
        cv2.watershed(road, marker_image_copy)
        segments = np.zeros(road.shape, dtype=np.uint8)

        for color_ind in range(n_markers):
            segments[marker_image_copy == (color_ind)] = colors[color_ind]

        marks_updated = False

cv2.destroyAllWindows()
Example #35
0
    sx = np.min(ind[0]) - border_width
    ex = np.max(ind[0]) + border_width
    sy = np.min(ind[1]) - border_width
    ey = np.max(ind[1]) + border_width

    # distance transform
    one_comp = oldmarkers[sx:ex, sy:ey] == i
    compon_dis = cv2.distanceTransform(one_comp.astype(np.uint8), cv2.DIST_L2,
                                       5)
    _, dis_peak = cv2.threshold(compon_dis, 0.75 * compon_dis.max(), 255, 0)

    # watershed
    ret, new_markers = cv2.connectedComponents(dis_peak.astype(np.uint8))
    new_markers = new_markers + 1
    new_markers[(one_comp == True) & (new_markers == 1)] = 0
    water = cv2.watershed(img[sx:ex, sy:ey], new_markers.copy())

    # draw
    for j in range(2, ret + 1):
        c = cv2.findContours(np.uint8(water == j), cv2.RETR_EXTERNAL,
                             cv2.CHAIN_APPROX_SIMPLE)[1]
        if len(c):
            c = c[0]
        else:
            continue
        c[:, 0, 0] += sy
        c[:, 0, 1] += sx
        # cv2.drawContours(img, [c], -1, (0, 0, 255), 5)
        mm = 20
        minx = np.min(c[:, 0, 0]) - mm
        maxx = np.max(c[:, 0, 0]) + mm
Example #36
0
D2 = ndi.distance_transform_edt(fat_markers)
dist_binary2 = D2 > dt_t
dist_binary2 = dist_binary2.astype(np.float)
# plt.figure();plt.imshow(dist_binary2)
dist_binary2_ = morphology.remove_small_holes(
    util.pad(dist_binary2, (1, ), 'constant',
             constant_values=0).astype(np.int), 300)
dist_binary2_ = dist_binary2_[1:-1, 1:-1]
# plt.figure();plt.imshow(dist_binary2_)

sure_fg = dist_binary1_.astype(np.float) * dist_binary2_.astype(np.float)

sure_fgo = morphology.binary_opening(sure_fg, morphology.disk(5))

unknown = np.maximum(sure_bg - sure_fgo, 0)

markers = measure.label(sure_fgo, background=0)
markers += 1
markers[unknown == 1] = 0
# plt.figure();plt.imshow(markers, cmap=cmap)

imgc_ = np.uint8(imgc * 255.)
labels = cv2.watershed(imgc_, markers)

plt.figure()
plt.imshow(labels.get(), cmap=cmap)
imgc_overlay = imgc
imgc_overlay[labels.get() == -1] = [1, 0, 0]
plt.figure()
plt.imshow(imgc_overlay)
#######################################################################
fg = compare(road_lbp, sample=(880, 100), high=64, width=32, condi=0.84)
# print(np.unique(fg, return_counts=True))
cv2.imshow("fg", fg)

# watershed
blur = cv2.GaussianBlur(gray, (5, 5), 0)
_, thres = cv2.threshold(blur, 0, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY_INV)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
mb = cv2.morphologyEx(thres, cv2.MORPH_OPEN, kernel, iterations=2)
bg = cv2.dilate(mb, kernel, iterations=3)
# cv2.imshow("bg", bg)

unknown = cv2.subtract(bg, fg)
_, markers = cv2.connectedComponents(fg)
# print(np.unique(markers, return_counts=True))
markers = cv2.watershed(road, markers=markers)
# markers = markers + 1
# markers[unknown == 255] = 4
road[markers == -1] = [0, 0, 0]
# print(road[markers == 1])
# cv2.imshow("watershed", road)

# draw
color_block = np.zeros(road.shape, dtype=np.uint8)
color_block[markers == 0] = [255, 255, 255]
color_block[markers == 1] = [191,  62, 255]
color_block[markers == 2] = [130, 130, 130]
color_block[markers == 3] = [152, 251, 152]
# cv2.imshow("color_block", color_block)

# result
Example #38
0
def getWatershed(data, w):
    height = np.array(data)
    image = np.zeros(height.shape)
    for i in range(len(data)):
        for j in range(len(data[0])):
            height[i][j] = data[i][j].elevation
    maximum = np.amax(height)
    minimum = np.amin(height)
    numberOfBits = 16
    interval = (maximum - minimum) / (pow(2, numberOfBits) - 1)
    for i in range(len(height)):
        for j in range(len(height[0])):
            image[i][j] = int(data[i][j].getRisk(minimum, maximum) *
                              (pow(2, numberOfBits) - 1))

    image = image.astype('uint8') * 255
    cv2.imshow("w", resizeimage(image, 1000))
    cv2.waitKey(0)

    # image = cv2.bitwise_not(image)
    # image = resizeimage(image, 1000)
    image3 = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)

    ret, thresh = cv2.threshold(image, 0, 255,
                                cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

    # noise removal
    kernel = np.ones((3, 3), np.uint8)

    # sure background area
    sure_bg = cv2.dilate(thresh, kernel, iterations=3)

    # Finding sure foreground area
    dist_transform = cv2.distanceTransform(thresh, cv2.DIST_L2, 5)
    ret, sure_fg = cv2.threshold(dist_transform, 0.3 * dist_transform.max(),
                                 255, 0)

    # Finding unknown region
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg, sure_fg)

    # Marker labelling
    ret, markers = cv2.connectedComponents(sure_fg)

    # Add one to all labels so that sure background is not 0, but 1
    markers = markers + 1

    # Now, mark the region of unknown with zero
    markers[unknown == 255] = 0
    markers = cv2.watershed(image3, markers)
    diff = []
    for m in markers:
        for a in m:
            if not a in diff:
                diff.append(a)

    image3[markers == -1] = [255, 0, 0]

    # Map to store region wise location objects
    regions = getRegions(markers, data)

    # Map to store region boundary location objects
    regionBoundary = findboundary2(markers, data)

    # Map to store regions and there relative sizes
    sizeFactor = {}

    # Size list
    sizeList = {}

    # Map to Store Average Depths
    avgDepth = {}

    # Map to store the centers of the regions
    centers = {}
    maxSize = 0
    for k in regions:
        # Find maximum size region
        if k not in sizeFactor:
            sizeFactor[k] = float(len(regions[k]))
            maxSize = max(maxSize, sizeFactor[k])
        sizeList[k] = len(regions[k])

        # Find the center of the region i,e, the minimum depth region
        minDepth = regions[k][0]

        # Depth wise classification
        depthSum = 0
        for val in regions[k]:
            if minDepth.elevation > val.elevation:
                minDepth = val
            depthSum = depthSum + val.elevation
        centers[k] = minDepth

        # Normalise the depth
        avgDepth[k] = depthSum / len(regions[k])
    # Normalize the size factors with respect to greatest size region
    for k in sizeFactor:
        sizeFactor[k] = sizeFactor[k] / maxSize

    maxDepth = avgDepth[list(avgDepth.keys())[0]]
    for k in avgDepth:
        maxDepth = max(maxDepth, avgDepth[k])
    for k in avgDepth:
        avgDepth[k] = avgDepth[k] / maxDepth

    factor1 = 0.5
    factor2 = 0.5
    riskFactor = {}
    for k in regions:
        riskFactor[k] = factor1 * (1 - avgDepth[k]) + factor2 * sizeFactor[k]
    riskObjects = []
    rs = []
    for k in regions:
        if k == -1:
            continue
        risk = riskFactor[k]
        area = pow((pow(sizeList[k], 0.5) * w) / 1000, 2)
        riskObjects.append(
            RiskMapRegion(centers[k], regionBoundary[k], risk, area))
        # rs.append((-risk, -area, k))

    # rs.sort()
    # rss = rs[:w]
    # rb = {}
    # for r in rss:
    #     rb[r[2]] = regionBoundary[r[2]]

    # print("YO")
    # sb = sort_boundaries(rb, data)
    # for r in rss:
    #     riskObjects.append(RiskMapRegion(centers[r[2]],sb[r[2]],risk,area))

    return sorted(riskObjects, key=func)
Example #39
0
def find_contours(image):
    # Conversion to HSV space and taking the saturation channel
    hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
    img = cv.split(hsv)[1]
    # cv.imwrite("0_saturation.png", img)

    # Thresholding
    _, dst = cv.threshold(img, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
    # cv.imwrite("1_thresholded.png", dst)

    # Mask borders
    b_mask = borders_mask(image)
    # cv.imwrite("2_borders_mask.png", b_mask)

    dst = cv.bitwise_and(dst, b_mask)

    # Finding contours to remove holes
    contours, _ = cv.findContours(dst, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)
    # tmp = np.zeros((400, 600), dtype=np.uint8)
    # cv.drawContours(tmp, contours, -1, (255, 255, 255), -1, 4)
    # cv.imwrite("3_unfiltered_cc.png", tmp)
    final = None
    final_ref = 1.0
    for c in contours:
        area = cv.contourArea(c)
        perimeter = cv.arcLength(c, True)
        circ = circularity(area, perimeter)
        if area > 400 and circ < 0.8:
            if area > final_ref:
                final = c
                final_ref = area

    mask = np.zeros((400, 600), dtype=np.uint8)
    if final is not None:
        cv.drawContours(mask, [final], -1, (255, 255, 255), -1, 4)
        # cv.imwrite("4_final_mask.png", mask)

    ### WATERSHED START
    ## FOREGROUND
    # Distance transform and thresholding
    fg = cv.distanceTransform(mask, cv.DIST_L2, cv.DIST_MASK_PRECISE)
    fg_min = np.amin(fg)
    fg_max = np.amax(fg)
    fg[:] = (fg - fg_min) * 255 // (fg_max - fg_min)
    fg = np.uint8(fg)
    _, fg = cv.threshold(fg, 100, 255, cv.THRESH_BINARY)

    ## BACKGROUND
    bg = cv.dilate(mask, None, iterations=4)
    bg[bg == 0] = 128
    bg[bg == 255] = 0

    ## MARKERS
    markers = cv.add(fg, bg)
    # cv.imwrite("5_watershed_mask.png", markers)
    markers32 = np.int32(markers)

    cv.watershed(image, markers32)
    w_mask = cv.convertScaleAbs(markers32)
    # cv.imwrite("6_watershed_mask.png", w_mask)
    w_mask[w_mask == 128] = 0
    w_mask[w_mask == 1] = 255
    w_mask[0, :] = 0
    w_mask[w_mask.shape[0] - 1, :] = 0
    w_mask[:, 0] = 0
    w_mask[:, w_mask.shape[1] - 1] = 0
    # cv.imwrite("7_final_result.png", w_mask)

    return w_mask
Example #40
0
def bottleCapDetect(img):
    scale_factor = min(1024 / img.shape[0], 768 / img.shape[1], 1)
    img = cv2.resize(img, (0, 0), fx=scale_factor, fy=scale_factor)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    edge_threshold = 10
    edeg_threahold_max = 2 * edge_threshold
    blurred = cv2.medianBlur(gray, 3)
    edges = cv2.Canny(blurred,
                      edge_threshold,
                      edeg_threahold_max,
                      apertureSize=3)
    struct_ele = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
    edges_closed = edges.copy()
    edges_closed = cv2.morphologyEx(edges_closed,
                                    cv2.MORPH_DILATE,
                                    struct_ele,
                                    iterations=1)
    edges_closed = cv2.morphologyEx(edges_closed,
                                    cv2.MORPH_CLOSE,
                                    struct_ele,
                                    iterations=5)
    mask = np.zeros((edges_closed.shape[0] + 2, edges_closed.shape[1] + 2),
                    dtype="uint8")
    cv2.floodFill(edges_closed,
                  mask, (0, 0),
                  255,
                  flags=cv2.FLOODFILL_MASK_ONLY)[1]
    mask[...] = 255 * (1 - mask)
    cap_cnt = 10

    def get_markers(mask_orig):
        mask = mask_orig.copy()
        cnt = 0
        result = []
        while cnt < cap_cnt:
            mask = cv2.medianBlur(mask, 9)
            # do distance transform
            dist = cv2.distanceTransform(mask, cv2.DIST_L2, 5)
            dist = dist.astype("uint8")
            ret, markers_binary = cv2.threshold(dist, 0.8 * dist.max(), 255, 0)
            # do marker labelling
            ret, markers = cv2.connectedComponents(markers_binary)
            cur_cnt = markers.max()
            print("Got", cur_cnt, "marker(s)")
            cnt += cur_cnt
            cur_result = []
            for i in range(1, cur_cnt + 1):
                pos = np.nonzero(markers == i)
                x, y = pos[1], pos[0]
                minx, maxx, miny, maxy = x.min(), x.max(), y.min(), y.max()
                w = np.max(dist[markers == i])
                cur_result.append(((minx, miny), (maxx, maxy), w))
            result.extend(cur_result)
            if cnt < cap_cnt:
                for i in range(cur_cnt):
                    (minx, miny), (maxx, maxy), w = cur_result[i]
                    radius = w + 20  # just in case :)
                    print("Removing", (minx, miny), (maxx, maxy), radius)
                    mask = cv2.circle(mask,
                                      ((minx + maxx) // 2, (miny + maxy) // 2),
                                      radius, 0, -1)
            elif cnt > cap_cnt:
                print("warning: 翻车啦")
        return result

    markers = get_markers(mask)
    # now prepare for watersheding
    ws = np.logical_not(mask).astype('int32')
    for i, (p1, p2, w) in enumerate(markers):
        center = (p1[0] + p2[0]) // 2, (p1[1] + p2[1]) // 2
        axis = ((p2[0] - p1[0]) // 2, (p2[1] - p1[1]) // 2)
        cv2.ellipse(ws, center, axis, 0, 0, 360, i + 2, cv2.FILLED)
    flooded = ws.copy()
    flooded = cv2.watershed(cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR), flooded)
    flooded[...] = flooded - 1
    flooded[flooded <= 0] = 0
    # dilate a little to remove tiny edges
    flooded = flooded.astype("uint8")
    flooded = cv2.morphologyEx(flooded,
                               cv2.MORPH_DILATE,
                               struct_ele,
                               iterations=1)
    ws = flooded
    boxed = img.copy()
    bounding_boxes = []
    minimal_bounding_boxes = []
    for i in range(cap_cnt):
        # value in marker image is i+1
        buf = (ws == i + 1).astype('uint8')
        contours, hierarchy = cv2.findContours(buf, cv2.RETR_EXTERNAL,
                                               cv2.CHAIN_APPROX_NONE)
        assert (len(contours) == 1)
        x, y, w, h = cv2.boundingRect(contours[0])
        bounding_boxes.append(((x, y), (x + w, y + h)))
        minimal_bounding_boxes.append(cv2.minAreaRect(contours[0]))
        ellipse = cv2.fitEllipse(contours[0])
        cv2.ellipse(boxed, ellipse, (0, 255, 0), 2)
        box_points = cv2.boxPoints(minimal_bounding_boxes[-1])
        box_points = np.int0(box_points)
        cv2.rectangle(boxed, bounding_boxes[-1][0], bounding_boxes[-1][1],
                      (255, 0, 0), 2)
        cv2.drawContours(boxed, [box_points], 0, (0, 0, 255), 2)
    real_caps = []
    cap_edges = []
    real_ans = []
    cord = []
    edges = cv2.Canny(img, 40, 80)
    for i, ((p1, p2),
            (center, (width, height),
             a)) in enumerate(zip(bounding_boxes, minimal_bounding_boxes)):
        g = gray[p1[1]:p2[1], p1[0]:p2[0]]
        e = edges[p1[1]:p2[1], p1[0]:p2[0]]
        cord.append(center)
        if width / height > 1.5 or height / width > 1.5:
            print(i, "is a side")
            real_ans.append('side')
        else:
            real_ans.append(None)
            # do circle approximation for better center mounting
            circles = cv2.HoughCircles(g, cv2.HOUGH_GRADIENT, 2, 40, 1, 20, 40,
                                       200)
            if type(circles[0][0]) == np.ndarray:
                for i in circles[0, :]:
                    # draw the outer circle
                    cv2.circle(g, (i[0], i[1]), i[2], 255, 2)
                    # draw the center of the circle
                    cv2.circle(g, (i[0], i[1]), 2, 255, 3)
        real_caps.append(g)
        cap_edges.append(e)
    k = len(real_caps)
    t = cv2.getGaussianKernel(9, 1)
    gaussian_kernel = t * t.T
    gaussian_kernel *= 255 / np.max(gaussian_kernel)
    gaussian_kernel = np.uint8(gaussian_kernel)
    gaussian_kernel = cv2.resize(gaussian_kernel, (64, 64))
    for no, (cap, edge) in enumerate(zip(real_caps, cap_edges)):
        if real_ans[no] is not None:
            print("Skipping", no, "it is a side")
            continue
        c = cv2.resize(cap, (128, 128))
        e = cv2.resize(edge, (128, 128))
        rx, ry = c.shape[0] // 4, c.shape[1] // 4
        cx, cy = c.shape[0] // 2, c.shape[1] // 2
        score = np.sum(e[cx - rx:cx + rx, cy - ry:cy + ry] * gaussian_kernel)
        print(score)
        real_ans[no] = 'top' if score > 50000 else 'tail'
    labelled = img.copy()
    for i in range(len(real_ans)):
        if real_ans[i] == 'top':
            color = (255, 0, 0)
        elif real_ans[i] == 'tail':
            color = (0, 255, 0)
        else:
            color = (0, 0, 255)
        cv2.rectangle(labelled, bounding_boxes[i][0], bounding_boxes[i][1],
                      color, 2)
        cv2.putText(labelled, real_ans[i], bounding_boxes[i][0],
                    cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2)
        cv2.putText(labelled, "({},{})".format(int(cord[i][0]),
                                               int(cord[i][1])),
                    (int(cord[i][0]) - 50, int(cord[i][1])),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2)
    return labelled
Example #41
0
def segment_by_watershed(
        binary_img: np.ndarray,
        img: np.ndarray,
        dist_thresh: float = 3.0) -> Tuple[np.ndarray, List[np.ndarray]]:
    """Segment image using watershed algorithm.

    Parameters
    ----------
    binary_img:np.ndarray
        Binary image derived from ``img`` with nonzero pixel blobs for objects.
        This is usually produced after converting the ``img`` to grayscale and
        then thresholding.
    img: np.ndarray
        Original image to be segmented.
    dist_thresh: float, optional
        Threshold for distance of pixels from boundary to consider them core
        points. If it is < 1.0, it is interpreted as fraction of the maximum
        of the distances.

    Returns
    -------
    points_list: list[np.ndarray]
        List of arrays containing positions of the pixels in each object.

    Notes
    -----
    This code is derivative of this OpenCV tutorial:

    https://docs.opencv.org/master/d3/db4/tutorial_py_watershed.html

    and falls under the same licensing.
    """
    kernel = np.ones((3, 3), dtype=np.uint8)
    opening = cv2.morphologyEx(binary_img,
                               cv2.MORPH_OPEN,
                               kernel,
                               iterations=2)
    # Distance transform calculates the distance of each pixel from
    # background (black in this case) pixels. So we have an image
    # where pixel intensity means the distance of that pixel from the
    # background
    dist_xform = cv2.distanceTransform(opening, cv2.DIST_L2,
                                       cv2.DIST_MASK_PRECISE)
    # Thresholding the distance image to find pixels which are more
    # than a certain distance away from background - this should give
    # us the pixels central to foreground objects
    if dist_thresh < 1.0:
        # threshold relative to maximum of computed distance
        dist_thresh *= dist_xform.max()
    ret, sure_fg = cv2.threshold(dist_xform, dist_thresh, 255, 0)
    sure_fg = np.uint8(sure_fg)
    # border between background and foreground
    sure_bg = cv2.dilate(opening, kernel, iterations=3)
    unknown = cv2.subtract(sure_bg, sure_fg)
    ret, markers = cv2.connectedComponents(sure_fg, connectivity=4)
    # logging.debug(f'Found {ret} connected components')
    # 0 is for background - assign a large value to keep them off
    markers += 1
    markers[unknown == 255] = 0
    markers = cv2.watershed(img, markers)
    unique_labels = set(markers.flat)
    unique_labels.discard(-1)
    unique_labels.discard(0)
    ret = [np.argwhere(markers == label) for label in sorted(unique_labels)]
    # markers[markers == -1] = 0
    # markers = np.uint8(markers)
    # Fast swapping of y and x - see answer by blax here:
    # https://stackoverflow.com/questions/4857927/swapping-columns-in-a-numpy-array
    for points in ret:
        points[:, 0], points[:, 1] = points[:, 1], points[:, 0].copy()
    return ret
Example #42
0
def get_track(img):
    """
    Creates and returns a binary image of the track. Also finds track sections and starts the calculation of the racing line
    :param img: the image
    :return: a binary image of the track
    """
    # Set the bounds to detect the black parts of the track and invert it to get the actual track
    lower_bounds_track = np.array([0, 0, 0])
    upper_bounds_track = np.array([10, 10, 10])
    track = cv.bitwise_not(
        cv.inRange(img, lower_bounds_track, upper_bounds_track))
    # Closing (Dilate + Erode) to remove noise (of the ball border)
    track = cv.morphologyEx(track, cv.MORPH_CLOSE, np.ones((5, 5), np.uint8))

    # Find the finish line
    lower_bounds_finish = np.array([200, 100, 0])
    upper_bounds_finish = np.array([255, 150, 10])
    finish_line = cv.dilate(cv.inRange(img, lower_bounds_finish,
                                       upper_bounds_finish),
                            np.ones((5, 5), np.uint8),
                            iterations=1)
    finish_line_coords = cv.findNonZero(finish_line)
    finish_line_center = np.mean(finish_line_coords, axis=0)[0]

    # Get the contours of the track
    _, contours, _ = cv.findContours(track, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
    image = track.copy()

    # Get the inner and outer contour and the indices of the points where they touch the finish line
    inner_contour, outer_contour, inner_start_index, outer_start_index, inner_contour_index = _get_inner_and_outer_contour(
        contours, finish_line_coords)

    # Calculate the starting direction based on the center of the actual start line and center of the orange area
    direction = finish_line_center - MatrixOps.convex_combination(
        inner_contour[inner_start_index], outer_contour[outer_start_index],
        0.5)
    direction = direction / MatrixOps.fast_norm(direction)

    ### Calculate cross sections of the track ###
    # Create empty/black 3-channel image to run watershed on
    img_empty = np.zeros(img.shape, np.uint8)
    # Create a 1-channel image for the markers
    markers = np.zeros(image.shape, np.int32)
    # Mark the inner contour with label 1 and the other contours with label 2 by drawing them on the markers image
    for i in range(0, len(contours)):
        cv.drawContours(markers, contours, i,
                        1 if i == inner_contour_index else 2)
    # Use watershed to get the boundary between inner and outer contour
    markers = cv.watershed(img_empty, markers)
    # Remove '-1' markers on the border of the image
    markers[:, 0] = markers[1, 1]
    markers[0, :] = markers[1, 1]
    markers[:, -1] = markers[1, 1]
    markers[-1, :] = markers[1, 1]

    # Get a sorted vector of all positions of points on the watershed border
    _, watershed_contours, _ = cv.findContours(
        (markers == -1).astype(np.uint8), cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
    watershed_contour = watershed_contours[0].reshape(
        len(watershed_contours[0]), 2)

    img[markers == -1] = [0, 0, 255]

    # cv.imshow("color", img) TODO remove #

    # Circshift the contour so that the first point corresponds to the start/finishing line
    start_index = MatrixOps.find_closest_point_index(
        MatrixOps.convex_combination(inner_contour[inner_start_index],
                                     outer_contour[outer_start_index], 0.5),
        watershed_contour)
    watershed_contour = np.roll(watershed_contour, -2 * start_index)

    # Check if flipping the contour array is necessary based on the start direction
    next_point = watershed_contour[0] + direction
    closest_point_index = MatrixOps.find_closest_point_index(
        next_point, watershed_contour[[1, len(watershed_contour) - 1]])
    if closest_point_index == 1:
        watershed_contour = np.flip(watershed_contour, 0)

    # Reduce the number of points on the contour to get the checkpoints needed for smoothing and for the features
    checkpoints = watershed_contour[::20]

    #for c in checkpoints:
    #    cv.circle(image, tuple(c), 3, (192, 192, 192), -1)
    #cv.imshow("image", image)

    # Erode the track/dilate the track border by the radius of the ball
    kernel = np.ones((5, 5), np.uint8)
    eroded_track = cv.erode(
        image, kernel, iterations=4
    )  # Kernel increases border by 2 pixel each iteration, ball seems to have a radius of about 8 pixels
    #cv.imshow("eroded_track", eroded_track) TODO remove #

    smoothened_checkpoints = _smoothen_checkpoints_contour(
        checkpoints, eroded_track)

    #for c in smoothened_checkpoints:
    #    cv.circle(image, tuple(c), 3, (192, 192, 192), -1)
    #cv.imshow("image", image)

    return track, smoothened_checkpoints
Example #43
0
    DistNorm = np.uint8(DistImg * C)
    cv2.imshow('DistNorm', DistNorm)
    _, DistBin = cv2.threshold(src=DistNorm,
                               thresh=DistNorm.max() * 0.7,
                               maxval=255,
                               type=cv2.THRESH_BINARY)
    cv2.imshow('DistBin', DistBin)
    # cv2.imshow('DistImg', cv2.normalize(src=DistImg, norm_type=cv2.NORM_MINMAX))

    # unknown
    # Unknown = DilationImg - DistBin
    Unknown = cv2.subtract(DilationImg, DistBin)
    cv2.imshow('Unknown', Unknown)

    # connect
    MarkImg = np.zeros(GrayImg.shape, dtype=np.int32)
    MarkImg[DilationImg == 0] = 1
    ForegroundContours, _ = cv2.findContours(image=DistBin.copy(),
                                             mode=cv2.RETR_EXTERNAL,
                                             method=cv2.CHAIN_APPROX_NONE)
    ret, MarkImg = markContours(ForegroundContours,
                                markImg=MarkImg,
                                startNum=2)
    cv2.imshow('MarkImg', np.uint8(MarkImg * (255.0 / MarkImg.max())))

    cv2.watershed(SrcImg, MarkImg)
    SrcImg[MarkImg == -1] = [0, 0, 255]
    cv2.imshow('Src', SrcImg)
    cv2.imshow('Gray', GrayImg)
    cv2.imshow('Bin', BinImg)
    cv2.waitKey()
Example #44
0
def textDetectWatershed(thresh, original, draw=False, group=False):
    """ Text detection using watershed algorithm """
    # According to: http://docs.opencv.org/trunk/d3/db4/tutorial_py_watershed.html
    img = resize(original, 3000)
    thresh = resize(thresh, 3000)
    # noise removal
    kernel = np.ones((3, 3), np.uint8)
    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=3)

    # sure background area
    sure_bg = cv2.dilate(opening, kernel, iterations=3)

    # Finding sure foreground area
    dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
    ret, sure_fg = cv2.threshold(dist_transform, 0.001 * dist_transform.max(),
                                 255, 0)

    # Finding unknown region
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg, sure_fg)

    # Marker labelling
    ret, markers = cv2.connectedComponents(sure_fg)

    # Add one to all labels so that sure background is not 0, but 1
    markers += 1

    # Now, mark the region of unknown with zero
    markers[unknown == 255] = 0

    markers = cv2.watershed(img, markers)

    image = img.copy()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Creating result array
    boxes = []
    for mark in np.unique(markers):
        # mark == 0 --> background
        if mark == 0:
            continue

        # Draw it on mask and detect biggest contour
        mask = np.zeros(gray.shape, dtype="uint8")
        mask[markers == mark] = 255

        cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
                                cv2.CHAIN_APPROX_SIMPLE)[-2]
        c = max(cnts, key=cv2.contourArea)

        # Draw a bounding rectangle if it contains text
        x, y, w, h = cv2.boundingRect(c)
        cv2.drawContours(mask, c, 0, (255, 255, 255), cv2.FILLED)
        maskROI = mask[y:y + h, x:x + w]
        # Ratio of white pixels to area of bounding rectangle
        r = cv2.countNonZero(maskROI) / (w * h)

        # Limits for text
        if r > 0.1 and 2000 > w > 15 and 1500 > h > 15:
            boxes += [[x, y, w, h]]

    # Group intersecting rectangles
    if group:
        boxes = group_rectangles(boxes)

    boxes.sort(key=lambda b: (b[1] + b[3], b[0]))

    bounding_boxes = np.array([0, 0, 0, 0])
    rois = []

    for (x, y, w, h) in boxes:
        rois.append(img[y:y + h, x:x + w])
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
        bounding_boxes = np.vstack(
            (bounding_boxes, np.array([x, y, x + w, y + h])))
    if draw:
        implt(sure_bg, t='sure_background')
        implt(sure_fg, t='sure_foreground')
        implt(unknown, t='unknown area')
        implt(markers, t='Markers')
        implt(image)
    # Recalculate coordinates to original size
    boxes = bounding_boxes[1:].dot(ratio(original,
                                         img.shape[0])).astype(np.int64)

    return boxes, rois
Example #45
0
def process(filename, output_folder, verbose):
    img = cv.imread(filename)
    grayscale = cv.imread(filename, 0)
    filename = os.path.basename(filename).split('.')[-2]

    # Edge enchancement
    unsharp = unsharp_mask(grayscale, amount=6, threshold=0)
    bilateral_blur = cv.bilateralFilter(unsharp, 9, 75, 75)
    _, th = cv.threshold(bilateral_blur, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU)

    # Noise reduction
    kernel = np.ones((3,3), np.uint8)
    m_blur = cv.medianBlur(cv.medianBlur(th, 3), 3)
    opening = cv.morphologyEx(m_blur, cv.MORPH_OPEN, kernel, iterations = 1)

    # Watershed segmentation
    sure_bg = cv.dilate(opening, kernel, iterations=2)
    dist_transform = cv.distanceTransform(opening, cv.DIST_L2, 0)
    dist_transform = cv.normalize(dist_transform, dist_transform, 0, 255, cv.NORM_MINMAX)
    _, sure_fg = cv.threshold(dist_transform, 0.23 * dist_transform.max(), 255, 0)
    sure_fg = np.uint8(sure_fg * 100000)
    unknown = cv.subtract(sure_bg, sure_fg)

    _, markers = cv.connectedComponents(sure_fg)
    markers = markers + 1
    markers[unknown==255] = 0

    markers = cv.watershed(img, markers)
    bordered = opening
    bordered[markers == -1] = 0
    bordered = cv.convertScaleAbs(bordered)
    bordered = cv.erode(bordered, kernel, iterations=1)

    # Contour detection
    contours, hierarchy = cv.findContours(bordered, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

    contours = [c for c in contours if cv.contourArea(c)>5]  # Filtering erroneous contours (with tiny areas)
    moments = [cv.moments(c) for c in contours]
    centroids = [(int(m['m10']/m['m00']), int(m['m01']/m['m00'])) for m in moments]

    # Scaling contours up (to revert errosion effect)
    contours = [np.asarray(((c - cent)*1.05)+cent, int) for c, cent in zip(contours, centroids)]

    result = cv.cvtColor(grayscale, cv.COLOR_GRAY2RGB)
    cv.drawContours(result, contours, -1, (0,255,0), thickness=1, lineType=cv.LINE_AA)

    contours_filled = np.zeros(grayscale.shape)
    cv.fillPoly(contours_filled, pts=contours, color=(255,255,255))

    # Calculation of equivalent diameter
    equivalent_diameters = [np.sqrt(4 * m['m00'] / np.pi) for m in moments]
    max_ = max(equivalent_diameters)
    min_ = min(equivalent_diameters)

    contours_colored = cv.cvtColor(grayscale, cv.COLOR_GRAY2RGB)

    for c, d in zip(contours, equivalent_diameters):
        color = (int(255*(d-min_)/(max_-min_)), 0, int(255-255*(d-min_)/(max_-min_)))
        cv.drawContours(contours_colored, [c], -1, color, thickness=2, lineType=cv.LINE_AA)

    colormap = colors.LinearSegmentedColormap.from_list("BuRd", [(0,0,1), (1,0,0)], 256)
    plt.figure(figsize=(10,10))
    plt.axis('off')
    plt.title('Particles colored with respect to equivalent diameter.')
    plt.imshow(contours_colored, colormap)

    cbar = plt.colorbar(fraction=0.0455, pad=0.04)
    interp = lambda x: (int(x)*(max_-min_)+255*min_)//255
    cbar.ax.set_yticklabels([interp(l.get_text()) for l in cbar.ax.get_yticklabels()])

    plt.savefig(output_folder+filename+'_contours_colored.png', dpi=200)

    # Size distribution
    plt.figure(figsize=(10,3))
    plt.title('Particle size distribution.')
    nums, bins, patches = plt.hist(equivalent_diameters, bins=16)
    bins /= max(bins)

    for b, p in zip(bins, patches):
        plt.setp(p, 'facecolor', colormap(b))

    plt.savefig(output_folder+filename+'_size_distribution.png', dpi=150)

    cv.imwrite(output_folder+filename+'_contours_filled.png', contours_filled)
    if verbose:
        cv.imwrite(output_folder+filename+'_unsharp.png', unsharp)
        cv.imwrite(output_folder+filename+'_th.png', th)
        cv.imwrite(output_folder+filename+'_opening.png', opening)
        cv.imwrite(output_folder+filename+'_sure_bg.png', sure_bg)
        cv.imwrite(output_folder+filename+'_dist_transform.png', dist_transform)
        cv.imwrite(output_folder+filename+'_sure_fg.png', sure_fg)
        cv.imwrite(output_folder+filename+'_unknown.png', unknown)
        cv.imwrite(output_folder+filename+'_markers.png', markers)
        cv.imwrite(output_folder+filename+'_contours.png', result)
Example #46
0
foreground = foreground.astype(np.uint8)

#label是标签,该函数把图像背景标成0,其他封闭目标用从1开始的整数标记
#stats 是bounding box的信息,N*5的矩阵,行对应每个label,五列分别为[x0, y0, 宽度, 高度, 面积]
#centroids 是每个域的质心坐标
_, labels, stats, centroids = cv2.connectedComponentsWithStats(foreground)
#使背景标记为1
labels = labels + 1

ax4 = fig.add_subplot(164)
ax4.imshow(labels)
ax4.set_title("foreground")

#确定的前景目标标记为2、3、4......(不同目标标记为不同序号,方面后面进行粘连前景的分割)
markers[np.where(labels != 1)] = labels[np.where(labels != 1)]
markers2 = markers.copy()

ax5 = fig.add_subplot(165)
ax5.imshow(markers)
ax5.set_title("markers")

#只接受三通道的图像
#分水岭变换的结果会保存在markers2中
cv2.watershed(img, markers2)

ax6 = fig.add_subplot(166)
ax6.imshow(markers2)
ax6.set_title("obj")

plt.show()
def contours_watershed_filter(frame, contours):
    list_final_Contourn = []
    frame_height, frame_width = frame.shape[:2]
    i = 0
    for cnt in contours:
        black_frame = np.zeros((frame_height, frame_width, 1), dtype="uint8")
        cv2.drawContours(black_frame, [cnt], 0, 255, -1)
        x_rect, y_rect, w, h = cv2.boundingRect(cnt)
        x_prec = int(round(x_rect - (w / 2)))
        x2_prec = x_prec + (2 * w)
        y_prec = int(round(y_rect - (h / 2)))
        y2_prec = y_prec + (2 * h)

        height, width = frame.shape[:2]

        x = 0 if x_prec < 0 else x_prec
        y = 0 if y_prec < 0 else y_prec
        x2 = width - 1 if x2_prec > width - 1 else x2_prec
        y2 = height - 1 if y2_prec > height - 1 else y2_prec

        imCrop = frame[y:y2, x:x2]

        cropCopy = imCrop.copy()
        mask_crop = black_frame[y:y2, x:x2]

        kernel = np.ones((3, 3), np.uint8)
        opening = cv2.morphologyEx(mask_crop,
                                   cv2.MORPH_OPEN,
                                   kernel,
                                   iterations=1)

        sure_bg = cv2.dilate(opening, kernel, iterations=5)
        sure_fg = np.uint8(opening)
        unknown = cv2.subtract(sure_bg, sure_fg)
        ret, markers = cv2.connectedComponents(sure_fg)
        markers = markers + 1
        markers[unknown == 255] = 0
        markers = cv2.watershed(cropCopy, markers)
        markers[:, 0] = 1
        markers[0, :] = 1
        markers[-1, :] = 1
        markers[:, -1] = 1
        cropCopy[markers == -1] = [255, 0, 0]

        black_little_frame = np.zeros((y2 - y, x2 - x), np.uint8)
        black_little_frame[markers == -1] = 255

        contours_little, hieracy = cv2.findContours(black_little_frame,
                                                    cv2.RETR_EXTERNAL,
                                                    cv2.CHAIN_APPROX_NONE)
        img_contours_little = np.zeros(
            (black_little_frame.shape[0], black_little_frame.shape[1], 1),
            dtype="uint8")
        cv2.drawContours(img_contours_little, contours_little, -1, 255, -1)

        momenti = cv2.moments(img_contours_little, True)
        c = ((momenti['m00'])**2) / (2 * math.pi *
                                     (momenti['mu20'] + momenti['mu02']))

        if c >= 0.95:
            hu_moments = cv2.HuMoments(momenti).flatten()
            list_final_Contourn.append(cnt)
        i += 1
    return list_final_Contourn
Example #48
0
def crop_img(img, indx, done=False):

    if done is False:
        plt.imshow(img)
        plt.show()
        #sets the background of the image to black
        mask = np.zeros(img.shape[:2], np.uint8)
        bgdModel = np.zeros((1, 65), np.float64)
        fgdModel = np.zeros((1, 65), np.float64)
        rect = (50, 50, 450, 290)
        cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5,
                    cv2.GC_INIT_WITH_RECT)
        mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
        img = img * mask2[:, :, np.newaxis]
        plt.imshow(img)
        #plt.show()

    #picks out a specific object in the image and crops out everything but that
    #code from opencv's website on watershed
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    ret, thresh = cv2.threshold(gray, 100, 255,
                                cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    # noise removal
    kernel = np.ones((3, 3), np.uint8)
    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
    # sure background area
    sure_bg = cv2.dilate(opening, kernel, iterations=3)
    # Finding sure foreground area
    dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
    ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(),
                                 255, 0)
    # Finding unknown region
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg, sure_fg)
    # Marker labelling
    ret, markers = cv2.connectedComponents(sure_fg)
    # Add one to all labels so that sure background is not 0, but 1
    markers = markers + 1
    # Now, mark the region of unknown with zero
    markers[unknown == 255] = 0
    markers = cv2.watershed(img, markers)
    img[markers == -1] = [255, 255, 255]
    loc = []
    plt.imshow(img)
    plt.show()

    #performs the cropping of the image
    for i in range(len(markers)):
        for j in range(len(markers[i])):
            if markers[i][j] == 1:
                loc.append((i, j))
    if len(loc) > 1:
        loc.pop(0)
        x = []
        for i in range(len(loc)):
            x.append(loc[i][0])
        y = []
        for i in range(len(loc)):
            y.append(loc[i][1])
        minx = np.min(x) - 3
        miny = np.min(y) - 3
        maxx = np.max(x) + 3
        maxy = np.max(y) + 3
        img[markers == -1] = [255, 0, 0]
        plt.imshow(img)
        plt.show()
        roi = img[minx:maxx, miny:maxy]
        #roi_rgb = cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)
        plt.imshow(roi)
        plt.show()
        cv2.imwrite("roi.jpg", roi)
while True:
    cv2.imshow('Image',selectOnImage_copy)
    cv2.imshow('Watershed Segments', segments)
    k = cv2.waitKey(1)
    if k == 27:
        break
    elif k == ord('c'):
        selectOnImage_copy = image.copy()
        marker_image = np.zeros(image.shape[:2],dtype=np.int32)
        segments = np.zeros(image.shape, dtype=np.uint8)
    elif k>0 and chr(k).isdigit():
        current_marker = int(chr(k))
    
    if marks_updated:
        marker_image_copy = marker_image.copy()
        cv2.watershed(image,marker_image_copy)
        segments = np.zeros(image.shape,dtype=np.uint8)
        for color_ind in range(n_markers):
            segments[marker_image_copy==(color_ind)] = colors[color_ind]
cv2.imwrite('images/seg.jpg',segments)
cv2.destroyAllWindows()

cimg = cv2.imread("images/seg.jpg", cv2.IMREAD_GRAYSCALE)
circles = cv2.HoughCircles(cimg,cv2.HOUGH_GRADIENT,1.5,120,param1=50,param2=30,minRadius=0,maxRadius=0)
circles = np.uint16(np.around(circles))
# print(len(circles[0,:]))

img = image.copy()
# for circle in circles[0,:]:
circle = circles[0,:][0]
# draw the outer circle
Example #50
0
def heartSeg(file_name):
    # img_blur = cv2.GaussianBlur(img_origin, (3,3), 0, 0)
    # img_blur = cv2.blur(img_origin, (5,5))
    # Input the image
    img_origin_name = 'public/data/' + file_name
    img_origin = cv2.imread(img_origin_name, 1)
    img_origin_singlechannel = cv2.imread(img_origin_name, 0)

    # Image smoothing (also reduce noise)
    img_medianblur = cv2.medianBlur(img_origin_singlechannel, 5)

    # Apply thresholding to the image twice to get the desired grayscale interval (between 50~145)
    thresh_val_high = 145
    thresh_val_low = 50
    ret, thresh = cv2.threshold(img_medianblur, thresh_val_high, 255,
                                cv2.THRESH_TOZERO_INV)
    ret, img_binary = cv2.threshold(thresh, thresh_val_low, 255,
                                    cv2.THRESH_BINARY)

    # Apply morphology opening to binary image to eliminate small objects
    kernel = np.ones((3, 3), dtype=np.uint8)
    img_obj = cv2.morphologyEx(img_binary,
                               cv2.MORPH_OPEN,
                               kernel,
                               iterations=2)

    # Find the absolute foreground (i.e. objects) by eroding all objects
    fg = cv2.erode(img_obj, kernel, iterations=3)
    # Specify heart wall foreground with the condition of object window size
    fg_labels_num, fg_labels_img, fg_stats, fg_centroids = cv2.connectedComponentsWithStats(
        fg)
    muscle_fg_idx = 0
    for muscle_fg_idx in range(fg_labels_num):
        if fg_stats[muscle_fg_idx,cv2.CC_STAT_WIDTH] > 80 and fg_stats[muscle_fg_idx,cv2.CC_STAT_WIDTH] < 120 \
        and fg_stats[muscle_fg_idx,cv2.CC_STAT_HEIGHT] > 100 and fg_stats[muscle_fg_idx,cv2.CC_STAT_HEIGHT] < 140:
            break
    fg_labels_img[fg_labels_img != muscle_fg_idx] = 0
    fg_labels_img[fg_labels_img == muscle_fg_idx] = 1
    muscle_fg = fg_labels_img.astype('uint8')
    muscle_fg = cv2.erode(muscle_fg, kernel, iterations=2)

    # Specify heart wall region with the condition of object window size
    bg = img_obj
    bg_labels_num, bg_labels_img, bg_stats, bg_centroids = cv2.connectedComponentsWithStats(
        bg)
    muscle_bg_idx = 0
    for muscle_bg_idx in range(bg_labels_num):
        if bg_stats[muscle_bg_idx,cv2.CC_STAT_WIDTH] > 120 and bg_stats[muscle_bg_idx,cv2.CC_STAT_WIDTH] < 160 \
        and bg_stats[muscle_bg_idx,cv2.CC_STAT_HEIGHT] > 120 and bg_stats[muscle_bg_idx,cv2.CC_STAT_HEIGHT] < 160:
            break
    bg_labels_img[bg_labels_img != muscle_bg_idx] = 0
    bg_labels_img[bg_labels_img == muscle_bg_idx] = 1
    muscle_bg = bg_labels_img.astype('uint8')
    # Find the absolute background by dilating heart wall region
    muscle_bg = cv2.dilate(muscle_bg, kernel, iterations=7)

    muscle_fg = muscle_fg.astype('int32')
    muscle_bg = muscle_bg.astype('int32')
    # The area between heart wall object and background is unknown area TBD with watershed algorithm
    muscle_unknown = np.copy(muscle_bg)
    muscle_unknown[muscle_fg > 0] = 0
    '''
    markers:
    >1: absolute foreground (heart wall object)
    1: absolute background
    0: unknown area (TBD with watershed algorithm)
    (all 0 will become 1 (bg) or >1 (fg) after watershed algorithm applied)
    -1: watershed boundaries (generated with watershed algorithm)
    '''
    markers = muscle_fg + 1
    markers[muscle_unknown > 0] = 0

    # Apply watershed algorithm on Gaussian-blurred image (not the origin one, because the noise is massive)
    img_gaussblur = cv2.GaussianBlur(img_origin, (3, 3), 0, 0)
    markers = cv2.watershed(img_gaussblur, markers)

    # Use our function to generate the image where heart wall region is specified
    img_out = getWatershedImage(img_origin, markers)
    if not os.path.isdir('public/result'):
        os.mkdir('public/result')
    cv2.imwrite('public/result/result_' + file_name, img_out)
Example #51
0
    def watershed(self, original):

        hsv = cv2.cvtColor(original, cv2.COLOR_BGR2HSV)

        for i in range(len(self.lower_fg)):
            self.create_window()
            self.fine_tune_fg(self.lower_fg[i], self.upper_fg[i], hsv,
                              original)

        for i in range(len(self.lower_bg)):
            self.create_window_bg()
            self.fine_tune_bg(self.lower_bg[i], self.upper_bg[i], hsv,
                              original)

        if self.fg is None or self.bg is None:
            self.fg = []
            self.bg = []
            return None, None
        self.fg = self.fg_array[0]
        for j in range(len(self.fg_array)):
            if j > 0:
                self.fg = cv2.add(self.fg, self.fg_array[j])

        self.bg = self.bg_array[0]
        for j in range(len(self.bg_array)):
            if j > 0:
                self.bg = cv2.add(self.bg, self.bg_array[j])

        # passa para gray
        fg_gray = cv2.cvtColor(self.fg, cv2.COLOR_BGR2GRAY)
        bg_gray = cv2.cvtColor(self.bg, cv2.COLOR_BGR2GRAY)

        # simplificar Binarias
        _, thresh_fg = cv2.threshold(fg_gray, 0, 255,
                                     cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        _, thresh_bg = cv2.threshold(bg_gray, 0, 255,
                                     cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

        # retirar areas comuns que nao interresam
        mark = cv2.subtract(thresh_bg, thresh_fg)

        # simplificar markers
        mark32 = np.int32(cv2.addWeighted(thresh_fg, 1, thresh_bg, 0.5, 0))
        markers = mark32 + 1
        markers[mark == 255] = 0

        # watershed
        markers = cv2.watershed(original, markers)

        # encontrar contornos
        m = cv2.convertScaleAbs(markers)
        _, m = cv2.threshold(m, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        cntr, h = cv2.findContours(m, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)

        cv2.drawContours(original, cntr, -1, (255, 255, 255), 2, cv2.LINE_AA)

        self.create_window_view()
        while 1:
            cv2.imshow(self.filename, original)

            k = cv2.waitKey(5) & 0xFF
            if k == ord("s"):
                cv2.destroyAllWindows()
                self.fg = ""
                self.bg = ""
                self.fg_array = []
                self.bg_array = []
                return original, cntr
Example #52
0
 def watershed(self):
     m = self.markers.copy()
     cv.watershed(self.img, m)
     overlay = self.colors[np.maximum(m, 0)]
     vis = cv.addWeighted(self.img, 0.5, overlay, 0.5, 0.0, dtype=cv.CV_8UC3)
     cv.imshow('watershed', vis)
Example #53
0
def main():
    #Input the images from the file you want analysed for comparison: img = Original img2 = Labelled
    cv2.namedWindow("Results")
    img = cv2.imread(r'originals/001.jpg')
    img2 = cv2.imread(r'labelled/001.jpg')

    #Converting the images into grayscale.
    rows, cols = img.shape[0], img.shape[1]
    img = cv2.resize(img, (int(cols / 2), int(rows / 2)))
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 0, 255,
                                cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

    # Noise reduction.
    kernel = np.ones((3, 3), np.uint8)
    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)

    # Identifying the background area of the overall image.
    sure_bg = cv2.dilate(opening, kernel, iterations=1)

    # Determining each individual object. (Cells.)
    sure_fg = cv2.erode(opening, kernel, iterations=1)

    # Remaining area is the border (seperation area) between the cells and the background.
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg, sure_fg)

    # Label the interior of each individual cell with a unique label.
    ret, markers = cv2.connectedComponents(sure_fg)
    # Add one to all labels so that sure background is not 0, but 1
    markers = markers + 1

    # Watershed algorithm identifies the boundaries of each cell.
    markers[unknown == 255] = 0
    markers = cv2.watershed(img, markers)

    # Number of markers is the number of cells in the image.
    numbers = markers.max()

    # Calculate the gray-scale variance for each cell and treat all cells that are greater than the maximum value of the (gray-scale variance * var_threshold) as diseased and marked as green.
    var_threshold = 0.2
    mess = []
    max_var = 0
    for i in range(2, numbers + 1):
        if gray[markers == i] != []:
            tmp = gray[markers == i]
            if tmp.size > 50:
                pix_var = tmp.var()
                mess.append((pix_var, i, tmp.min()))
                if pix_var > max_var:
                    max_var = pix_var
    disease = []
    for i in range(len(mess)):
        if mess[i][0] >= max_var * var_threshold:
            disease.append(mess[i][2])
            img[markers == mess[i][1]] = [0, 255, 0]  #BGR

# Traverse all the cells once again to prevent any leaks.
# Taking the average of the darkest gray values for each diseased cell as described above, treat all cells that have a darker color than the average* pix_threshold as being diseased and marked in red.
    pix_threshold = 0.75
    for i in range(len(mess)):
        if mess[i][2] <= np.array(mess).mean() * pix_threshold:
            img[markers == mess[i][1]] = [0, 0, 255]  #BGR

    # Map all borders in blue for easy viewing.
    img[markers == -1] = [255, 0, 0]  #BGR

    #Show final results.
    print('Total Number Of Cells:' + str(numbers))
    (r, g, b) = cv2.split(img)
    img = cv2.merge([b, g, r])
    (r, g, b) = cv2.split(img2)
    img2 = cv2.merge([b, g, r])
    plt.figure('Result')
    plt.subplot(1, 2, 1)
    plt.imshow(img2)
    plt.subplot(1, 2, 2)
    plt.imshow(img)
    plt.show()

    # Show grey level histogram.
    plt.figure('Gray Level Histogram')
    arr = gray.flatten()
    n, bins, patches = plt.hist(arr,
                                bins=256,
                                normed=1,
                                facecolor='green',
                                alpha=0.75)
    plt.show()
Example #54
0
print(unknown)

# Marker labelling
ret, markers = cv.connectedComponents(sure_fg)

print(markers.shape)
# for x in markers:
#     print(x)
# Add one to all labels so that sure background is not 0, but 1
markers = markers + 1

# Now, mark the region of unknown with zero
print(markers[unknown == 255])
markers[unknown == 255] = 0
new_img = np.zeros((312, 252, 3), np.uint8)
new_img[:] = (255, 255, 255)

cv.imshow('img1', img)
print(markers)
markers = cv.watershed(img, markers)
markers2 = cv.watershed(new_img, markers)
# print(markers)
img[markers == -1] = [255, 0, 0]
new_img[markers == -1] = [255, 0, 0]
cv.imshow('img', img)
cv.imshow('new_img', new_img)
# cv2.waitKey()
while (1):
    # cv2.imshow('newimg', newimg)
    if cv.waitKey(1) == ord('q'):
        break
Example #55
0
    def __init__(self, org_img, org_mask):
        #画像格納
        train_data = org_img[:, :, :3].copy()  # omit alpha channel
        train_data_gray = cv2.cvtColor(train_data, cv2.COLOR_RGB2GRAY)
        mask_data = org_mask
        mask_data = mask_data.copy()
        #ヒストグラム正規化により差が出やすくする
        clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
        equ = clahe.apply(train_data_gray)
        #equからdatas作成、maskと被ってないとこ消去、ノイズ消去
        datas = []
        for i in range(0, 256):
            th = Threshold(equ, i)
            thd = th.data()
            kernel = np.ones((5, 5), np.uint8)
            opening = cv2.morphologyEx(thd, cv2.MORPH_OPEN, kernel)  #膨張収縮
            closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)  #収縮膨張
            inverse = cv2.bitwise_not(closing)  #色調反転
            data = cv2.bitwise_and(inverse, inverse,
                                   mask=mask_data)  #maskの輪郭外を消去
            datas.append(data)
        datas.append(mask_data)  #最後にmaskを入れる

        #輪郭配列を作る。
        all_contours_array = []  #dataごとのcontoursが全て入っている
        for data in datas:
            contours_array = [
            ]  #contour_array:各画像に対して[フラグ,moment,輪郭]の形で複数入っている
            image, contours, hierarchy = cv2.findContours(
                data, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
            for contour in contours:
                curve_flag = flag.no_curve  #くびれがなければ0
                if curve(contour):  #くびれがあれば1
                    curve_flag = flag.curve
                moment = cv2.moments(contour)
                #重心
                if moment['m00'] != 0:
                    cx = int(moment['m10'] / moment['m00'])
                    cy = int(moment['m01'] / moment['m00'])
                else:
                    cx = 0
                    cy = 0
                contours_array.append([curve_flag, [cx, cy], contour])
            all_contours_array.append(contours_array)

        seeds = []  #watershedアルゴリズムの前景となる輪郭を入れる配列

        first_outer_contours = []
        #datas256番=mask_dataで輪郭を取得。くびれていなければseedsへ。くびれていたらfirst_outer_contoursへ。
        first_contours_array = all_contours_array[256]
        for contour_array in first_contours_array:
            if contour_array[0] == flag.curve:
                first_outer_contours.append(contour_array[2])
            elif contour_array[0] == flag.no_curve:
                seeds.append(contour_array[2])
        #255番からループスタート
        Search(255, first_outer_contours, all_contours_array, seeds)

        img = np.copy(train_data)
        contour_img = cv2.drawContours(img, seeds, -1, (125, 125, 0), 1)

        zero = np.zeros(mask_data.shape)
        devided = cv2.fillPoly(zero, pts=seeds,
                               color=(255, 255, 255))  #分割されたやつ
        devided = np.uint8(devided)
        #前景となる場所を決める
        dist_transform = cv2.distanceTransform(devided, cv2.DIST_L2, 5)
        ret, sure_fg = cv2.threshold(dist_transform,
                                     0.1 * dist_transform.max(), 255, 0)

        #背景となる場所を決める
        kernel = np.ones((3, 3), np.uint8)
        sure_bg = cv2.dilate(mask_data, kernel, iterations=3)

        sure_fg = np.uint8(sure_fg)
        unknown = cv2.subtract(sure_bg, sure_fg)

        ret, markers = cv2.connectedComponents(sure_fg)
        markers = markers + 1
        # 不明領域に0をつけておく
        markers[unknown == 255] = 0
        #watershedアルゴリズムを行う
        markers = cv2.watershed(train_data, markers)

        self.__data = markers
img = cv2.imread('C:/Users/Ferhat/Desktop/img3.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 0, 255,
                            cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
# noise removal
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)

# sure background area
sure_bg = cv2.dilate(opening, kernel, iterations=5)

# Finding sure foreground area
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform, 0.2 * dist_transform.max(), 255,
                             50)

# Finding unknown region
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)
# Marker labelling
ret, markers = cv2.connectedComponents(sure_fg)

# Add one to all labels so that sure background is not 0, but 1
markers = markers + 1

# Now, mark the region of unknown with zero
markers[unknown == 255] = 0
markers = cv2.watershed(img, markers)
img[markers == -1] = [255, 0, 0]
cv2.imwrite('C:/Users/Ferhat/Desktop/img1213.jpg', img)
Example #57
0
    ## find compromise for overlapping areas

    if len(polygon) > 0:

        # label non-cell areas
        background_label = i + 2
        labels[labels == 0] = background_label

        # label overlapping areas
        labels[cell_count > 1] = 0

        # apply watershed algorithm to fill in overlap areas. The "image" entry is an array of zeros, so that the
        # boundaries extend uniformly without paying attention to the original histology image (otherwise, the
        # boundaries will be crooked)
        labels = watershed(np.zeros(im.size[::-1] + (3,), dtype=np.uint8), np.array(labels))

        # set background pixels back to zero
        labels[labels == background_label] = 0

        # compute borders between labels, because in some cases, adjacent cells have intermittent overlaps
        # that produce interrupted 0 boundaries
        borders = mahotas.labeled.borders(labels, mode='ignore')

        # add borders to the labels
        labels[borders] = 0

    if DEBUG:
        plt.subplot(224)
        plt.imshow(labels)
Example #58
0
def processing(data):
    print(data)
    file_num = int(len(data))
    # Reading 3 images to work
    img = [cv2.imread(i, cv2.IMREAD_UNCHANGED) for i in data[:file_num]]

    try:
        print('Original size', img[0].shape)
        myshape = img[0].shape

    except AttributeError:
        print("shape not found")

    # --------------------------------
    # setting dim of the resize
    height = myshape[0]
    width = myshape[1]
    dim = (width, height)
    res_img = []
    for i in range(len(img)):
        res = cv2.resize(img[i], dim, interpolation=cv2.INTER_LINEAR)
        res_img.append(res)

    # Checcking the size
    try:
        print('RESIZED', res_img[1].shape)
    except AttributeError:
        print("shape not found")
    # Visualizing one of the images in the array
    #original = res_img[1]
    #display_one(original)
    # ----------------------------------
    # Remove noise
    # Using Gaussian Blur
    no_noise = []

    for i in range(len(res_img)):
        #blur = cv2.GaussianBlur(res_img[i], (5, 5), 0)
        blur = cv2.bilateralFilter(res_img[i], 5, 100, 100)
        no_noise.append(blur)

    for i in range(len(res_img)):

        original = res_img[i]
        image = no_noise[i]

        #display(original, image, 'Original', 'Blured')
        im = Image.fromarray(image)
        myname = data[i]
        mynamestring = str(myname[+image_path_length:])
        print("no_noise_path", no_noise_path)
        print("my_name", mynamestring)
        #im.save(f"{no_noise_path}{mynamestring}")

        #---------------------------------
        # Segmentation
        gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
        im5 = Image.fromarray(gray)
        ret, thresh = cv2.threshold(gray, 0, 255,
                                    cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

        ret, thresh1 = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV)
        ret, thresh2 = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
        ret, thresh3 = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)

        th4 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
                                    cv2.THRESH_BINARY_INV, 11, 4)
        #increasing to 4 keeps features but removes noise

        #display(thresh, thresh2, "Their thresh", "My Thresh")

        im2 = Image.fromarray(thresh)

        # Further noise removal (Morphology)
        kernel = np.ones((3, 3), np.uint8)
        opening = cv2.morphologyEx(thresh,
                                   cv2.MORPH_OPEN,
                                   kernel,
                                   iterations=2)

        im6 = Image.fromarray(th4)
        # sure background area
        sure_bg = cv2.dilate(opening, kernel, iterations=3)

        # Displaying sure background
        #display(original, sure_bg, 'Original', 'Sure background')

        # Finding sure foreground area
        dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
        ret, sure_fg = cv2.threshold(dist_transform,
                                     0.7 * dist_transform.max(), 255, 0)

        # Finding unknown region
        sure_fg = np.uint8(sure_fg)
        unknown = cv2.subtract(sure_bg, sure_fg)
        #Displaying unknown
        #display(original, unknown, 'Original', 'Unknown')

        #Displaying segmented back ground
        #display(original, sure_bg, 'Original', 'Segmented Background')
        im3 = Image.fromarray(sure_bg)
        # Marker labelling
        ret, markers = cv2.connectedComponents(sure_fg)

        # Add one to all labels so that sure background is not 0, but 1
        markers = markers + 1

        # Now, mark the region of unknown with zero
        markers[unknown == 255] = 0

        markers = cv2.watershed(image, markers)
        image[markers == -1] = [0, 0, 255]

        im4 = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

        im4 = Image.fromarray(im4)

        im.save(f"{no_noise_path}{mynamestring}")
        im2.save(f"{segmented_path}{mynamestring}")
        im3.save(f"{segmented_background_path}{mynamestring}")
        im4.save(f"{markers_path}{mynamestring}")
        im5.save(f"{grey_path}{mynamestring}")
        im6.save(f"{adapthresh_path}{mynamestring}")
def get_mask_watershed(image, thresh, aprox_seg, debug=False):
    """Returns the mask of an accurate segmentation based on a approximate
    segmentation and an aggresive threshold.

    Arguments:
        image {cv2 image} -- The image where the search will be perfomed
        thresh {np 2d binary array} -- An aggresive threshold mask of the organ
        aprox_seg {np 2d binary array} -- An aproximate segmentation of the organ

    Keyword Arguments:
        debug {bool} -- Set True to see the full contours given by watershed (default: {False})

    Returns:
        np 2d binary array -- An accurate mask of the organ
    """
    width, height = image.shape

    # Part of mask we're "sure" is the organ
    sure_fg = np.zeros((width, height, 1), np.uint8)
    # Part of mask we're "sure" isn't the organ
    sure_bg = np.zeros((width, height, 1), np.uint8)

    for i in range(width):
        for j in range(height):
            coord = i, j
            sure_bg[coord] = 255
            # If it is part of an aggresive threshold,
            # and part of an approximate contour, it should be the organ
            if aprox_seg[coord] and thresh[i][j]:
                sure_fg[coord] = 255
            # If it isn't part of either, it should be ignored
            elif not aprox_seg[coord] and not thresh[i][j]:
                sure_bg[coord] = 0

    # Parts we'll have to find what they are
    unknown = cv2.subtract(sure_bg, sure_fg)

    # Get the markers for watershed
    _, markers = cv2.connectedComponents(sure_fg)

    # Add one to all labels so that sure background is not 0, but 1
    markers = markers + 1

    # Now, mark the region of unknown with zero
    markers[unknown == 255] = 0

    # Wathershed only works with rgb images
    backtorgb = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
    # Watershed returnes markers of a background, and different foregrounds
    markers = cv2.watershed(backtorgb, markers)

    # In our case:
    # 1 - Background
    # 2 - The organ we're interested in
    # 3... - Other organs or bones

    if debug:
        marked = backtorgb
        marked[markers == -1] = [0, 255, 0]
        cv2.imshow('markers', marked)
        cv2.waitKey()

    # Since we started the search fron the organ, the first
    # foreground region will be the organ of interest
    mask = np.zeros((width, height), np.uint8)
    for i in range(markers.shape[0]):
        for j in range(markers.shape[1]):
            if markers[i, j] == 2:
                mask[i, j] = 1

    return mask
Example #60
0
def test(args):
    data_loader = CTW1500TestLoader(long_size=args.long_size)
    test_loader = torch.utils.data.DataLoader(data_loader,
                                              batch_size=1,
                                              shuffle=False,
                                              num_workers=2,
                                              drop_last=True)
    submit_path = 'outputs_shape'
    if os.path.exists(submit_path):
        shutil.rmtree(submit_path)

    os.mkdir(submit_path)
    # Setup Model
    if args.arch == "resnet50":
        model = models.resnet50(pretrained=True,
                                num_classes=7,
                                scale=args.scale)
    elif args.arch == "resnet101":
        model = models.resnet101(pretrained=True,
                                 num_classes=7,
                                 scale=args.scale)
    elif args.arch == "resnet152":
        model = models.resnet152(pretrained=True,
                                 num_classes=7,
                                 scale=args.scale)

    for param in model.parameters():
        param.requires_grad = False

    model = model.cuda()

    if args.resume is not None:
        if os.path.isfile(args.resume):
            print("Loading model and optimizer from checkpoint '{}'".format(
                args.resume))
            checkpoint = torch.load(args.resume)

            # model.load_state_dict(checkpoint['state_dict'])
            d = collections.OrderedDict()
            for key, value in checkpoint['state_dict'].items():
                tmp = key[7:]
                d[tmp] = value
            model.load_state_dict(d)

            print("Loaded checkpoint '{}' (epoch {})".format(
                args.resume, checkpoint['epoch']))
            sys.stdout.flush()
        else:
            print("No checkpoint found at '{}'".format(args.resume))
            sys.stdout.flush()

    model.eval()

    total_frame = 0.0
    total_time = 0.0
    for idx, (org_img, img) in enumerate(test_loader):
        print('progress: %d / %d' % (idx, len(test_loader)))
        sys.stdout.flush()

        img = Variable(img.cuda(), volatile=True)
        org_img = org_img.numpy().astype('uint8')[0]
        text_box = org_img.copy()

        torch.cuda.synchronize()
        start = time.time()

        outputs = model(img)

        score = torch.sigmoid(outputs[:, 0, :, :])
        outputs = (torch.sign(outputs - args.binary_th) + 1) / 2

        text = outputs[:, 0, :, :]
        kernels = outputs[:, 0:args.kernel_num, :, :] * text

        score = score.data.cpu().numpy()[0].astype(np.float32)
        text = text.data.cpu().numpy()[0].astype(np.uint8)
        kernels = kernels.data.cpu().numpy()[0].astype(np.uint8)

        # # c++ version pse
        # # pred = pse(kernels, args.min_kernel_area / (args.scale * args.scale))
        # # python version pse
        # pred = pypse(kernels, args.min_kernel_area / (args.scale * args.scale))

        # # scale = (org_img.shape[0] * 1.0 / pred.shape[0], org_img.shape[1] * 1.0 / pred.shape[1])
        # scale = (org_img.shape[1] * 1.0 / pred.shape[1], org_img.shape[0] * 1.0 / pred.shape[0])
        # label = pred
        # label_num = np.max(label) + 1
        # bboxes = []

        tmp_marker = kernels[-1, :, :]
        # for i in range(args.kernel_num-2, -1, -1):
        # sure_fg = tmp_marker
        # sure_bg = kernels[i, :, :]
        # watershed_source = cv2.cvtColor(sure_bg, cv2.COLOR_GRAY2BGR)
        # unknown = cv2.subtract(sure_bg,sure_fg)
        # ret, marker = cv2.connectedComponents(sure_fg)
        # label_num = np.max(marker)
        # marker += 1
        # marker[unknown==1] = 0
        # marker = cv2.watershed(watershed_source, marker)
        # marker[marker==-1] = 1
        # marker -= 1
        # tmp_marker = np.asarray(marker, np.uint8)
        sure_fg = kernels[-1, :, :]
        sure_bg = text
        watershed_source = cv2.cvtColor(sure_bg, cv2.COLOR_GRAY2BGR)
        unknown = cv2.subtract(sure_bg, sure_fg)
        ret, marker = cv2.connectedComponents(sure_fg)
        label_num = np.max(marker)
        marker += 1
        marker[unknown == 1] = 0
        marker = cv2.watershed(watershed_source, marker)
        marker -= 1
        label = marker

        # label = tmp_marker
        # scale = (w / marker.shape[1], h / marker.shape[0])
        scale = (org_img.shape[1] * 1.0 / marker.shape[1],
                 org_img.shape[0] * 1.0 / marker.shape[0])
        bboxes = []
        for i in range(1, label_num):
            points = np.array(np.where(label == i)).transpose((1, 0))[:, ::-1]

            if points.shape[0] < args.min_area / (args.scale * args.scale):
                continue

            score_i = np.mean(score[label == i])
            if score_i < args.min_score:
                continue

            # rect = cv2.minAreaRect(points)1
            binary = np.zeros(label.shape, dtype='uint8')
            binary[label == i] = 1
            # a=cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
            # print(a)
            contours, _ = cv2.findContours(binary, cv2.RETR_TREE,
                                           cv2.CHAIN_APPROX_SIMPLE)
            contour = contours[0]
            # epsilon = 0.01 * cv2.arcLength(contour, True)
            # bbox = cv2.approxPolyDP(contour, epsilon, True)
            bbox = contour

            if bbox.shape[0] <= 2:
                continue

            bbox = bbox * scale
            bbox = bbox.astype('int32')
            bboxes.append(bbox.reshape(-1))

        torch.cuda.synchronize()
        end = time.time()
        total_frame += 1
        total_time += (end - start)
        print('fps: %.2f' % (total_frame / total_time))
        sys.stdout.flush()

        for bbox in bboxes:
            cv2.drawContours(text_box, [bbox.reshape(bbox.shape[0] // 2, 2)],
                             -1, (0, 255, 0), 2)

        image_name = data_loader.img_paths[idx].split('/')[-1].split('.')[0]
        write_result_as_txt(image_name, bboxes,
                            'outputs_shape/submit_ctw1500/')

        text_box = cv2.resize(text_box, (text.shape[1], text.shape[0]))
        debug(idx, data_loader.img_paths, [[text_box]],
              'outputs_shape/vis_ctw1500/')