<jupyter_start><jupyter_text><jupyter_code>#bnsreenu(2021) Source Code: python_for_microscopists, 090a-autoencoder_colorize_V0.2.py
#Available at: https://github.com/bnsreenu/python_for_microscopists/blob/master/090a-autoencoder_colorize_V0.2.py
#Last Accessed: 29 April 2021

#Importing Libraries
from keras.layers import Conv2D, UpSampling2D
from keras.models import Sequential
from keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img
from skimage.color import rgb2lab, lab2rgb
from skimage.transform import resize
from skimage.io import imsave
import numpy as np
import tensorflow as tf
#Mount google drive
from google.colab import drive
drive.mount('/content/drive')
root_path = 'gdrive/My Drive/your_project_folder/'  #change dir to your project folder
#Upload kaggle.json file (Config file obtained by:
#To use the Kaggle API, sign up for a Kaggle account at https://www.kaggle.com. 
#Then go to the 'Account' tab of your user profile (https://www.kaggle.com/<username>/account) and select 'Create API Token'. 
#This will trigger the download of kaggle.json, a file containing your API credentials.)
#https://github.com/Kaggle/kaggle-api
from google.colab import files
files.upload()  #this will prompt you to upload the kaggle.json
#Installs kaggle API from json
!pip install -q kaggle
!mkdir -p ~/.kaggle
!cp kaggle.json ~/.kaggle/
!ls ~/.kaggle
!chmod 600 /root/.kaggle/kaggle.json  # set permission
#download natural dataset
#<NAME> (2018) Natural Images. Kaggle Dataset. Available at: https://www.kaggle.com/prasunroy/natural-images. Last Accessed: 03 May 2021
!kaggle datasets download -d prasunroy/natural-images -p /content/gdrive/My\ Drive/kaggle/natural
#Creating a folder for dataset to unzip to
import os
os.chdir('/content/gdrive/My Drive/kaggle/natural')  #change dir
!unzip -q natural-images.zip -d natural-images/  #unzip data in natural-images/
#folder for all images
if not os.path.exists('/content/gdrive/My Drive/kaggle/natural/natural-images/allImages'):
    os.makedirs('/content/gdrive/My Drive/kaggle/natural/natural-images/allImages')
#put all images into one folder
import shutil

# --------------------------------------------------------
reorg_dir = "/content/gdrive/My Drive/kaggle/natural/natural-images/natural_images"
target_dir = "/content/gdrive/My Drive/kaggle/natural/natural-images/allImages" 
# ---------------------------------------------------------
for root, dirs, files in os.walk(reorg_dir):
    for name in files:
        subject = root+"/"+name
        n = 1; name_orig = name
        while os.path.exists(target_dir+"/"+name):
            name = "duplicate_"+str(n)+"_"+name_orig; n = n+1
        newfile = target_dir+"/"+name; shutil.copy(subject, newfile)
#shuffling image names
import os
from random import shuffle

dirname = r'/content/gdrive/My Drive/kaggle/natural/natural-images/allImages'

paths = [
    os.path.join(root, filename)
    for root, dirs, files in os.walk(dirname)
    for filename in files
    if filename.endswith('.jpg')
]
shuffle(paths)
randomData= paths[:6890]
#creating directory to contain shuffled images (train_datagen works with a nested directory)
if not os.path.exists('/content/gdrive/My Drive/kaggle/natural/natural-images/allImagesProcessed'):
    os.makedirs('/content/gdrive/My Drive/kaggle/natural/natural-images/allImagesProcessed')

if not os.path.exists('/content/gdrive/My Drive/kaggle/natural/natural-images/allImagesProcessed/resized'):
    os.makedirs('/content/gdrive/My Drive/kaggle/natural/natural-images/allImagesProcessed/resized')
#save shuffled images to folder
from PIL import Image

count = 0
for imagename in randomData:
    image = Image.open(randomData[count])
    image.save('/content/gdrive/My Drive/kaggle/natural/natural-images/allImagesProcessed/resized/image_'+str(count)+'.jpg')
    count+=1
path = '/content/gdrive/My Drive/kaggle/natural/natural-images/allImagesProcessed/'

#Normalize images - divide by 255
train_datagen = ImageDataGenerator(rescale=1. / 255)

#Resize images, if needed
train = train_datagen.flow_from_directory(path, 
                                          target_size=(256, 256), 
                                          batch_size=340, 
                                          class_mode=None)


#convert images to greyscale for training and splitting into training and validation sets
X =[]
Y =[]
for img in train[0]:
  try:
      lab = rgb2lab(img)
      X.append(lab[:,:,0]) 
      Y.append(lab[:,:,1:] / 128) #A and B values range from -127 to 128, 
      #so we divide the values by 128 to restrict values to between -1 and 1.
  except:
     print('error')
X = np.array(X)
Y = np.array(Y)
X = X.reshape(X.shape+(1,)) #dimensions to be the same for X and Y
print(X.shape)
print(Y.shape)
#model definitions

#Encoder

model = Sequential()
model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=2, input_shape=(256, 256, 1)))
model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(Conv2D(128, (3,3), activation='relu', padding='same', strides=2))
model.add(Conv2D(256, (3,3), activation='relu', padding='same'))
model.add(Conv2D(256, (3,3), activation='relu', padding='same', strides=2))
model.add(Conv2D(512, (3,3), activation='relu', padding='same'))
model.add(Conv2D(512, (3,3), activation='relu', padding='same'))
model.add(Conv2D(256, (3,3), activation='relu', padding='same'))

#Decoder
#Decoder
#Note: For the last layer we use tanh instead of Relu. 
#This is because we are colorizing the image in this layer using 2 filters, A and B.
#A and B values range between -1 and 1 so tanh (or hyperbolic tangent) is used
#as it also has the range between -1 and 1. 
#Other functions go from 0 to 1.
model.add(Conv2D(128, (3,3), activation='relu', padding='same'))
model.add(UpSampling2D((2, 2)))
model.add(Conv2D(64, (3,3), activation='relu', padding='same'))
model.add(UpSampling2D((2, 2)))
model.add(Conv2D(32, (3,3), activation='relu', padding='same'))
model.add(Conv2D(16, (3,3), activation='relu', padding='same'))
model.add(Conv2D(2, (3, 3), activation='tanh', padding='same'))
model.add(UpSampling2D((2, 2)))
model.compile(optimizer='adam', loss='mse' , metrics=['accuracy'])
model.summary()

#create folder for saving model files
if not os.path.exists('/content/gdrive/My Drive/kaggle/natural/models'):
    os.makedirs('/content/gdrive/My Drive/kaggle/natural/models')
#train model
model.fit(X,Y,validation_split=0.3, epochs=350, batch_size=48)

#save model
model_json = model.to_json()
with open('/content/gdrive/My Drive/kaggle/natural/models/model.json', "w") as json_file:
    json_file.write(model_json)
model.save_weights("/content/gdrive/My Drive/kaggle/natural/models/model.h5")

model.save('/content/gdrive/My Drive/kaggle/natural/models/colorize_autoencoder.model')

#test model
tf.keras.models.load_model(
    '/content/gdrive/My Drive/kaggle/natural/models/colorize_autoencoder.model',
    custom_objects=None,
    compile=True)
img1_color=[]
img1=img_to_array(load_img("/content/gdrive/My Drive/kaggle/natural/natural-images/allImages/car_0186.jpg"))

img1 = resize(img1 ,(256,256))
imsave("previous.png", img1) #saves original image 
img1_color.append(img1)
img1_color = np.array(img1_color, dtype=float)
img1_color = rgb2lab(1.0/255*img1_color)[:,:,:,0]
img1_color = img1_color.reshape(img1_color.shape+(1,))
output1 = model.predict(img1_color)
output1 = output1*128
result = np.zeros((256, 256, 3))
result[:,:,0] = img1_color[0][:,:,0]
result[:,:,1:] = output1[0]
imsave("result.png", lab2rgb(result)) #saves colourised test image<jupyter_output>WARNING:root:Lossy conversion from float32 to uint8. Range [4.4609375, 254.90478515625]. Convert image to uint8 prior to saving to suppress this warning.
WARNING:root:Lossy conversion from float64 to uint8. Range [0, 1]. Convert image to uint8 prior to saving to suppress this warning.
StarcoderdataJupyterStructuredCleanDedup