Find Disease in Retinal OCT Image

Find Disease in Retinal OCT ImageShivam KumarBlockedUnblockFollowFollowingJan 21Overview:Optical Coherence Tomography (OCT):Optical coherence tomography (OCT) is an imaging technique that uses coherent light to capture high resolution images of biological tissues.

OCT is heavily used by ophthalmologists to obtain high resolution images of the eye retina.

Retina of the eye functions much more like a film in a camera.

OCT images can be used to diagnose many retina related eyes diseases.

The following picture shows the anatomy of the eye:Source: https://en.

wikipedia.

org/wiki/Macula_of_retina#/media/File:Blausen_0389_EyeAnatomy_02.

pngAbout the dataset:This dataset contains four categories (NORMAL,CNV,DME,DRUSEN).

It is organized into 3 folders (train, test, val) and contains subfolders for each image category (NORMAL, CNV, DME, DRUSEN).

The ‘test’ and ‘val’ folders contain very very less number of images.

‘train’ folder contains 83484 number of images.

Three are four class in rerinal oct images.

They are listed belowChoroidal neovascularization (CNV):Choroidal neovascularization (CNV) is the creation of new blood vessels in the choroid layer of the eye.

Choroidal neovascularization is a common cause of neovascular degenerative maculopathy (i.

e.

‘wet’ macular degeneration)[1] commonly exacerbated by extreme myopia, malignant myopic degeneration, or age-related developments.

https://en.

wikipedia.

org/wiki/Choroidal_neovascularizationChoroidal neovascularization (CNV)2.

Diabetic Macular Edema (DME):DME is a complication of diabetes caused by fluid accumulation in the macula that can affect the fovea.

The macula is the central portion in the retina which is in the back of the eye and where vision is the sharpest.

Vision loss from DME can progress over a period of months and make it impossible to focus clearly.

The following picture shows OCT image have DME disease.

Macular Edema (DME)3.

Drusen (DRUSEN):Drusen are yellow deposits under the retina.

Drusen are made up of lipids, a fatty protein.

Drusen likely do not cause age-related macular degeneration (AMD).

But having drusen increases a person’s risk of developing AMD.

There are different kinds of drusen.

“Hard” drusen are small, distinct and far away from one another.

This type of drusen may not cause vision problems for a long time, if at all.

“Soft” drusen are large and cluster closer together.

Their edges are not as clearly defined as hard drusen.

This soft type of drusen increases the risk for AMD.

In this article, we will find the disease from which a Retinal optical coherence tomography (OCT) image is suffering from.

Retinal optical coherence tomography (OCT) is an imaging technique used to capture high-resolution cross sections of the retinas of living patients.

The following image show OCT image have Drusen disease.

DrusenDrusen4.

NORMAL or Normal Eye Retina:Normal vision occurs when light is focused directly on the retina rather than in front or behind it.

A person with normal vision can see objects clearly near and faraway.

The following image show OCT image have normal imageNoraml OCT imageHow does it work ?Understand image data.

Image Augmentation.

Apply deep learning models.

Understand image dataWe need to check how many images we have in our ‘train’ folder.

normal_len = len(os.

listdir(".

/input/oct2017/OCT2017 /train/NORMAL"))drusen_len = len(os.

listdir(".

/input/oct2017/OCT2017 /train/DRUSEN"))cnv_len = len(os.

listdir(".

/input/oct2017/OCT2017 /train/CNV"))dme_len = len(os.

listdir(".

/input/oct2017/OCT2017 /train/DME"))print("length of normal images = ",normal_len)print("length of images with disease drusen = ",drusen_len)print("length of images with disease cnv = ",cnv_len)print("length of images with disease dme = ",dme_len)Output-length of normal images = 26315length of images with disease drusen = 8616length of images with disease cnv = 37205length of images with disease dme = 11348As we can see that 83484 images in ‘train’ folder.

We will split this data into train and test with ratio 80:20.

It is also important that we should have images of same shape.

We will check that images are in same shape or not.

If not we will bring all images in same shape.

files = os.

listdir(".

/input/oct2017/OCT2017 /train/NORMAL/")size = []for i in tqdm(range(len(files))): img = cv2.

imread(".

/input/oct2017/OCT2017 /train/NORMAL/"+files[i]) #print("image size = ",img.

shape) size.

append(img.

shape)print("There are different sizes of DRUSEN images, they are = ",set(size))output —There are different sizes of DRUSEN images, they are = {(496, 1024, 3), (496, 1536, 3), (496, 768, 3), (496, 512, 3), (496, 384, 3), (512, 512, 3)}Similarly we can find the shapes of images belonging to each class.

We can see that they are in different shapes.

We can also see that the images have three channel by looking up their shapes.

We can show some images belongs to every class with their separate channel.

# https://stackoverflow.

com/questions/37431599/how-to-slice-an-#image-into-red-green-and-blue-channels-with-misc-imreadfiles = os.

listdir(".

/input/oct2017/OCT2017 /train/NORMAL/")titles = ['', 'Red channel', 'Green channel', 'Blue channel']cmaps = [None, plt.

cm.

Reds_r, plt.

cm.

Greens_r, plt.

cm.

Blues_r]print('Five images from class – NORMAL')for i in range(5): image = cv2.

imread(".

/input/oct2017/OCT2017 /train/NORMAL/"+random.

choice(files)) fig, axes = plt.

subplots(1, 4, figsize=(13,3)) objs = zip(axes, (image, *image.

transpose(2,0,1)), titles, cmaps) for ax, channel, title, cmap in objs: ax.

imshow(channel, cmap=cmap) ax.

set_title(title) ax.

set_xticks(()) ax.

set_yticks(())output —Five images from class – NORMAL# https://stackoverflow.

com/questions/37431599/how-to-slice-an-#image-into-red-green-and-blue-channels-with-misc-imreadfiles = os.

listdir(".

/input/oct2017/OCT2017 /train/DRUSEN/")titles = ['', 'Red channel', 'Green channel', 'Blue channel']cmaps = [None, plt.

cm.

Reds_r, plt.

cm.

Greens_r, plt.

cm.

Blues_r]print('Five images from class – DRUSEN')for i in range(5): image = cv2.

imread(".

/input/oct2017/OCT2017 /train/DRUSEN/"+random.

choice(files)) fig, axes = plt.

subplots(1, 4, figsize=(13,3)) objs = zip(axes, (image, *image.

transpose(2,0,1)), titles, cmaps) for ax, channel, title, cmap in objs: ax.

imshow(channel, cmap=cmap) ax.

set_title(title) ax.

set_xticks(()) ax.

set_yticks(())output —Five images from class – DRUSENSimilarly we can show rest of two classes sample image.

Image AugmentationFeature Standardization : — We can standardize pixel values across the entire dataset.

We can do it by setting the featurewise_center and featurewise_std_normalization arguments on the ImageDataGenerator class.

Random Flip : — We can apply flipping to our image data.

For that, we can set vertical_flip and horizontal_flip arguments on the ImageDataGenerator class.

Random Shift : — The objects in the image may not be centered always.

To train the model such that it can find the off-centered object in the image, we can create shifted version of our training data.

For that, we can set width_shift_range and height_shift_range arguments on the ImageDataGenerator.

Validation Split : — We can split the data into train and validation.

For that, we have to set validation_split argument on the ImageDataGenerator.

train_datagen = ImageDataGenerator(samplewise_center=True, samplewise_std_normalization=True, horizontal_flip = True, vertical_flip = False, height_shift_range= 0.

05, width_shift_range=0.

1, rotation_range=15, zoom_range=0.

15, validation_split=0.

2)Now with the help of flow_from_directory method, we can generate batches of augmented data.

We can provide the path to directory, the target size of image.

As we set validation_split argument in ImageDataGenerator class, we will use subset argument in flow_from_directory method to get the training data or validation data.

One thing is noticeable that the image data directory should contain folders that contain the images of that particular class.

File Structure of retinal oct imagesIMG_SIZE = 224train_data_dir = '.

/input/oct2017/OCT2017 /train'validation_data_dir = '.

/input/oct2017/OCT2017 /val'train_generator = train_datagen.

flow_from_directory( train_data_dir, target_size=(IMG_SIZE , IMG_SIZE), batch_size=16, subset='training', class_mode='categorical')Deep Learning Models:Before applying models , let’s see the basic definition of precision and recall.

Precision : — Of all the points the model predicted to be class x , what percentage of them are actually class x.

Recall : — Of all the points that are actually from class x, what percentage of them are predicted as class x.

A simple model with five convolution layer : —We will have a simple model with five convolution layer, along with two dense layer and at the last dense layer with 4 nodes(because of 4 classes we have) and softmax activation function.

We used adam optimizer and categorical_crossentropy loss function and then trained the model.

You can find the code here — https://github.

com/anshuak100/Retinal-OCT-ImagesWe got accuracy_score with value 0.

78825.

Here we got the precision and recall matrix —precisionrecall2.

DenseNet model : —Applying DenseNet model with removing three fully connected layer from top of the network and initializing pre-trained weight on imagenet dataset.

We add a dense layer with four nodes with softmax activation function.

Now train the model with adam optimizer and categorical_crossentropy loss function.

You can find the code here — https://github.

com/anshuak100/Retinal-OCT-Images# defining densenet modeldef densenet_model(): img_in = Input(t_x.

shape[1:]) model = DenseNet121(include_top= False , weights='imagenet', # pre train weight input_tensor= img_in, input_shape= t_x.

shape[1:], pooling ='avg') x = model.

output predictions=Dense(4,activation="softmax", name="predictions")(x) model = Model(inputs=img_in, outputs=predictions) return modelWe got accuracy_score with value 0.

9355 .

Here we got the precision and recall matrix —precisionrecall3.

ResNet Model : —Let’s apply ResNet model.

We take the same thing that we have taken in DenseNet like removing top layer and adding a dense layer with four units and softmax activation function.

And then train the model with adam optimizer and categorical_crossentropy loss function.

# Defining ResNet modeldef resnet_model(): img_in = Input(t_x.

shape[1:]) model = ResNet50(include_top= False , weights='imagenet', input_tensor= img_in, input_shape= t_x.

shape[1:], pooling ='avg') x = model.

output predictions=Dense(4,activation="softmax", name="predictions")(x) model = Model(inputs=img_in, outputs=predictions) return modelYou can find the code here — https://github.

com/anshuak100/Retinal-OCT-ImagesWe got accuracy_score with value 0.

914375 .

Here we got the precision and recall matrix —precisionrecall4.

InceptionNet Model : —We do the same that we have done in DenseNet and ResNet, only change is taking InceptionNet instead of DenseNet or ResNet.

# defining inceptionnet modeldef inception_v3(): img_in = Input(t_x.

shape[1:]) model = InceptionV3(include_top= False , weights='imagenet', input_tensor= img_in, input_shape= t_x.

shape[1:], pooling ='avg') x = model.

output predictions=Dense(4,activation="softmax", name="predictions")(x) model = Model(inputs=img_in, outputs=predictions) return modelYou can find the code here — https://github.

com/anshuak100/Retinal-OCT-ImagesWe got accuracy_score with value 0.

927375 .

Here we got the precision and recall matrix —precisionrecallcode here: https://github.

com/anshuak100/Retinal-OCT-ImagesConclusion :Transfer learning gives better accuracy than manually created network.

If we compare the recall matrix of everyone, we get that label 2 is misclassified more.

InceptionNet recall matrix is better than other.

InceptionNet model tries to make balance between all that classes.

We can choose it as our best model.

References :https://www.

appliedaicourse.

com2.

https://www.

kaggle.

com/paultimothymooney/kermany2018/homehttp:3.

https://machinelearningmastery.

com/image-augmentation-deep-learning-keras/4.

https://becominghuman.

ai/image-data-pre-processing-for-neural-networks-498289068258?gi=b3755339c2de5.

https://www.

preventblindness.

org/diabetic-macular-edema-dme6.

https://www.

aao.

org/eye-health/diseases/what-are-drusen.

. More details

Leave a Reply