Switch to unified view

a b/Segmentation_PDF_Generation.py
1
# %% importing packages
2
3
import numpy as np
4
from skimage import measure
5
from skimage import morphology
6
from skimage import segmentation
7
from scipy import ndimage
8
import cv2 as cv
9
import os
10
import matplotlib.pyplot as plt
11
import tqdm
12
import random
13
from glob import glob
14
from natsort import natsorted
15
from fpdf import FPDF
16
plt.rcParams['figure.figsize'] = [50, 150]
17
18
19
# %% Sources
20
#############################################################
21
#############################################################
22
23
# https://pypi.org/project/img2pdf/
24
# https://stackoverflow.com/questions/57576686/how-to-overlay-segmented-image-on-top-of-main-image-in-python
25
# https://stackoverflow.com/questions/27327513/create-pdf-from-a-list-of-images
26
# https://docs.opencv.org/3.4/d4/d73/tutorial_py_contours_begin.html
27
28
# Defining Functions
29
#############################################################
30
#############################################################
31
32
def filter_fun_vasculature(file_name:str):
33
    '''I realize this isn't very functional programming, but this function
34
    is paired with the "filter_fun_nerves" function for filtering file names
35
    according to the class for which the tile was selected using the 
36
    DatasetCreation.py file'''
37
    class_id = 'vasc_seg'
38
    
39
    if class_id in file_name:
40
        return(True)
41
    else:
42
        return(False)
43
44
#############################################################
45
46
def filter_fun_nerves(file_name:str):
47
    '''Performs filtering of file names according to the class for which the
48
    tile was selected when using the DatasetCreation.py file'''
49
    class_id = 'neural_seg'
50
    
51
    if class_id in file_name:
52
        return(True)
53
    else:
54
        return(False)
55
56
57
#############################################################
58
59
60
def sample_image_names_from_directory(directory,number_of_samples):
61
    '''Randomly selects number_of_samples file names of each of the two 
62
    different classes (vasculature and neural) from the sub_sampled
63
    dataset created by the DatasetCreation.py script. Returns those file 
64
    names.'''
65
66
    os.chdir(directory)    
67
    file_names = glob('./*.png')
68
    
69
    vasc_filt = filter(filter_fun_vasculature,file_names)
70
    nerve_filt = filter(filter_fun_nerves,file_names)
71
72
    vasc_image_names = list(vasc_filt)
73
    nerve_image_names = list(nerve_filt)
74
75
    rand_vasc_images = random.choices(vasc_image_names,k=number_of_samples)
76
    rand_nerve_images = random.choices(nerve_image_names,k=number_of_samples)
77
78
    random_image_names = rand_vasc_images + rand_nerve_images
79
80
    random.shuffle(random_image_names)
81
82
    return(random_image_names)
83
84
#############################################################
85
86
def create_segment_outline_image(image_name):
87
    '''Uses openCV to create an border for the segmentations of interest in the 
88
    image whose file name is provided as an argument. Returns an image with the 
89
    vasculature highlighted in red, and the neural tissue highlighted in 
90
    green.'''
91
92
    current_image = cv.imread(image_name,cv.IMREAD_UNCHANGED)
93
    color = current_image[:,:,0:3]
94
    # color = cv.cvtColor(color,cv.COLOR_BGR2RGB)
95
    seg = current_image[:,:,3]
96
    dilation_amount = 50
97
    vasculature = seg==5
98
    neural = seg==6
99
100
    vasculature = morphology.binary_dilation(
101
        vasculature,
102
        np.ones((dilation_amount,dilation_amount))
103
        )
104
105
    neural = morphology.binary_dilation(
106
        neural,
107
        np.ones((dilation_amount,dilation_amount))
108
        )
109
110
    vasc_contours,_heirarchy = cv.findContours(vasculature.astype(np.uint8),
111
                                               cv.RETR_EXTERNAL,
112
                                               cv.CHAIN_APPROX_NONE)
113
    
114
    neural_contours,_heirarchy = cv.findContours(neural.astype(np.uint8),
115
                                                 cv.RETR_EXTERNAL,
116
                                                 cv.CHAIN_APPROX_NONE)
117
118
    contoured_image = cv.drawContours(
119
        np.ascontiguousarray(color,np.uint8), vasc_contours, -1, (0,0,255), 10
120
        )
121
    contoured_image = cv.drawContours(
122
        contoured_image, neural_contours, -1, (0,255,0), 10
123
        )
124
    
125
126
    return(contoured_image)
127
128
#############################################################
129
130
def save_images_to_PDF(image_name_list,file_name,create_contour = True):
131
    '''Uses the above functions to save images sequentially to a PDF for use
132
    in validating the segmentations performed. The PDF has space at the bottom
133
    for adding check boxes in a separate program such as Adobe Acrobat.'''
134
135
    pdf = FPDF()
136
    pdf.set_auto_page_break(False)
137
    pdf.set_left_margin(margin=5)
138
139
    save_directory = dataset_directory + '/../PDF_images/'
140
141
    current_directory = os.getcwd()
142
143
    if not os.path.isdir(save_directory):
144
        os.mkdir(save_directory)
145
146
147
    for idx in tqdm.tqdm(range(len(image_name_list))):
148
        if create_contour:
149
            image_name = image_name_list[idx]
150
151
            contoured_image = create_segment_outline_image(image_name)
152
            
153
            image_name_split = image_name.split('/')[1].split('.')[0]
154
            new_image_name = image_name_split+'_outlined.png'
155
156
            os.chdir(save_directory)
157
            cv.imwrite(new_image_name,contoured_image)
158
159
            pdf.add_page(format=(610,350))
160
            pdf.image(new_image_name,h=300)
161
            os.chdir(current_directory)
162
        else:
163
            image_name = image_name_list[idx]
164
            pdf.add_page(format=(610,350))
165
            pdf.image(image_name,h=300)
166
167
    os.chdir(save_directory)
168
169
    pdf.output(file_name,'F')
170
171
    return(True)
172
173
#############################################################
174
#############################################################
175
# %%
176
177
dataset_directory = '/var/confocaldata/HumanNodal/HeartData/08/01/PDFImages'
178
179
filtered_names = sample_image_names_from_directory(dataset_directory,20)
180
181
save_images_to_PDF(filtered_names,'test_file.pdf',create_contour=False)
182
183
# %%