# Modelo Computacional para Detectar Micrometástases em Câncer de Mama - 2022/02
## Classificacao
### Comparacao de levels
#### Slide 110
- x=16000, y=24000, level=3, width=224, height=224

- x=16000, y=24000, level=0, width=1792, height=1792

- x=16000, y=24000, level=3, width=224, height=224

- x=16000, y=24000, level=4, width=112, height=112

**Level_3 vs Level_0 - 224px**

### Comparacao de corte central
#### Slide 110
A parte central desta imagem nao esta anotada, ainda assim, 112 é talvez uma boa magem de seguranca visto que ainda ha pixels positivos na imagem central... Avaliar se a imagem central precisa ser ainda menor.
```python
patchSize = 224
croppedCentralSize = round(patchSize/2) = 112
strideCroppedCentral = round(patchSize/4) = 56
```
Opções
- Dimimuir a parte central
- Percentual dentro da parte central de 112
- Mascara 224
```python
centerCroppedMask = read_slide(tumor_mask,
x=16896,
y=24896,
level=0,
width=224,
height=224)
```

- Mascara central 112
```python
# para x e y acrecentar metade de 112 que é metade de 224
centerCroppedMask = read_slide(tumor_mask,
x=16952,
y=24952,
level=0,
width=112,
height=112)
```

- Slide 224

- Slide central de 112px
- 
#### Imagem é majoritariamente negativa, ainda assim rotulada como positiva
Referencia: Image = 110_23296_51296 | Pasta = 224px_level0_vs01
- Patch 224x224px

- Centro da imagem 112x112px referencia para o rotulo (pequeno pedaço positivo canto superior direito)
 
- Comparação

### Comparacao de Background removal and Stain norm
#### Slide 110
``` python
slide_image = read_slide(slide,
x=16896,
y=24896,
level=0,
width=224,
height=224)
norm_img = normalizeStaining(img = slide_image)
# Background removal
rgb = slide_image
mask = grays_filter(rgb) # the mask is important, the background_removal_img is just to plot
background_removal_img = rgb * np.dstack([mask, mask, mask]) # not import, just to plot
# Stain normalization image result + background removal mask to remove the background
img_result = norm_img * np.dstack([mask, mask, mask])
plt.figure(figsize=(8,8))
plt.imshow(img_result) # norm_img / slide_image
```



```python
patchSize = 224
croppedCentralSize = round(patchSize/4) = 56
strideCroppedCentral = round((patchSize - croppedCentralSize)/2) = 84
```
i = 36064
j = 59136




i = 25760
j = 41216


### Numero de patchs positivos
#### Pasta 224px_level0_vs02
- Esta pasta contem patchs de level=0 e 224x224px
- possui normalizacao de cores
- Background nao foi removido
- 56x56px é o tamanho do centro da mascara utilizado para rotular se ao menos 1px é positivo
``` python
###### CONFIGURACOES DO PATCH ######
LEVEL = 0
slideWidth = slide.level_dimensions[LEVEL][0]
slideHeight = slide.level_dimensions[LEVEL][1]
patchSize = 224
croppedCentralSize = round(patchSize/4)
strideCroppedCentral = round((patchSize - croppedCentralSize)/2)
numPatchesX = math.floor(slideWidth/224) - 1
numPatchesY = math.floor(slideHeight/224) - 1 # round down
```
#### Numero de patchs gerados por cada slide - treinamento
* 110 = 11620 positivos
* 107 = 105 positivos
* 007 = 63 positivos
* 009 = 17137 positivos
* 011 = 4314 positivos
* 013 = 162 positivos
* 015 = 271 positivos
* 023 = 47 positivos
* 024 = 26 positivos
* 026 = 3339 positivos
* 027 = 61 positivos
* 028 = 48 positivos
* 030 = 8 positivos
* 031 = 2757 positivos
* 032 = 75 positivos
* 033 = 2035 positivos
* 033 = 2035 positivos => 42069
* 000 = xx positivos
* 000 = xx positivos
* 000 = xx positivos
* 000 = xx positivos
#### Numero de patchs gerados por cada slide - validacao
* 014 = xx positivos
* 016 = xx positivos
* 018 = xx positivos
* 019 = xx positivos
* 020 = 1673 positivos
* 021 = 733 positivos
* 022 = 106 positivos
* 025 = 1629 positivos
* 029 = xx positivos
* 034 = xx positivos
* 042 = 924 positivos
* 063 = 36 positivos
* 065 = 49 positivos
* 074 = 70 positivos
* 097 = 70 positivos
* 100 = 124 positivos
* 108 = 1464 positivos
---
#### Normal (treinamento)
normal_001 = 794
normal_007 = 1315
029 = 661
036 =2670
055 = 1938
065 = 1998
067 = 2751
077 =1660
084_79072_134400.jpg = 479
089_40544_94752.jpg = 3000
093_89376_142912.jpg = 2350
100_84224_168224.jpg = 2306
105_69440_65184.jpg = 3000
107_106848_19936.jpg = 2343
113_149856_13216.jpg = 3000
126_82880_38304.jpg = 3000
132_111104_50624.jpg = 3000
137_111776_26880.jpg = 3000
158_103264_57120.jpg = 3000
160_97216_38752.jpg = 3000
TOTAL = 45610
#### Normal - Negative (val)
003_96320_198464.jpg = 1940
024_81760_75936.jpg = 2254
060 = 562
150_56224_37856.jpg = 1681
090_66304_135296.jpg = 3000
Total = 9436 > balanced to 6600
#### Normal - Negative (test)
003_80864_107968.jpg = 1539
005_70784_191072.jpg = 1133
012_120736_60480.jpg = 2725
028_106624_20832.jpg = 3000
035_86464_135520.jpg = 2970
050_65184_88704.jpg = 3000
#### Tumor - positive (test)
001 = 0
002 = 759
010 = 14
026 = 0
030 = 266
051 = 1441
068 = 3332
### Pasta 224px_level0_vs01
- Esta pasta contem patchs de level=0 e 224x224px
- possui normalizacao de cores
- Background nao foi removido
- 112x112px é o tamanho do centro da mascara utilizado para rotular se ao menos 1px é positivo
``` python
###### CONFIGURACOES DO PATCH ######
LEVEL = 0
slideWidth = slide.level_dimensions[LEVEL][0]
slideHeight = slide.level_dimensions[LEVEL][1]
patchSize = 224
croppedCentralSize = round(patchSize/2) # 112
strideCroppedCentral = round((patchSize - croppedCentralSize)/2)
numPatchesX = math.floor(slideWidth/224)
numPatchesY = math.floor(slideHeight/224) # round down
```
#### Numero de patchs gerados por cada slide
##### Slide 110 gerou 11842 positivos
### Negative slides
##### Slide 001 gerou 79 negativos
Minimo de 75% de tecido nao branco para normal patches entrarem na conta e serem considerados no treinamento. This is an empirico value dues some observations.
* Example of 76.02638711734694 % of non zero tissues (percentTissuePixel) => normal_100 x=55192 y=180000

* Example of 96.63052721088435 % of non zero tissues (percentTissuePixel) => normal_100 x=67192 y=180000

* 48.00435799319728% tissue => normal_100 x=76192 y=180000

* 87.71059204931973% tissue => normal_100 x=75692 y=180000

* 66.32254464285714 => normal_100 x=76192 y=180300

* 66.2109375 => normal_100x=39192, y=156165,

* 79.28890306122449 => normal_100 x=39192, y=155965,

* 74.91430165816327 => normal_100 x=76192, y=180365,

```python
patch_image = read_slide(slide,
x=55192,
y=180000,
level=0,
width=224,
height=224)
```
```python
mask = grays_filter(patch_image)
img_result = patch_image * np.dstack([mask, mask, mask])
isAllBlack = np.all((img_result == 0))
qtyTissuePixel = np.count_nonzero(img_result)
percentTissuePixel = ((qtyTissuePixel/3)/(patchSize*patchSize))*100 # 3 channels
if(not isAllBlack and percentTissuePixel > 75):
# normalize, label and save patch
```
## isPatchNotFullPositive
Tensorflow esta negativando os patchs que são full positivos ao fazer o dataloader das images. Portanto estou cortando apenas as images com um limite maximo que seja inferior a totalidade do patch, eliminando os patches 100% positivos. Abaixo alguns exeplos de limite de corte 150000
```python
#150528 = (224*224*3) minus 528 as margin of 14px
def isPatchNotFullPositive(patch):
qty_positive_pixel = np.count_nonzero(patch)
if(qty_positive_pixel < 150000):
return True
else:
return False
```



## Segmentacao
FIGURAS SEM MASCARS
44 - 48 - 49 - 56
### Treinamento
* 001 = 265 patches
* 012 = 29 patches
* 106 = 1835 patches
* 053 = 21 patches
* 035 = 10 patches
* 025 = 1700 patches
* 020 = XXX patches
* 041 = XXX patches
* 024 = XXX patches
* 059 = XXX patches
* 103 = XXX patches
* 109 = XXX patches
* 080
* 095
* 063
* 074
003
004
007
010
019
022
028
038
050
057
088
094
107
['001','003','004','007','010','012','019','022','020','024','025','028','035','038','041','050','053','057','059','063','074','080','088','094','095''103','106','107','109']
### Validacao
* 005 = 66 patches
* 008 = 23 patches
* 069 = 232 patches
* 100 = 133 patches
* 021
* 037
* 078
* 105
* 011
* 026
* 081
* 093
* 099
* 108
TUMOR_SLIDES_ARRAY = ['005','008','011','021','026','037','069','078','081','093','099','100','108','105']
### Test
* 016 = 3371 patches
* 040 = 25 patches
* 061 = 2510 patches
* 094 = 1320 patches
* 087 = 99 patches
#### Slides
* 068 = XXX patches
* 069 = XXX patches
* 072 = XXX patches
* 073 = XXX patches
* 075 = XXX patches
* 103 = XXX patches
['016','040','061','068','069','072','073','075','103']
### Data arrays
train = ['001','002','003','004','006','007','009','010',
'012','013','014','015','017','018','019','020','022','023','024','025','027','028','029','030','031','032','033','034','035','036','038','039',
'041','042','043','045','046','047','050','053','054','055','057','059','060','062','063','064','065','066','067','070','071','074','075','076','077','079','080','082','083','084','085','086','087','088','089','090','091','092','094','095','096','097','098','101','102','104','106','107',109']
'075', '094', '087', '106'
'110']
val = ['005','008','011','021','026','037','069','078','081','093','099','100','105','108']
teste = ['016','040','051','052','058','061','068','072','073','103']
'058', '061', '068', '072', '073', '103'
Last patch_name 001_73024_124992.jpg
numOfPatches= 428910
numOfPositivesPatches= 265
numOfExtractedPatches= 102
Last patch_name 002_47264_104384.jpg
numOfPatches= 425865
numOfPositivesPatches= 24
numOfExtractedPatches= 19
Last patch_name 003_80864_153664.jpg
numOfPatches= 428910
numOfPositivesPatches= 180
numOfExtractedPatches= 100
Last patch_name 004_76832_96992.jpg
numOfPatches= 428040
numOfPositivesPatches= 740
numOfExtractedPatches= 205
Last patch_name 006_60928_176288.jpg
numOfPatches= 428910
numOfPositivesPatches= 65
numOfExtractedPatches= 54
Last patch_name 007_32480_105728.jpg
numOfPatches= 428910
numOfPositivesPatches= 74
numOfExtractedPatches= 59
Last patch_name 009_85792_79968.jpg
numOfPatches= 421080
numOfPositivesPatches= 17274
numOfExtractedPatches= 924
Last patch_name 010_72576_110656.jpg
numOfPatches= 418035
numOfPositivesPatches= 16
numOfExtractedPatches= 16
= 1479
## Correções Professores
### Rafael
- [ ] 1) Evitar o uso de primeira pessoa no texto científico. Além disso, é necessária uma
revisão cuidadosa da escrita, visto que pequenos erros são presentes em várias partes
do texto.
> *Texto sera traduzido para o ingles possivelmente*
- [x] 2) Na introdução, antes da apresentação da questão de pesquisa, seria interessante justificar a escolha de rede neural convolucional.
> Parcialmente checked: Coloquei na apresentacao mas vou colocar na versao final do trabalho com os resultados finais
- [x] 3) Os objetivos específicos do trabalho não foram apresentados.
> *Avaliar com o professor*
> - Compreender os dados e identificar quais características são relevantes para que seja possível treinar um Modelo de Aprendizado Profundo utilizando Imagens de Lâmina Inteira - WSI (do inglês Whole-Slide-Image).
> - Analisar se uma Rede Neural Convolucional é capaz de aprender as características para identificar células ou conjunto de células metastáticas muito pequenas, na escala de milímetros e micro milímetros, em imagens de altíssima resolução.
> - Estudar os processos de pré-processamento de imagens necessários para auxiliar o modelo a alcançar os melhor resultados baseados na linha de base proposta.
> - Explorar a literatura em busca de trabalhos na área, limitações e oportunidades.
> - Explorar a literatura em para identificar as métricas relevantes para comparar o modelo proposto e definir uma linha de base de modo a verificar se o mesmo tem potencial para atingir os objetivo proposto.
- [x] 4) Na introdução, seria importante apresentar as principais abordagens relacionadas e seus gaps. Além disso, como existem resultados iniciais,
> Parcialmente checked: Coloquei na apresentacao mas vou colocar na versao final do trabalho com os resultados finais
- [ ] 5) O capítulo 2 é bastante extenso. Em especial, a parte relativa a Inteligência Artificial
apresenta conceitos bastante básicos e, eventualmente, não necessários para
compreensão da proposta. Sendo assim, sugere-se verificar a necessidade de manter
todos os conceitos no volume final da dissertação.
> *Avaliar com o professor*
- [ ] 6) A aluna utiliza os termos aprendizado pronfudo e deep learning. Seria importante
padronizar em apenas um deles.
> *Texto sera traduzido para o ingles possivelmente*
- [ ] 7) Boa revisão de literatura, apresentando claramente a metodologia e realizando uma
boa análise dos trabalhos relacionados. No entanto, a discussão apresentada neste
capítulo é um pouco tímida. Seria importante aprofundá-la, destacando e discutindo
em detalhes os gaps que serão explorados pela dissertação.
> *Acrescentar tambem quadro comparativo sugerido pelo CAC*
- [x] 8) É importante justificar a escolha da string de busca inicial, visto que, aparentemente,
pode ser bastante abrangente.
- [x] 9) Como foi mensurada a relevância dos artigos no processo de revisão da literatura?
- [ ] 10) Justificar a escolha do tamanho de imagem (256x256 pixels) -
> *Este valor sera alterado para 224 pois é uma relacao (1792/896/448/224) entre o tamanho 1792 pixel, que na imagem original representa 1 mm.*
## Próximos passos:
- [x] Slides apresentação. Prazo: 18/09/2022
- [ ] Refatorar código e deixá-lo pronto para o cluster. Prazo: 21/09/2022.
- [ ] Prévia apresentação. Prazo: 23/09/2022.
- [ ] Seminário de andamento. Prazo: 27/09/2022.
- [ ] Treinar modelo de classificação com dataset novo. Prazo: 02/10/2022.
- [ ] Construir rede de segmentação. Prazo: 12/10/2022.
- [ ] Treinar rede de segmentação. Prazo: 27/10/2022.
- [ ] Análise de resultados. Prazo: 29/10/2022.
- [ ] Organizar estrutura artigo. Prazo: 31/10/2022.
- [ ] Inicio de dezembro de artigo
- [ ] toda sexta um update