Raw File
findyourcell_partial_watershed.jl
using Images
using ImageSegmentation

"""
TODO: LoG with threshold or Gaussian with minima?
"""
function watershedborder(watershed_segments)
    marker_border = BitArray(undef, size(watershed_segments.image_indexmap));
    marker_border .= false
    for label in watershed_segments.segment_labels
        marker_border .|= ((watershed_segments.image_indexmap.==label)
            .⊻ erode(watershed_segments.image_indexmap .==label));
    end
    marker_border;
end

function locate_cell(_img)
    _img_gaussian = imfilter( _img, Kernel.gaussian(12))
    # Extract local minima as watershed markers
    _img_center = Int.(local_minima(opening(closing( .- _img_gaussian ))))
    # remove wrong local minima
    estimated_th = otsu_threshold(_img_gaussian)
    @inbounds for i in eachindex(_img_center)
        now = _img_center[i] 
        if now > 0 
            # remove point which darker than estimated threshold
            if  _img_gaussian[i] < estimated_th
                _img_center[i] = 0
            else
                _img_center[i] = 1
            end
        end
    end
    _img_center = label_components(_img_center)
    # Use watershed to split each cell
    # _img_region= watershed( 1 .- imfilter(_img, Kernel.gaussian(5)), _img_center)
    return _img_center #, labels_map(_img_region)
end

function pickup_cell(_img, _img_center)#, _img_watershed)
    width = 100
    x_len, y_len = size(_img)
    ##!! x length and y length
    mask = zeros(UInt16, size(_img))
    cell_center = component_centroids(_img_center)
    cell_num = length(cell_center) - 1
    cell_info = zeros(cell_num, 5) # [threshold  size intensity]
    #TODO: relabel mask map & only keep one connected component
    @inbounds for cell in 1:cell_num
        #print(cell , " ")
        if (width < cell_center[cell+1][1] < x_len-width) && 
                (width < cell_center[cell+1][2] < y_len-width)
            x0 = Int(floor(cell_center[cell + 1][1] - width/2 + 1))
            y0 = Int(floor(cell_center[cell + 1][2] - width/2 + 1))
            x1 = Int(floor(cell_center[cell + 1][1] + width/2 - 1))
            y1 = Int(floor(cell_center[cell + 1][2] + width/2 - 1)) 
            #println(x0, " ", y0, " ",x1, " ", y1)
            cell_raw = _img[x0:x1, y0:y1]
            mask[x0:x1, y0:y1] = cell_raw .> otsu_threshold(cell_raw)
        end
    end
    region_mask = label_components(mask)
    region_boxes = component_boxes(region_mask)
    region_num = length(region_boxes) - 1
    for region in 1:region_num
        x0, y0 = region_boxes[region+1][1]
        x1, y1 = region_boxes[region+1][2]
        cell_list = []
        for cell in 1:cell_num
            x_now, y_now = cell_center[cell+1]
            if x0<=x_now<=x1 && y0<=y_now<=y1
                push!(cell_list, cell)
            end
        end

        cell_raw = view(_img, x0:x1, y0:y1)
        cell_mask = view(mask, x0:x1, y0:y1)
        if length(cell_list) > 1
            cell_label = view(_img_center, x0:x1, y0:y1)
            region_watershed = labels_map(watershed(1 .- cell_raw, cell_label))
            for idx in eachindex(cell_mask)
                if cell_mask[idx] > 0
                    cell_mask[idx] = region_watershed[idx]
                end
            end
        elseif length(cell_list) == 1
            for idx in eachindex(cell_mask)
                if cell_mask[idx] > 0
                    cell_mask[idx] = cell_list[1]
                end
            end
        else
            #println("no cell found here")
        end
        # save cell location
        for cell in cell_list
            cell_info[cell, 1:2] .= cell_center[cell+1]
        end
    end
    return mask, cell_info
end


function find_your_cell(img)
    img_center = locate_cell(img)         
    cell_mask, cell_info = pickup_cell(img, img_center)
    return cell_mask, cell_info
end
back to top