Diff of /scripts/DABanalysis.py [000000] .. [c52ce0]

Switch to unified view

a b/scripts/DABanalysis.py
1
import numpy as np
2
import os
3
from natsort import natsorted
4
import pandas as pd
5
from skimage.color import rgb2hsv, rgb2gray
6
from skimage.filters import gaussian, threshold_triangle
7
from skimage.exposure import rescale_intensity
8
from PyQt5.QtCore import QThread, pyqtSignal
9
from PIL import Image
10
11
12
class DabAnalysis(QThread):
13
14
    maxcuts = pyqtSignal(int)
15
    info = pyqtSignal(str)
16
    countChanged = pyqtSignal(int)
17
    figures = pyqtSignal()
18
    activate = pyqtSignal(bool)
19
20
    def __init__(self, path, save=False):
21
        super().__init__()
22
        self.inputpath = path
23
        self.save = save
24
        self.threshold = None
25
26
    def run(self, debug=False):
27
        self.activate.emit(False)
28
        analysis = []
29
        files = [f for f in natsorted(os.listdir(self.inputpath)) if not f.endswith("Overlay.png")]
30
        self.maxcuts.emit(len([f for f in files if f.endswith('.png')]))
31
        i = 0
32
        for file in files:
33
            if file.endswith('.png'):
34
                self.info.emit("Analysing "+file)
35
                print(file)
36
                info = []
37
                image = np.array(Image.open(self.inputpath+os.sep+file))[:, :, :3]
38
                self.current_image = image[::10, ::10]
39
                self.figures.emit()
40
                info.append(str(file))
41
                info.extend(self.QuantStain(image, filename=file, save=self.save))
42
                info.append(self.QuantCore(image, filename=file, save=self.save))
43
                analysis.append(info)
44
                print(info)
45
                self.countChanged.emit(int(i)+1)  # EMIT the loading bar
46
            self.info.emit(file + " analysed")
47
            i += 1
48
        # TODO can make this more lightweight by removing pandas and using csv
49
        df = pd.DataFrame(analysis, columns=('CoreName', 'AMTsignal', 'Mean_intensity', 'Standard_Dev_intensity',
50
                                             'AMTtissue'))
51
        df['AFperAMTT'] = df['AMTsignal']/df['AMTtissue']*100
52
        df['Mean_Intensity_perAMTT'] = df['Mean_intensity'] / df['AMTtissue'] * 100
53
        df['SD_Intensity_perAMTT'] = df['Standard_Dev_intensity'] / df['AMTtissue'] * 100
54
        df.to_excel(self.inputpath+os.sep+'CoreAnalysis_'+str(df['CoreName'][0])[:-6]+'.xlsx')
55
        self.info.emit("All Files Analysed - ready")
56
        self.activate.emit(True)
57
58
    def QuantStain(self, image, filename, save=False):
59
        img_hsv = rgb2hsv(image)
60
        img_hue = img_hsv[:, :, 0]
61
        image_sat = img_hsv[:, :, 1]
62
        hue = np.logical_and(img_hue > 0.02, img_hue < 0.10)  # BROWN PIXELS BETWEEN 0.02 and 0.10
63
        if self.threshold:
64
            stain = np.logical_and(hue, image_sat > self.threshold)
65
        else:
66
            print("normal threshold")
67
            stain = np.logical_and(hue, image_sat > 0.79)
68
        # TODO : fix this - sent bug report to Github
69
        self.current_image = stain[::10, ::10].astype(float)
70
        self.figures.emit()
71
        if save:
72
            self.info.emit("Saving - " + filename+'_stain.tiff')
73
            imagesave = Image.fromarray(stain)
74
            imagesave.save(self.inputpath+os.sep+filename+'_stain.tiff')
75
        stint = np.copy(image)
76
        stint = rgb2gray(stint)
77
        stint = rescale_intensity(stint, out_range=(0, 255))
78
        stint[stain == 0] = 0  # array with only the stained pixels
79
        stint = np.ravel(stint)
80
        stint = stint[stint != 0]
81
        stint_mean = stint.mean()
82
        stint_std = stint.std()
83
        stained = np.sum(stain)
84
        return stained, stint_mean, stint_std
85
86
    def QuantCore(self, image, filename, save=False):
87
        image = gaussian(rgb2gray(image), sigma=2)
88
        thresh = threshold_triangle(image[image > 0])
89
        binary = np.logical_and(image < thresh, image > 0)
90
        wholeCore = np.sum(binary)
91
        if save:
92
            self.info.emit("Saving - " + filename + '_core.tiff')
93
            imagesave = Image.fromarray(binary)
94
            imagesave.save(self.inputpath+os.sep+filename + '_core.tiff')
95
        return wholeCore