WSI中基于面积方式获取组织掩码图

在WSI中大部分都是背景区域,所以一般都会提取组织区域,形成组织掩码图。一般都是基于HSV颜色空间的方法来提取前景的,这里记录一下基于面积的方式来提取组织区域,主要使用的包是opencv。

源码

get_infill_tissue_matrix
用于获取组织mask图。
参数:
im:RGB图像(传入这个格式的图像主要是因为从openslide获取的图像格式是RGBA)
binary_threshold:二值化阈值
contour_area_threshold:最小面积比例
mode:opencv的findContours函数中寻找轮廓的模式
erode_iter:腐蚀次数
dilate_iter:膨胀次数

def get_infill_tissue_matrix(im, binary_threshold=210, contour_area_threshold=0.001,
                             mode=0, erode_iter=0, dilate_iter=0):
    im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR)
    cnts = find_tissue_contours(im, is_erode_dilate=True, thresh=binary_threshold, mode=mode, erode_iter=erode_iter, dilate_iter=dilate_iter)

    # 获取当前区域面积
    area_cnt_list = list(map(cv2.contourArea, cnts))
    # 获取当前区域占矩阵区域的面积比率
    rate_area = [area / im.size for area in area_cnt_list]
    # 过滤当前区域占矩阵区域的面积比率小于等于filter_rate的区域
    tissue_cnts = [cnts[i] for i in range(len(cnts)) if rate_area[i] >contour_area_threshold]

    # initialize mask to zero
    mask = np.zeros((im.shape[0], im.shape[1])).astype(im.dtype)
    color = [1]
    mask = cv2.fillPoly(mask, tissue_cnts, color)

    return mask

find_contours
获取轮廓坐标
参数:
im:RGB图像
is_erode_dilate:是否进行腐蚀和膨胀
mode:opencv的findContours函数中寻找轮廓的模式
thresh:二值化阈值
erode_iter:腐蚀次数
dilate_iter:膨胀次数

def find_contours(im, is_erode_dilate = False, mode=3, thresh=210, erode_iter=3, dilate_iter=3):
        """
        get the points of contours
        :param morphology: output of erode_dilate
        :return:
        """
        morphology = gray_binary(im, thresh=thresh, show=False)
        if is_erode_dilate:
            morphology = erode_dilate(morphology, erode_iter=erode_iter, dilate_iter=dilate_iter, show=False)
        morphology = cv2.copyMakeBorder(morphology,0,0,0,0,cv2.BORDER_CONSTANT,value=0)

        if not isinstance(mode,int):
            mode_dic = {'RETR_EXTERNAL':0, 'RETR_LIST':1, 'RETR_CCOMP':2, 'RETR_TREE':3, 'RETR_FLOODFILL':4}
            mode = mode_dic[mode]
        if cv2.__version__[0]=='4':
            cnts, _ = cv2.findContours(morphology.copy(),mode=mode,method=cv2.CHAIN_APPROX_SIMPLE)
        else:
            _, cnts , _ = cv2.findContours(morphology.copy(),mode=mode,method=cv2.CHAIN_APPROX_SIMPLE)
        return cnts    

gray_binary
获取灰度图
参数:
im:RGB图像
thresh:二值化阈值
show:是否展示灰度图结果

def gray_binary(im, thresh=230, show=False):
     """
     convert image to binary image after gray scale
     :param thresh: binary image threshold
     :param show: show the binary dynamically
     :return:
     """
     if len(im.shape) >2 :
         gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
     else:
         gray = np.uint8(im)
     blurred = cv2.GaussianBlur(gray, (5,5), 0)
     binary = cv2.threshold(blurred, thresh, 255, cv2.THRESH_BINARY_INV)[1]

     def binary_theshold(threshold):
         binary = cv2.threshold(blurred, threshold, 255, cv2.THRESH_BINARY_INV)[1]
         cv2.imshow("binary image", binary)

     if show:
         window_name = "binary image"
         cv2.namedWindow(window_name, 0)
         cv2.resizeWindow(window_name, 640, 480)
         cv2.createTrackbar("binary threshold", window_name, 100, 255, binary_theshold)
         binary_theshold(100)
         if cv2.waitKey(0) == 27:
             cv2.destroyAllWindows()

     return binary

erode_dilate
腐蚀膨胀处理
binary:灰度图
erode_iter:腐蚀次数
dilate_iter:膨胀次数
kernel_size:核大小
show:是否展示腐蚀膨胀结果

def erode_dilate(binary, erode_iter=6, dilate_iter=9, kernel_size=(5, 5), show=False):
     """
     errode and dilate the binary image dynamically
     :param binary: binary image, output of gray_binary
     :param erode_iter: erode iteration, default 2
     :param dilate_iter: dilate iteration, default 3
     :return:
     """

     morphology = binary

     if show:
         window_name = "errode dilate"
         cv2.namedWindow(window_name, 0)
         cv2.resizeWindow(window_name, 640, 480)

     kernel = cv2.getStructuringElement(cv2.MORPH_RECT, kernel_size)

     while show:
         cv2.imshow(window_name, morphology)
         key = cv2.waitKey(1) & 0xFF
         if ord('e') == key:
             morphology = cv2.erode(morphology, kernel, iterations=1)
             print('erode')
         if ord('d') == key:
             morphology = cv2.dilate(morphology, kernel, iterations=1)
             print('dilate')
         if ord('r') == key:
             morphology = binary
             print('reset threshold image')
         if ord('q') == key:
             break

     cv2.destroyAllWindows()

     morphology = cv2.erode(morphology, kernel, iterations=erode_iter)
     morphology = cv2.dilate(morphology, kernel, iterations=dilate_iter)

     return morphology
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值