python - 分水岭分割: Cannot split some cells

标签 python opencv image-segmentation scikit-image

我正在尝试分割细胞核的图像,但最终得到了分割不足的结果。一些大 Blob 出现,理想情况下应该分解成更小的物体,比如右边缘的那些,见下文。
enter image description here
请问有什么我可以做的。我想使用分水岭分割(skimageopencv )分割这些大单元格,如右边缘中间附近的蓝色单元格
到目前为止,我的代码如下所示:

def segment_dapi(img_in):
    img = cv2.cvtColor(img_in, cv2.COLOR_BGR2GRAY)
    kernel = np.ones((3, 3), np.uint8)

    # set the parameters
    thresh = 90
    min_size = 5


    # Adjust brightness
    lims = stretchlim(img)
    img_adj = imadjust(img, lims)

    # Threshold the image
    thres_val = np.percentile(img, thresh)

    _, bw_img = cv2.threshold(img_adj, thres_val, 255, cv2.THRESH_BINARY)

    # Apply morphology opening to remove small objects
    img_obj = cv2.morphologyEx(bw_img, cv2.MORPH_OPEN, kernel, iterations=1)

    bg = cv2.dilate(img_obj, kernel, iterations=1)  # black points belong to the background

    # white points (value = 255) belong to the foreground
    dist_transform = cv2.distanceTransform(img_obj, cv2.DIST_L2, 3)
    _, fg = cv2.threshold(dist_transform, min_size, 255, cv2.THRESH_BINARY)
    fg = np.uint8(fg)
    fg_temp = 255/fg.max() * fg

    x = cv2.subtract(bg, fg)

    _, markers = cv2.connectedComponents(fg)
    markers = markers + 1  # prevent the markers from having values = 0
    markers[x == 255] = 0

    '''
    markers:
    > 1: absolute foreground
    = 1: absolute background
    = 0: unknown area (TBD by watershed)
    '''
    markers = cv2.watershed(img_in, markers)
    img_in[markers == -1] = [0, 255, 255]
    cv2.imwrite('watershed_borders.tif', img_in);
    small_img = cv2.resize(img_in, None, fx=1/2, fy=1/2)
    # cv2.imshow('Overlay', small_img)
    # cv2.waitKey(0)
    ''' 
    markers after watershed:
    = 0: background (set by watershed)
    = 1: background (because the markers have been shifted by 1)
    > 1: object labels 
    - 1: borders between object
    '''

    markers[markers>0] = markers[markers>0]-1
    markers[markers == -1] = 0

    print(markers.max())
    overlay = color.label2rgb(markers, bg_label=0)

    my_dpi = 72
    fig, ax = plt.subplots(figsize=(6000 / my_dpi, 6000 / my_dpi), dpi=my_dpi)
    plt.imshow(overlay)
    ax.set_axis_off()
    plt.tight_layout()
    plt.show()



def stretchlim(img):
    nbins = 255
    tol_low = 0.01
    tol_high = 0.99
    sz = np.shape(img)
    if len(sz) == 2:
        img = img[:, :, None]
        sz = np.shape(img)

    p = sz[2]
    ilowhigh = np.zeros([2, p])
    for i in range(0,p):
        hist,bins = np.histogram(img[:, :, i].ravel(), nbins+1, [0, nbins])
        cdf = np.cumsum(hist) / sum(hist)
        ilow = np.argmax(cdf > tol_low)
        ihigh = np.argmax(cdf >= tol_high)
        if ilow == ihigh:
            ilowhigh[:, i] = np.array([1, nbins])
        else:
            ilowhigh[:, i] = np.array([ilow, ihigh])

    lims = ilowhigh / nbins
    return lims


def imadjust(img, lims):
    lims = lims.flatten()
    lowIn = lims[0]
    highIn = lims[1]
    lowOut = 0
    highOut = 1
    gamma = 1
    lut = adjustWithLUT(img, lowIn, highIn, lowOut, highOut, gamma)
    out = lut[img].astype(np.uint8)
    return out


def adjustWithLUT(img,lowIn,highIn,lowOut,highOut,gamma):
    lutLength = 256 # assumes uint8
    lut = np.linspace(0, 1, lutLength)
    lut = adjustArray(lut, lowIn, highIn, lowOut, highOut, gamma)
    lut = img_as_ubyte(lut)
    return lut


def adjustArray(img, lIn, hIn, lOut, hOut, g):
    # %make sure img is in the range [lIn;hIn]
    img = np.maximum(lIn, np.minimum(hIn, img))
    out = ((img - lIn) / (hIn - lIn)) ** g
    out = out ** (hOut - lOut) + lOut
    return out

最佳答案

你可能会花很长时间找到准确的参数来很好地分割它,但根据我的经验,它很挑剔,然后不适用于你想要分割的下一张图像。这些天,我实际上建议您使用预训练的深度学习网络,例如 cellpose .

关于python - 分水岭分割: Cannot split some cells,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64253959/

相关文章:

c++ - 使用opencv编译头文件。自己的类定义

matlab - matlab 图像中的自主接缝检测

c++ - 获取垫子类型

c++ - 如何在 OpenCV SVM 中获取分离超平面?

python - 从 CSV 读取数据时,如何在 Dask 中添加索引列?

python - 高效地将一系列字典转换为 DataFrame

opencv - 如何使用 OpenCV 在无需人工交互的情况下分割图像中的对象

opencv - 查找非二进制图像的轮廓

python - 执行 randomizedSearchCV 时通过了多个评估指标

python - 使用python进行相机校准