{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom skimage.io import imread, imshow\nfrom skimage.draw import disk\n#from skimage.morphology import closing, opening\nfrom skimage.color import rgb2gray\nfrom scipy.ndimage import gaussian_filter\nfrom PIL import Image, ImageFilter\n#from skimage.filters import frangi, hessian\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2023-08-01T17:21:02.376872Z","iopub.execute_input":"2023-08-01T17:21:02.377385Z","iopub.status.idle":"2023-08-01T17:21:03.275931Z","shell.execute_reply.started":"2023-08-01T17:21:02.377295Z","shell.execute_reply":"2023-08-01T17:21:03.274808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ALMACENAMIENTO DEL DATASET 2019","metadata":{}},{"cell_type":"markdown","source":"En primer lugar, es necesario importar el archivo csv con los ids y diagnósticos para las imágenes de entrenamiento de la competencia \"APTOS 2019 BLINDNESS DETECTION\": https://www.kaggle.com/competitions/aptos2019-blindness-detection/overview","metadata":{}},{"cell_type":"code","source":"#IMPORTACIÓN DATASET CSV\ntrain_ds = pd.read_csv('/kaggle/input/aptos2019-blindness-detection/train.csv')\n\nprint(\"INFORMACIÓN IMPORTADA\")","metadata":{"execution":{"iopub.status.busy":"2023-08-01T17:21:05.511120Z","iopub.execute_input":"2023-08-01T17:21:05.511491Z","iopub.status.idle":"2023-08-01T17:21:05.536202Z","shell.execute_reply.started":"2023-08-01T17:21:05.511463Z","shell.execute_reply":"2023-08-01T17:21:05.535011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Ahora, se guarda la columna con los ids en la variable \"X_ds\" y los diagnósticos en \"y_ds\". Después, con ello, se seccionan en listas los nombres de las imágenes para separarlos según el diagnóstico que le corresponda (0, 1, 2, 3 o 4).","metadata":{}},{"cell_type":"code","source":"X_ds = train_ds['id_code']\ny_ds = train_ds['diagnosis']\n\nX0_ids = []\nX1_ids = []\nX2_ids = []\nX3_ids = []\nX4_ids = []\n\nfor i in range(X_ds.shape[0]):\n    if(y_ds[i] == 0):\n        X0_ids.append(X_ds.iloc[i])\n    elif(y_ds[i] == 1):\n        X1_ids.append(X_ds.iloc[i])\n    elif(y_ds[i] == 2):\n        X2_ids.append(X_ds.iloc[i])\n    elif(y_ds[i] == 3):\n        X3_ids.append(X_ds.iloc[i])\n    elif(y_ds[i] == 4):\n        X4_ids.append(X_ds.iloc[i])\n\nprint(len(X0_ids))\nprint(len(X1_ids))\nprint(len(X2_ids))\nprint(len(X3_ids))\nprint(len(X4_ids))\nprint(\"INFORMACIÓN SECCIONADA Y ALMACENADA\")","metadata":{"execution":{"iopub.status.busy":"2023-08-01T17:21:07.353805Z","iopub.execute_input":"2023-08-01T17:21:07.354229Z","iopub.status.idle":"2023-08-01T17:21:07.462557Z","shell.execute_reply.started":"2023-08-01T17:21:07.354197Z","shell.execute_reply":"2023-08-01T17:21:07.461621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ALMACENAMIENTO DEL DATASET 2015/2019","metadata":{}},{"cell_type":"markdown","source":"Lo siguiente es para realizar lo mismo que lo anterior, pero ahora obteniendo el csv y las imágenes de otro dataset.","metadata":{}},{"cell_type":"code","source":"#IMPORTACIÓN DATASET CSV\ntrain_ds = pd.read_csv('/kaggle/input/resized-2015-2019-diabetic-retinopathy-detection/labels/traintestLabels15_trainLabels19.csv')\n\nprint(\"INFORMACIÓN IMPORTADA\")","metadata":{"execution":{"iopub.status.busy":"2023-07-30T17:15:27.056751Z","iopub.execute_input":"2023-07-30T17:15:27.057139Z","iopub.status.idle":"2023-07-30T17:15:27.161052Z","shell.execute_reply.started":"2023-07-30T17:15:27.057084Z","shell.execute_reply":"2023-07-30T17:15:27.159676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_ds = train_ds['image']\ny_ds = train_ds['level']\n\nX0_ids = []\nX1_ids = []\nX2_ids = []\nX3_ids = []\nX4_ids = []\n\nfor i in range(X_ds.shape[0]):\n    if(y_ds[i] == 0):\n        X0_ids.append(X_ds.iloc[i])\n    elif(y_ds[i] == 1):\n        X1_ids.append(X_ds.iloc[i])\n    elif(y_ds[i] == 2):\n        X2_ids.append(X_ds.iloc[i])\n    elif(y_ds[i] == 3):\n        X3_ids.append(X_ds.iloc[i])\n    elif(y_ds[i] == 4):\n        X4_ids.append(X_ds.iloc[i])\n\nprint(len(X0_ids))\nprint(len(X1_ids))\nprint(len(X2_ids))\nprint(len(X3_ids))\nprint(len(X4_ids))\nprint(\"INFORMACIÓN SECCIONADA Y ALMACENADA\")","metadata":{"execution":{"iopub.status.busy":"2023-07-30T17:15:28.091189Z","iopub.execute_input":"2023-07-30T17:15:28.092291Z","iopub.status.idle":"2023-07-30T17:15:29.418540Z","shell.execute_reply.started":"2023-07-30T17:15:28.092238Z","shell.execute_reply":"2023-07-30T17:15:29.417743Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DETECCIÓN DE EXUDADOS","metadata":{}},{"cell_type":"markdown","source":"El siguiente procesamiento de las imágenes sirve para detectar los exudados en los exámenes de fondos de ojo, esto al seguir el procedimiento propuesto en el siguiente artículo: https://www.researchgate.net/publication/343981785. Puede ser útil para clasificar entre pacientes enfermos y sanos. No obstante, no rescata detalles suficientes para determinar la severidad de retinopatía diabética.","metadata":{}},{"cell_type":"code","source":"tamano_img = 224\nimg_path = \"/kaggle/input/resized-2015-2019-diabetic-retinopathy-detection/resized_traintest15_train19/\"+X0_ids[0]+\".jpg\"\nimage = cv2.imread(img_path)\nif (image is not None):\n#IMAGE EXTRACTION\n    image = cv2.resize(image, (tamano_img, tamano_img)) #redimensionar las imgs\n    image1 = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n    image1 = image1.reshape(tamano_img, tamano_img, 1) #indicar el tamaño de la imagen y los canales\n\n#PREPROCESSING\n    Fmax = image1.max()\n    Fmin = image1.min()\n    df = Fmax - Fmin\n    T = 0.95 * Fmax \n    \n    m = (image1-Fmin) / df #Fuzzification 0-1\n    mp = np.where(m < 0.5, 2*(m**2), 1-(2*((1-m)**2))) #Memebership modification\n    Fp = Fmin + (mp*df) #Deffuzification Fmin-Fmax\n    g = np.where(Fp < T, 0, 1) #Segmentation\n\nprint(Fmin, Fmax, T)","metadata":{"execution":{"iopub.status.busy":"2023-08-01T17:21:19.654142Z","iopub.execute_input":"2023-08-01T17:21:19.654577Z","iopub.status.idle":"2023-08-01T17:21:19.730446Z","shell.execute_reply.started":"2023-08-01T17:21:19.654545Z","shell.execute_reply":"2023-08-01T17:21:19.729564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(3,2, figsize=(12,20))\n\nax[0, 0].imshow(image)\nax[0, 1].imshow(image1, cmap = 'gray')\nax[1, 0].imshow(m, cmap='gray')\nax[1, 1].imshow(mp, cmap = 'gray')\nax[2, 0].imshow(Fp, cmap='gray')\nax[2, 1].imshow(g, cmap = 'gray')","metadata":{"execution":{"iopub.status.busy":"2023-08-01T17:21:21.461103Z","iopub.execute_input":"2023-08-01T17:21:21.461826Z","iopub.status.idle":"2023-08-01T17:21:23.544891Z","shell.execute_reply.started":"2023-08-01T17:21:21.461779Z","shell.execute_reply":"2023-08-01T17:21:23.544034Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# PROCESAMIENTO CON CROP","metadata":{}},{"cell_type":"markdown","source":"Otra forma que obtener las características de las imágenes es la siguiente:\n\nLos siguientes métodos realizan un procesamiento distinto de las imágenes. En primer lugar, la función crop_image_from_gray realiza un recorte de las imágenes, de manera que delimita la sección de la figura enfocandose solo en la parte del ojo, mientras que circle_crop crea una máscara volviendo circular aquellas imágenes que están más recortadas, logrando que todas las fotografías puedan verse de manera similar dimensionalmente para que el modelo se enfoque únicamente en las características internas de la retina y generan ruido los detalles del fondo de la imagen.","metadata":{}},{"cell_type":"code","source":"def crop_image_from_gray(img,low_bound=7):\n    if img.ndim ==2:\n        mask = img>low_bound\n        return img[np.ix_(mask.any(1),mask.any(0))]\n    elif img.ndim==3:\n        gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n        mask = gray_img>low_bound\n        \n        check_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]\n        if (check_shape == 0): # image is too dark so that we crop out everything,\n            return img # return original image\n        else:\n            img1=img[:,:,0][np.ix_(mask.any(1),mask.any(0))]\n            img2=img[:,:,1][np.ix_(mask.any(1),mask.any(0))]\n            img3=img[:,:,2][np.ix_(mask.any(1),mask.any(0))]\n    #         print(img1.shape,img2.shape,img3.shape)\n            img = np.stack([img1,img2,img3],axis=-1)\n    #         print(img.shape)\n        return img\n\ndef circle_crop(img, sigmaX=30):   \n    \"\"\"\n    Create circular crop around image centre    \n    \"\"\"    \n    img = crop_image_from_gray(img)    \n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    height, width, depth = img.shape    \n    \n    x = int(width/2)\n    y = int(height/2)\n    r = np.amin((x,y))\n    \n    circle_img = np.zeros((height, width), np.uint8)\n    cv2.circle(circle_img, (x,y), int(r), 1, thickness=-1)\n    img = cv2.bitwise_and(img, img, mask=circle_img)\n    img = crop_image_from_gray(img)\n    #img=cv2.addWeighted(img,4, cv2.GaussianBlur( img , (0,0) , sigmaX) ,-4 ,128) #Difuminación gausiana\n    return img ","metadata":{"execution":{"iopub.status.busy":"2023-08-01T17:24:22.431578Z","iopub.execute_input":"2023-08-01T17:24:22.432004Z","iopub.status.idle":"2023-08-01T17:24:22.446107Z","shell.execute_reply.started":"2023-08-01T17:24:22.431961Z","shell.execute_reply":"2023-08-01T17:24:22.445022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tamano_img = 224\nimg_path = \"/kaggle/input/aptos2019-blindness-detection/train_images/\"+X2_ids[182]+\".png\" #Guarda la ruta de la imagen\nimg = cv2.imread(img_path) #Lee la imagen\n\nimage = circle_crop(img) #Hace una máscara circular\nimage = cv2.resize(image, (tamano_img, tamano_img)) #redimensionar las imgs\nimage = image.reshape(tamano_img, tamano_img, 3) #Indica el tamaño en pixeles y sus canales (3 para color, 1 para gray)\n\nimage2 = crop_image_from_gray(img) #Recorta los bordes no deseados\nimage2 = cv2.resize(image2, (tamano_img, tamano_img)) #redimensionar las imgs\nimage2 = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB) #Pasar de BGR a RGB\nimage2 = image2.reshape(tamano_img, tamano_img, 3) #Indica el tamaño en pixeles y sus canales (3 para color, 1 para gray)","metadata":{"execution":{"iopub.status.busy":"2023-08-01T17:27:11.804432Z","iopub.execute_input":"2023-08-01T17:27:11.804879Z","iopub.status.idle":"2023-08-01T17:27:12.238154Z","shell.execute_reply.started":"2023-08-01T17:27:11.804846Z","shell.execute_reply":"2023-08-01T17:27:12.236976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(2,2, figsize=(12,10))\n\nax[0, 0].imshow(img)\nax[0, 1].imshow(image, cmap = 'gray')\n\nax[1, 0].imshow(img)\nax[1, 1].imshow(image2, cmap = 'gray')\n","metadata":{"execution":{"iopub.status.busy":"2023-08-01T17:27:33.582043Z","iopub.execute_input":"2023-08-01T17:27:33.582439Z","iopub.status.idle":"2023-08-01T17:27:36.491166Z","shell.execute_reply.started":"2023-08-01T17:27:33.582410Z","shell.execute_reply":"2023-08-01T17:27:36.490096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# PROCESAMIENTO DEL BRILLO CON DATAGEN","metadata":{}},{"cell_type":"code","source":"#CONVERSIÓN DE LOS IDs DEL DATASET DE LA COMPETENCIA EN IMÁGENES\nX0 = []\nX1 = []\nX2 = []\nX3 = []\nX4 = []\ntamano_img = 224\nfor i in range(5):\n  img_path = \"/kaggle/input/aptos2019-blindness-detection/train_images/\"+X3_ids[i]+\".png\"\n  img = cv2.imread(img_path)\n  if (img is not None):\n        #img = crop_image_from_gray(img)\n        img = circle_crop(img)\n        img = cv2.resize(img, (tamano_img, tamano_img)) #redimensionar las imgs\n        #img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        img = img.reshape(tamano_img, tamano_img, 3) #indicar el tamaño de la imagen y los canales\n        X0.append(img)\nprint(len(X0))\n\n","metadata":{"execution":{"iopub.status.busy":"2023-08-01T17:30:06.858825Z","iopub.execute_input":"2023-08-01T17:30:06.859264Z","iopub.status.idle":"2023-08-01T17:30:08.553992Z","shell.execute_reply.started":"2023-08-01T17:30:06.859232Z","shell.execute_reply":"2023-08-01T17:30:08.552898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from numpy import expand_dims\nfrom matplotlib import pyplot\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nsam = expand_dims(X0[0], 0)\ngen = ImageDataGenerator(brightness_range=[0.3,0.9])\ngen.fit(sam)\niterator= gen.flow(sam, batch_size=1)\nfor j in range(6):\n    pyplot.subplot(330+1+j)\n    chunk = iterator.next()\n    sub_img = chunk[0].astype('uint8')\n    plt.imshow(sub_img)\n    \npyplot.show","metadata":{"execution":{"iopub.status.busy":"2023-08-01T17:30:28.948397Z","iopub.execute_input":"2023-08-01T17:30:28.948759Z","iopub.status.idle":"2023-08-01T17:30:30.211369Z","shell.execute_reply.started":"2023-08-01T17:30:28.948730Z","shell.execute_reply":"2023-08-01T17:30:30.210261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(X0[0].shape)\nprint(sam.shape)","metadata":{"execution":{"iopub.status.busy":"2023-08-01T17:30:31.547572Z","iopub.execute_input":"2023-08-01T17:30:31.547960Z","iopub.status.idle":"2023-08-01T17:30:31.554391Z","shell.execute_reply.started":"2023-08-01T17:30:31.547916Z","shell.execute_reply":"2023-08-01T17:30:31.553253Z"},"trusted":true},"execution_count":null,"outputs":[]}]}