-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
372 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import numpy as np | ||
from keras.models import Sequential | ||
from keras.layers import Dense, Activation | ||
from keras.utils import np_utils | ||
from keras import regularizers | ||
from sys import exit | ||
import matplotlib.pyplot as plt | ||
|
||
## load the data as numpy array | ||
data_train = np.load('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtrainData.npy') | ||
label_train = np.load('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtrainDataLabel.npy') | ||
data_train = data_train[..., 1] | ||
|
||
data_test = np.load('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestData.npy') | ||
label_test = np.load('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestDataLabel.npy') | ||
data_test = data_test[..., 1] | ||
|
||
## reshaping and normalizing the data | ||
## (27 * 27 * 3 = 2187) except green channel and clahe image (27 * 27 = 729) | ||
input_dim = 729 | ||
x_train = data_train.reshape(20000, input_dim).astype('float') | ||
x_test = data_test.reshape(20000, input_dim).astype('float') | ||
|
||
x_train /= 255 | ||
x_test /= 255 | ||
|
||
## modifying the label as catagorical | ||
label_train = (label_train / 255).astype('int') | ||
y_train = np_utils.to_categorical(label_train, 2) | ||
|
||
label_test = (label_test / 255).astype('int') | ||
y_test = np_utils.to_categorical(label_test, 2) | ||
|
||
## defining model | ||
model = Sequential() | ||
model.add(Dense(2, input_dim = input_dim, activation = 'softmax', kernel_regularizer = regularizers.l2(0.0001))) | ||
|
||
## compiling the model | ||
model.compile(optimizer = 'adam', loss='categorical_crossentropy', metrics=['accuracy']) | ||
|
||
## fitting the data | ||
batch_size = 128 | ||
epoch = 200 | ||
history = model.fit(x_train, y_train, batch_size = batch_size, nb_epoch = epoch, verbose = 1, shuffle = False, validation_data = (x_test, y_test)) | ||
|
||
## score the model | ||
score = model.evaluate(x_test, y_test, verbose = 0) | ||
print(model.metrics_names, score) | ||
score = model.evaluate(x_train, y_train, verbose = 0) | ||
print(model.metrics_names, score) | ||
|
||
## save the model | ||
json_string = model.to_json() # as json | ||
open('DRIVEgreen_Logistic_model.json', 'w').write(json_string) | ||
yaml_string = model.to_yaml() #as yaml | ||
open('DRIVEgreen_Logistic_model.yaml', 'w').write(yaml_string) | ||
|
||
# save the weights in h5 format | ||
model.save_weights('DRIVEgreen_Logistic_wts.h5') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import numpy as np | ||
from PIL import Image | ||
from sys import exit | ||
import matplotlib.pyplot as plt | ||
|
||
data = np.load('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEcl.npy') | ||
data = data.astype('uint8') | ||
|
||
#img = Image.fromarray(data[0]) | ||
#img.save('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\data.png') | ||
|
||
## checking array size and data type | ||
print(data.shape, data.dtype) | ||
|
||
## checking the data value content | ||
plt.hist(data.flatten(), bins = 20) | ||
plt.show() | ||
|
||
## plotting the data location to see the randomness | ||
#print(dataLoc, dataLabel) | ||
#plt.imshow(data[1], cmap = plt.cm.binary) | ||
#plt.scatter(dataLoc[:,1], dataLoc[:,0]) | ||
#plt.axis([0, 563, 583, 0]) | ||
#plt.show() | ||
|
||
## plotting the patches | ||
fig = plt.figure(figsize = (6, 6)) | ||
fig.subplots_adjust(left = 0, right = 1, bottom = 0, top = 1, hspace = 0.05, wspace = 0.005) | ||
|
||
l = np.random.randint(0, 20000, size = 42) | ||
for i, j in enumerate(l): | ||
ax = fig.add_subplot(7, 7, i + 1) | ||
ax.imshow(data[j], cmap = 'binary') | ||
plt.axis('off') | ||
plt.show() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#import cv2 | ||
import numpy as np | ||
from sys import exit | ||
from PIL import Image | ||
import matplotlib.pyplot as plt | ||
import random | ||
|
||
## defining parameters | ||
patchSize = 27 # rectangular patch with size patchSize*patchSize*channel | ||
patchPerImg = 1000 # patches per image | ||
numImage = 20 # number of images | ||
totalPatch = patchPerImg * numImage | ||
data = np.ones((totalPatch, patchSize, patchSize, 3), dtype = 'uint8') # all of the patches will be stored here | ||
dataLoc = np.ones((totalPatch, 2), dtype = 'uint8') # location of the patches stores as (row, column) | ||
dataLabel = np.ones((totalPatch), dtype = 'uint8') # label of the patches 0 - neg, 1 - pos | ||
|
||
balance = 0.5 # balance between positive and negative patches | ||
positive = int(patchPerImg * balance) # number of positive image in an image | ||
negative = patchPerImg - positive # number of negative image in an image | ||
|
||
## reading the image and mask | ||
for i in range(1, numImage + 1): | ||
imgNum = str(i) | ||
if i < 10: | ||
imgNum = '0' + imgNum | ||
imgDir = "E:\\library of EEE\\4-2\\eee 426\\code\\dataDRIVE\\" | ||
imgName = imgNum + '_test.tif' | ||
img = Image.open('E:\\library of EEE\\4-2\\eee 426\\data\\DRIVE\\DRIVE\\test\\images\\' + imgName) | ||
maskName = imgNum + '_test_mask.gif' | ||
mask = Image.open('E:\\library of EEE\\4-2\\eee 426\\data\\DRIVE\\DRIVE\\test\\mask\\' + maskName) | ||
gndTruthName = imgNum + '_manual1.gif' | ||
gndTruth = Image.open('E:\\library of EEE\\4-2\\eee 426\\data\\DRIVE\\DRIVE\\test\\1st_manual\\' + gndTruthName) | ||
|
||
## converting them to numpy array | ||
img = np.array(img) | ||
#img = np.array(img.getdata()).reshape(img.size[1], img.size[0], 3) # Image class store image as (width, height) but we want it as (row, column) | ||
#img = img.astype('float32') / 255 # to see the image in plt | ||
|
||
mask = mask.convert('RGB') | ||
#mask = np.array(mask.getdata()).reshape(mask.size[1], mask.size[0], 3) | ||
mask = np.array(mask) | ||
#mask = mask.astype('float32') / 255 | ||
|
||
gndTruth = gndTruth.convert('RGB') | ||
gndTruth = np.array(gndTruth)[:,:,0] | ||
#gndTruth = gndTruth.astype('float32') / 255 | ||
|
||
|
||
## cutting out patches from the image | ||
imgRow = img.shape[0] | ||
imgCol = img.shape[1] | ||
|
||
count = 0 | ||
ind = (i - 1) * patchPerImg | ||
posCount = 0 | ||
negCount = 0 | ||
while count < patchPerImg: | ||
r = int(round(random.uniform(0, img.shape[0]))) | ||
c = int(round(random.uniform(0, img.shape[1]))) | ||
|
||
rStart = r - patchSize // 2 | ||
rEnd = r + patchSize // 2 + 1 | ||
cStart = c - patchSize // 2 | ||
cEnd = c + patchSize // 2 + 1 | ||
|
||
if np.all(mask[rStart:rEnd, cStart:cEnd]) and r > 13 and r < imgRow - 14 and c > 13 and c < imgCol - 14: | ||
label = gndTruth[r, c] | ||
if label == 0: | ||
if negCount == negative: | ||
continue | ||
else: | ||
negCount += 1 | ||
else: | ||
if posCount == positive: | ||
continue | ||
else: | ||
posCount += 1 | ||
|
||
temp = img[rStart:rEnd, cStart:cEnd, :] | ||
data[ind + count] = temp | ||
dataLoc[ind + count] = np.array([r, c]) | ||
dataLabel[ind + count] = label | ||
|
||
count += 1 | ||
#print(negCount, posCount) | ||
|
||
print(np.count_nonzero(dataLabel)) | ||
|
||
## storing the images and data THE DATA IS STORED IN RGB FROMAT | ||
np.save('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestData', data) | ||
np.save('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestDataLcation', dataLoc) | ||
np.save('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestDataLabel', dataLabel) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import cv2 | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
from sys import exit | ||
|
||
dir = 'E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestData.npy' | ||
data = np.load(dir) | ||
data = data.astype('uint8') | ||
|
||
dir = 'E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestDataLabel.npy' | ||
Label = np.load(dir) | ||
Label = Label.astype('uint8') | ||
|
||
## to work with opencv the channel 0 and 2 must be interchanged | ||
#because opencv read image as BGR and our image is in RGB order | ||
def swapchannels(data): | ||
temp = np.ones(data[0].shape) | ||
|
||
for i in range(20000): | ||
temp[:, :, 0] = data[i, :, :, 2] | ||
data[i, :, :, 2] = data[i, :, :, 0] | ||
data[i, :, :, 0] = temp[:, :, 0] | ||
|
||
swapchannels(data) | ||
|
||
# ## gaussian blur | ||
# gaussBlur = np.ones((20000, 27, 27, 3)) | ||
# for i in range(20000): | ||
# gaussBlur[i] = cv2.GaussianBlur(data[i], (3, 3), 0) | ||
# swapchannels(gaussBlur) # we save the images in RGB order | ||
# np.save('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestgauss', gaussBlur) | ||
|
||
# ## median blur | ||
# medBlur = np.ones((20000, 27, 27, 3)) | ||
# for i in range(20000): | ||
# medBlur[i] = cv2.medianBlur(data[i], 3) | ||
# swapchannels(medBlur) | ||
# np.save('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestmed', medBlur) | ||
|
||
# ## laplacian filter | ||
# lapFilter = np.ones((20000, 27, 27, 3)) | ||
# for i in range(20000): | ||
# lapFilter[i] = cv2.Laplacian(data[i], cv2.CV_64F) | ||
# swapchannels(lapFilter) | ||
# np.save('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestlap', lapFilter) | ||
|
||
|
||
# ## Sobel filter | ||
# sobelx = np.ones((20000, 27, 27, 3)) | ||
# sobely = np.ones((20000, 27, 27, 3)) | ||
# sobel = np.ones((20000, 27, 27, 3)) | ||
# for i in range (20000): | ||
# sobelx[i] = cv2.Sobel(data[i], cv2.CV_64F, 1, 0, ksize=5) | ||
# sobely[i] = cv2.Sobel(data[i], cv2.CV_64F, 0, 1, ksize=5) | ||
# sobel = np.round(np.sqrt((sobelx ** 2 + sobely ** 2))) | ||
# swapchannels(sobel) | ||
# np.save('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestsobel', sobel) | ||
|
||
## CLAHE | ||
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) | ||
cl = np.ones((20000, 27, 27)) | ||
for i in range(20000): | ||
cl[i]= clahe.apply(data[i, :, :, 1]) | ||
np.save('E:\\library of EEE\\4-2\\eee 426\\data\\MSCprojectDataBase\\simpleClassifierDataBase\\DRIVEtestcl', cl) | ||
|
||
exit() | ||
|
||
## global contrast normalization | ||
# GCN = np.ones((27, 27, 3)) | ||
|
||
# Mean = np.mean(data[0, :, :, 0]) | ||
# SD = np.std(data[0, :, :, 0]) | ||
# GCN[:, :, 0] = (data[0, :, :, 0] - Mean) / SD | ||
|
||
# Mean = np.mean(data[0, :, :, 1]) | ||
# SD = np.std(data[0, :, :, 1]) | ||
# GCN[:, :, 1] = (data[0, :, :, 1] - Mean) / SD | ||
|
||
# Mean = np.mean(data[0, :, :, 2]) | ||
# SD = np.std(data[0, :, :, 2]) | ||
# GCN[:, :, 2] = (data[0, :, :, 2] - Mean) / SD | ||
|
||
# GCN = (GCN - np.min(GCN)) / np.max(GCN) * 255 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from keras.models import Sequential, model_from_json | ||
|
||
model = model_from_json(open('DRIVE_Logistic_model.json').read())# if json | ||
# model = model_from_yaml(open('my_model_architecture.yaml').read())# if yaml | ||
model.load_weights('DRIVE_Logistic_wts.h5') | ||
|
||
print(model.metrics_names) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
########################################################################## | ||
### PROJECT: RTINAL VESSEL SEGMENTATION USING CONVOLUTIONAL NEURAL NET ### | ||
######################### SYED NAKIB HOSSAIN ############################# | ||
######################### RAUFUR RAHMAN KHAN ############################# | ||
######################## MD SAZID ISLAM ARAF ############################# | ||
########################################################################## | ||
|
||
from __future__ import print_function | ||
import tensorflow | ||
KERAS_BACKEND = tensorflow | ||
import keras | ||
from keras.models import Sequential | ||
from keras.layers import Dense, Dropout, Flatten | ||
from keras.layers import Conv2D, MaxPooling2D, UpSampling2D | ||
from keras import backend as K | ||
from sys import exit | ||
|
||
######################## PREPROCESSING ##################################### | ||
|
||
# noralization | ||
# equalization | ||
# gamma adjustment | ||
# scaling | ||
|
||
####################### DATA PROCESSING #################################### | ||
|
||
# input image dimensions | ||
img_rows, img_cols = 28, 28 | ||
|
||
# the data, shuffled and split between train and test sets | ||
(x_train, y_train), (x_test, y_test) = mnist.load_data() | ||
|
||
|
||
if K.image_data_format() == 'channels_first': | ||
x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) | ||
x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) | ||
input_shape = (1, img_rows, img_cols) | ||
else: | ||
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) | ||
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) | ||
input_shape = (img_rows, img_cols, 1) | ||
|
||
|
||
x_train = x_train.astype('float32') | ||
x_test = x_test.astype('float32') | ||
x_train /= 255 | ||
x_test /= 255 | ||
|
||
print('x_train shape:', x_train.shape) | ||
print(x_train.shape[0], 'train samples') | ||
print(x_test.shape[0], 'test samples') | ||
|
||
# convert class vectors to binary class matrices | ||
y_train = keras.utils.to_categorical(y_train, num_classes) | ||
y_test = keras.utils.to_categorical(y_test, num_classes) | ||
|
||
|
||
####################### MODEL FORMATION #################################### | ||
num_classes = 10 | ||
|
||
# NOTE: in paper --> the dropout layer is said to be after each conv2D layer; assuming they said that as a mistake; | ||
# so the dropout layer is after every conv2D-pooling layer; see to this. | ||
model = Sequential() | ||
model.add(Conv2D(filters = 32, kernel_size = (3, 3), activation = 'relu', padding = 'same', input_shape = input_shape) # output shape (None, 28, 28, 32) | ||
model.add(Conv2D(filters = 32, kernel_size = (3, 3), activation = 'relu', padding = 'same') # output shape (None, 28, 28, 32) | ||
model.add(MaxPooling2D(pool_size=(2, 2))) # output shape (None, 14, 14, 32) | ||
model.add(Dropout(rate = 0.7)) # output shape (None, 14, 14, 32) | ||
|
||
model.add(Conv2D(filters = 64, kernel_size = (3, 3), activation = 'relu', padding = 'same') # output shape (None, 14, 14, 64) | ||
model.add(Conv2D(filters = 64, kernel_size = (3, 3), activation = 'relu', padding = 'same') # output shape (None, 14, 14, 64) | ||
model.add(UpSampling2D(pool_size=(2, 2))) # output shape (None, 28, 28, 64) | ||
model.add(Dropout(rate = 0.7)) # output shape (None, 28, 28, 64) | ||
|
||
model.add(Conv2D(filters = 32, kernel_size = (3, 3), activation = 'relu', padding = 'same') # output shape (None, 28, 28, 32) | ||
model.add(Conv2D(filters = 32, kernel_size = (3, 3), activation = 'relu', padding = 'same') # output shape (None, 28, 28, 32) | ||
|
||
# NOTE: in paper --> inmplemented multi label classification; not sure how to do this | ||
#model.add(Flatten()) # output shape (None, 9216) | ||
#model.add(Dense(units = 128, activation='relu')) # output shape (None, 128) | ||
#model.add(Dropout(rate = 0.5)) # output shape (None, 128) | ||
#model.add(Dense(units = num_classes, activation='softmax')) # output shape (None, 10) | ||
|
||
# NOTE: in paper --> momentum said to be 0.7 but in keras docuentation no momentum for rmsprop; see to rmsprop | ||
model.compile(loss = keras.losses.categorical_crossentropy, | ||
optimizer = keras.optimizers.RMSprop(lr=0.0001, rho=0.9, epsilon=1e-08, decay=0.0), | ||
metrics = ['accuracy']) | ||
|
||
|
||
######################### TRAINING AND EVALUATION ########################## | ||
batch_size = 32 | ||
epochs = 60 | ||
|
||
model.fit(x_train, y_train, batch_size = batch_size, epochs = epochs, verbose = 1, validation_data = (x_test, y_test)) | ||
score = model.evaluate(x_test, y_test, verbose = 0) | ||
print('Test loss:', score[0]) | ||
print('Test accuracy:', score[1]) |