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)
根据deeplesion给的官方标注文件的 Measurement_coordinates 生成伪mask的代码
最新推荐文章于 2022-11-15 13:11:41 发布