根据deeplesion给的官方标注文件的 Measurement_coordinates 生成伪mask的代码

import numpy as np
import pandas as pd
import cv2
import os

ann_file_path = 'xxx/DL_info.csv'
output_path = 'xxx/fake_masks'

def findIntersection(list_in):
    vector0 = []
    vector1 = []
    vector2 = []
    vector3 = []
    vector4 = []

    vector1.append(list_in[6]-list_in[4])
    vector1.append(list_in[7]-list_in[5])

    vector2.append(list_in[2]-list_in[0])
    vector2.append(list_in[3]-list_in[1])

    vector3.append(list_in[0]-list_in[4])
    vector3.append(list_in[1]-list_in[5])

    vector4.append(list_in[2]-list_in[4])
    vector4.append(list_in[3]-list_in[5])
    
    d1 = abs(np.cross(vector1, vector3))
    d2 = abs(np.cross(vector1, vector4))
    
    t = d1 / (d1 + d2)
    x0 = vector2[0] * t + list_in[0]
    y0 = vector2[1] * t + list_in[1]
    vector0.append(x0)
    vector0.append(y0)
    return vector0

def get_submask(point1, point2, cross_point, filename):
    '''
    params:
     point1, point2, cross_point: [x, y]
    return:
     bool np_array with shape (512,512) 
    '''
    # create 2 matrixes of (512,512), each element of them is its x coordinate and y coordinate
    coordinate_x = np.repeat(np.expand_dims(np.linspace(0,511,512).astype(int), axis=1), 512, axis=1) # coordinate_x[x][y] = x
    coordinate_y = np.repeat(np.expand_dims(np.linspace(0,511,512).astype(int), axis=0), 512, axis=0) # coordinate_y[x][y] = y

    # choose the right quarter
    # line point1-cross_point : (x - point1[0])(cross_point[1] - point1[1]) - (cross_point[0] - point1[0])(y - point1[1]) == 0
    # line point2-cross_point : (x - point2[0])(cross_point[1] - point2[1]) - (cross_point[0] - point2[0])(y - point2[1]) == 0
    flag1 = ( 
        ( (point2[0] - point1[0])*(cross_point[1] - point1[1]) - (cross_point[0] - point1[0])*(point2[1] - point1[1]) ) > 0       
    )
    flag2 = (
        ( (point1[0] - point2[0])*(cross_point[1] - point2[1]) - (cross_point[0] - point2[0])*(point1[1] - point2[1]) ) > 0
    )
    choose_matrix = (
        (
            ( (coordinate_x - point1[0])*(cross_point[1] - point1[1]) - (cross_point[0] - point1[0])*(coordinate_y - point1[1]) ) > 0
        ) == flag1
    )
    coordinate_x = coordinate_x[choose_matrix]
    coordinate_y = coordinate_y[choose_matrix]
    choose_matrix = (
        (
            ( (coordinate_x - point2[0])*(cross_point[1] - point2[1]) - (cross_point[0] - point2[0])*(coordinate_y - point2[1]) ) > 0
        ) == flag2
    )
    coordinate_x = coordinate_x[choose_matrix]
    coordinate_y = coordinate_y[choose_matrix]
    
    # choose the point inside ellipse
    # subsitute the point into two lines to compute transformed x^2 and y^2 then subsitute into ellipse function to judge
    half_axis1_pow = (point1[0] - cross_point[0])**2 + (point1[1] - cross_point[1])**2
    half_axis2_pow = (point2[0] - cross_point[0])**2 + (point2[1] - cross_point[1])**2
    if half_axis1_pow == 0 or half_axis2_pow == 0 :
        print(filename)
        raise TypeError
    choose_matrix = (
        np.square((coordinate_x - point1[0])*(cross_point[1] - point1[1]) - (cross_point[0] - point1[0])*(coordinate_y - point1[1]))
        / ((cross_point[1] - point1[1])**2 + (cross_point[0] - point1[0])**2) 
        / half_axis2_pow
        +np.square((coordinate_x - point2[0])*(cross_point[1] - point2[1]) - (cross_point[0] - point2[0])*(coordinate_y - point2[1]))
        / ((cross_point[1] - point2[1])**2 + (cross_point[0] - point2[0])**2)
        / half_axis1_pow
        < 1
    )
    coordinate_x = coordinate_x[choose_matrix]
    coordinate_y = coordinate_y[choose_matrix]

    '''
    judge = xxxxxx -> (512,512) bool
    coordinate_x = coordinate_x[judge]  -> (N,)
    coordinate_y = coordinate_y[judge]  -> (N,)
    '''

    mask = np.zeros((512,512)).astype(bool)
    # deeplesion mask horizontal as x while numpy use the second axis as horizontal
    mask[coordinate_y, coordinate_x] = True
    return mask


def generate_mask(file_name, lesion_coordinates, output_path, append_flag):
    '''
    params:
     lesion_coordinates: [x11,y11,x12,y12,x21,y21,x22,y22]
    DO:
     get mask and save to output_path as png file
    '''
    # compute cross point
    cross_point = findIntersection(lesion_coordinates)
    # compute 4 part of mask
    mask = get_submask([lesion_coordinates[0],lesion_coordinates[1]], [lesion_coordinates[4],lesion_coordinates[5]], cross_point, file_name)
    mask += get_submask([lesion_coordinates[0],lesion_coordinates[1]], [lesion_coordinates[6],lesion_coordinates[7]], cross_point, file_name)
    mask += get_submask([lesion_coordinates[2],lesion_coordinates[3]], [lesion_coordinates[4],lesion_coordinates[5]], cross_point, file_name)
    mask += get_submask([lesion_coordinates[2],lesion_coordinates[3]], [lesion_coordinates[6],lesion_coordinates[7]], cross_point, file_name)
    
    mask = mask.astype(int)
    # expand to 3 channels (512,512,3)
    # mask = np.expand_dims(mask, axis=2)
    # mask = np.repeat(mask, 3, axis=2)
    
    # save as image
    if append_flag == True:
        original_mask = cv2.imread(os.path.join(output_path, file_name))
        mask = original_mask[:,:,0] + mask
    cv2.imwrite(os.path.join(output_path, file_name), mask)



if __name__ == '__main__':

    if not os.path.exists(output_path):
        os.makedirs(output_path)
    ann = pd.read_csv(ann_file_path)
    # record line index that need to add multilesion
    filename = ''
    append_idx = []
    for index, row in ann.iterrows():
        if filename == row['File_name']:
            append_idx.append(index)
        filename = row['File_name']

    for index, row in ann.iterrows():
        append_flag = False
        if index in append_idx:
            append_flag = True
        linestr = row["Measurement_coordinates"]
        lesion_coordinates = linestr.split(",")
        lesion_coordinates = [float(i) for i in lesion_coordinates] # [x11,y11,x12,y12,x21,y21,x22,y22]
        generate_mask(row["File_name"], lesion_coordinates, output_path, append_flag)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值