DEV Community

Olaoyo Michael
Olaoyo Michael

Posted on

Naturals Detection Using Python.

The earth is blessed with lots of natural phenomenons such as Forests, Glaciers and all sort. In this article, I'll be taking you through how to use computer vision to detect these things. In this article we will be detecting Forests, Glaciers, Mountains, Seas and Buildings. In this article, we shall be using a pre-trained model called VGG16 to train our model. The VGG16 is an example of a transfer learning model.

Now let’s get started with the task of detecting Naturals within an image. The most challenging task in this project is to find a dataset that includes some images that we can use to train our neural network.

Getting Datasets for the Neural Network

To get the dataset, we will use chrome extension of zip downloads which will download all the images we have from google.

  1. First, we head to google, search for Forest, the we use the chrome extension Zip downloader to download all the images for our forest images
  2. We go google, search for Glaciers, then use the chrome zip downloader to download all the images.

We continue in that order, till we have the five data folders needed for classification to train the neural network.
After getting all the five folders(Froret, Glacier, Sea, Buildings and Mountains), we save all these folders into a single folder which hold all the five datasets folders.

Removing Doggy Images

When we download the images from google, there are some images which will be downloaded by the extension that we dont want to feed into our network. These are called outliers. They tend to reduce the learning of our models and reduce the accuracy. We need to get rid of them.

# Import the libraries and Modules
from PIL import Image
import os
import numpy as np
from sklearn.model_selection import train_test_split
import cv2
import tensorflow as tf
import matplotlib.pyplot as plt
import imghdr

# Loading into a path
data_dir = 'The path to which the folder that contains all five folders to the dataset is' 
image_exts = ['jpg', 'bmp', 'png', 'jpeg']
for image_class in os.listdir(data_dir):
    for image in os.listdir(os.path.join(data_dir, image_class)):
        image_path = os.path.join(data_dir, image_class, image)
        try:
           img = cv2.imread(image_path)
           tip = imghdr.what(image_path)
           if tip not in image_exts:
              print('Image not in exts list {}'.format(image_path))
              os.remove(image_path)
           except Exception as e:
           print('Issues with image {}'.format(image_path))
Enter fullscreen mode Exit fullscreen mode

This block of code will remove outliers and doggy images.

Load and preprocess the Data

img_size = 128
def load_data():
    training_data = []
    for category in CATEGORIES:
        path = os.path.join(DATADIR, category)
        class_num = CATEGORIES.index(category)
        for img in os.listdir(path):
            try:
                img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_COLOR)
                new_array = cv2.resize(img_array, (img_size, img_size))
                training_data.append([new_array, class_num])
            except Exception as e:
                pass
    x = np.array([i[0] for i in training_data]) / 255.0
    y = np.array([i[1] for i in training_data])
    y = tf.keras.utils.to_categorical(y, len(CATEGORIES))
    x_train, x_val, y_train, y_val = train_test_split(x, y, test_size=0.2, random_state=42)
    return x_train, x_val, y_train, y_val
x_train, x_val, y_train, y_val = load_data()
Enter fullscreen mode Exit fullscreen mode

Creating the Model

# Load the pre-trained VGG16 model
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(img_size, img_size, 3))

# Freeze the pre-trained layers
for layer in base_model.layers:
    layer.trainable = False

# Add new trainable layers on top of the pre-trained model
x = base_model.output
x = Flatten()(x)
x = Dense(1024, activation='relu')(x)
output = Dense(len(CATEGORIES), activation='softmax')(x)

# Define the new model
model = tf.keras.models.Model(inputs=base_model.input, outputs=output)

# Compile the model
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# Train the model
model.fit(x_train, y_train, epochs=10, validation_data=(x_val, y_val))
Enter fullscreen mode Exit fullscreen mode

Evaluating the model

test_loss, test_acc = model.evaluate(x_val, y_val, verbose=0)

Print the test loss and accuracy

print('Test loss:', test_loss)
print('Test accuracy:', test_acc)

Using the model to predict new images

import numpy as np
from PIL import Image
from keras.models import load_model

# Load your trained CNN model
model = load_model('my_model.h5')

# Load the image you want to classify
image = Image.open(r'C:\Users\mine\Desktop\natural\mountains\images344.jpg') # Now you can use any image the model hasn't seen before to see the prediction

# Preprocess the image
image = image.resize((128, 128))
image = np.array(image) / 255.0
image = image.reshape((1, 128, 128, 3))

# Make a prediction
preds = model.predict(image)

# Find the index of the highest probability value
pred_class = np.argmax(preds)

# Map the predicted index to the corresponding class label
classes = ['buildings', 'forest', 'sea', 'glaciers', 'mountains']
pred_label = classes[pred_class]

# Display the result
print('The predicted class of the image is:', pred_label)
Enter fullscreen mode Exit fullscreen mode

I hope you got and the model predicted well. If there is question, feel free to ask in the comment section and I'll be very happy to help.

Check out the full code and results on my GitHub account

I deployed the model on streamlit. You can try it out here

Top comments (0)