# 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 ![](https://i.imgur.com/h2qyBgY.png) - x=16000, y=24000, level=0, width=1792, height=1792 ![](https://i.imgur.com/xVdJLDh.png) - x=16000, y=24000, level=3, width=224, height=224 ![](https://i.imgur.com/x0WfTYv.png) - x=16000, y=24000, level=4, width=112, height=112 ![](https://i.imgur.com/n0Hx6FZ.png) **Level_3 vs Level_0 - 224px** ![](https://i.imgur.com/t5rrhT4.png) ### 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) ``` ![](https://i.imgur.com/dQJ6wC9.png) - 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) ``` ![](https://i.imgur.com/9Y6yTnW.png) - Slide 224 ![](https://i.imgur.com/Ig73rqy.png) - Slide central de 112px - ![](https://i.imgur.com/zQId5wj.png) #### Imagem é majoritariamente negativa, ainda assim rotulada como positiva Referencia: Image = 110_23296_51296 | Pasta = 224px_level0_vs01 - Patch 224x224px ![](https://i.imgur.com/L6EhWJ4.jpg) - Centro da imagem 112x112px referencia para o rotulo (pequeno pedaço positivo canto superior direito) ![](https://i.imgur.com/6abCdBE.jpg) ![](https://i.imgur.com/K7URwkP.png) - Comparação ![](https://i.imgur.com/RXpNF8f.png) ### 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 ``` ![](https://i.imgur.com/BbyOotk.png) ![](https://i.imgur.com/nnbmCKU.png) ![](https://i.imgur.com/qkBGDOD.png) ```python patchSize = 224 croppedCentralSize = round(patchSize/4) = 56 strideCroppedCentral = round((patchSize - croppedCentralSize)/2) = 84 ``` i = 36064 j = 59136 ![](https://i.imgur.com/xTocsFt.png) ![](https://i.imgur.com/lKMd5DJ.png) ![](https://i.imgur.com/oYTEAUJ.png) ![](https://i.imgur.com/E5ytIbv.png) i = 25760 j = 41216 ![](https://i.imgur.com/QPWgVV1.jpg) ![](https://i.imgur.com/q8g0nBn.jpg) ### 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 ![](https://i.imgur.com/GmZteG8.png) * Example of 96.63052721088435 % of non zero tissues (percentTissuePixel) => normal_100 x=67192 y=180000 ![](https://i.imgur.com/EslTM9s.png) * 48.00435799319728% tissue => normal_100 x=76192 y=180000 ![](https://i.imgur.com/d4ZIWWb.png) * 87.71059204931973% tissue => normal_100 x=75692 y=180000 ![](https://i.imgur.com/MgkfpqS.png) * 66.32254464285714 => normal_100 x=76192 y=180300 ![](https://i.imgur.com/MrZAaJD.png) * 66.2109375 => normal_100x=39192, y=156165, ![](https://i.imgur.com/mL2P9zy.png) * 79.28890306122449 => normal_100 x=39192, y=155965, ![](https://i.imgur.com/Dr7YFBS.png) * 74.91430165816327 => normal_100 x=76192, y=180365, ![](https://i.imgur.com/9ph0KJC.png) ```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 ``` ![](https://i.imgur.com/6BTD18Y.png) ![](https://i.imgur.com/SCRu3lu.png) ![](https://i.imgur.com/5Wd5cFw.png) ## 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