Απλή Ζωή

Μια σύντομη μελέτη των αλγορίθμων κατωφλίου εικόνας

Εισαγωγή

Αυτό το άρθρο παρουσιάζει εν συντομία το όριο εικόνας και τους αλγόριθμους που χρησιμοποιούνται για τον καθορισμό ορίου εικόνας. Το κατώφλι εικόνας είναι μια απλή τεχνική τμηματοποίησης εικόνας. Χρησιμοποιείται για τη μετατροπή μιας εικόνας σε κλίμακα του γκρι ή μιας εικόνας RGB σε δυαδική εικόνα. Σε αυτό το άρθρο, θα εξετάσουμε αλγόριθμους κατωφλίου όπως το απλό κατώφλι, την τεχνική κατωφλίου otsu και την προσαρμοστική τεχνική κατωφλίου, μαζί με μια σύντομη σημείωση για έναν αλγόριθμο βαθιάς εκμάθησης (U-Net) για τμηματοποίηση εικόνας.

Τι είναι το Image Thresholding;

Πριν κατανοήσουμε τον όρο Image Thresholding, ας κατανοήσουμε πρώτα τον όρο Image Segmentation. Η κατάτμηση εικόνας είναι μια κοινή τεχνική που χρησιμοποιείται για τη διαίρεση μιας εικόνας σε ομάδες pixel με βάση ορισμένα κριτήρια.

Το κατώφλι εικόνας είναι ένας τύπος τμηματοποίησης εικόνας που χωρίζει το προσκήνιο από το φόντο μιας εικόνας. Σε αυτήν την τεχνική, οι τιμές των εικονοστοιχείων εκχωρούνται που αντιστοιχούν στις παρεχόμενες τιμές κατωφλίου. Στην όραση υπολογιστή, ο καθορισμός κατωφλίου γίνεται σε εικόνες σε κλίμακα του γκρι.

Οι παρακάτω εικόνες δείχνουν μια εικόνα σε κλίμακα του γκρι και την εικόνα που λαμβάνεται μετά την εφαρμογή κατωφλίου σε αυτήν.

Κατώφλι εικόνας

Γιατί χρειαζόμαστε το Image Thresholding;

Ας καταλάβουμε τη σημασία του κατωφλίου εικόνας με ένα παράδειγμα-

Ρίξτε μια ματιά στις παρακάτω εικόνες,

Κατώφλι εικόνας
Συγκρίνοντας την πρώτη εικόνα, η μάσκα στη δεύτερη εικόνα φαίνεται καθαρά. Ας πάρουμε ένα άλλο παράδειγμα,

Κατώφλι εικόνας

Η πρώτη εικόνα, η αρχική εικόνα, είναι λίγο παραμορφωμένη από τη δεύτερη εικόνα που λάβαμε μετά την εφαρμογή του κατωφλίου. Έτσι, το thresholding είναι χρήσιμο για την εξαγωγή κειμένου που δεν είναι καθαρό στην εικόνα.

Το κατώφλι εικόνας μας βοηθά να διαιρέσουμε το προσκήνιο και το φόντο μιας εικόνας, κάτι που μπορεί να βοηθήσει στον εντοπισμό των αντικειμένων που δεν είναι καθαρά ορατά στις εικόνες.

Κατανόηση διαφορετικών τεχνικών κατωφλίου

Σε αυτό το άρθρο, θα μάθουμε για διαφορετικές τεχνικές που χρησιμοποιούνται στον καθορισμό ορίου εικόνας και θα εφαρμόσουμε αυτές τις τεχνικές χρησιμοποιώντας το OpenCV.

Απλό κατώφλι

Το Simple Thresholding είναι επίσης γνωστό ως Binary Thresholding. Αυτή η τεχνική ορίζει μια τιμή κατωφλίου και συγκρίνει κάθε pixel με τη συγκεκριμένη τιμή κατωφλίου. Εάν η τιμή του εικονοστοιχείου είναι μικρότερη ή ίση με το εκχωρημένο όριο, τότε η τιμή του εικονοστοιχείου ορίζεται στο μηδέν ή στη μέγιστη τιμή.

Εφαρμογή απλού κατωφλίου χρησιμοποιώντας OpenCV:

Εισαγωγή απαραίτητων βιβλιοθηκών

import cv2
from google.colab.patches import cv2_imshow
import matplotlib.pyplot as plt

Μετατροπή έγχρωμης εικόνας σε κλίμακα του γκρι

image = cv2.imread('/content/drive/MyDrive/AV/OpenCV/test.jpg')
cv2_imshow(image)
# coverting color image into grayscale
orig_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

Δυαδικό κατώφλι

# Arguments of function cv2.threshold
# cv2.threshold(grayscaled image, threshold value, maximum value of pixel, type of threshold)
# Output is a tuple containg the threshold value and thresholded image

t, thresh = cv2.threshold(orig_img,70,255,cv2.THRESH_BINARY)
cv2_imshow(thresh)

Δυαδικό αντίστροφο κατώφλι

t,thresh1 = cv2.threshold(orig_img,70,255,cv2.THRESH_BINARY_INV)
cv2_imshow(thresh1)

Περικοπή κατωφλίου

rect,thresh2 = cv2.threshold(orig_img,70,255,cv2.THRESH_TRUNC)
cv2_imshow(thresh2)

Όριο στο μηδέν

rect,thresh3 = cv2.threshold(orig_img,70,255,cv2.THRESH_TOZERO)
cv2_imshow(thresh3)

Αντίστροφο κατώφλι έως μηδέν

rect,thresh4 = cv2.threshold(orig_img,127,255,cv2.THRESH_TOZERO_INV)
cv2_imshow(thresh4)

Η παρακάτω εικόνα λαμβάνεται μετά την εφαρμογή απλού ορίου

Κατώφλι εικόνας

Το κατώφλι του Otsu

Ένας από τους τρόπους για να επιτευχθεί ένα βέλτιστο όριο είναι η μέθοδος του Otsu. Σε αυτή τη μέθοδο, βρίσκουμε την εξάπλωση του προσκηνίου και του φόντου των εικόνων για όλες τις πιθανές τιμές κατωφλίου. Ως βέλτιστο όριο λαμβάνεται το όριο με τη μικρότερη διαφορά.

Πώς λειτουργεί το κατώφλι του Otsu;

Η ιδέα στο όριο του Otsu είναι να μεγιστοποιήσει τη διακύμανση μεταξύ των κατηγοριών. Η διακύμανση μεταξύ των κατηγοριών μπορεί να οριστεί ως εξής:

Εδώ, είναι η διακύμανση μεταξύ των κλάσεων δύο κλάσεων – κλάσης προσκηνίου και κλάσης παρασκηνίου.

Αφήνω, είναι ο αριθμός των pixel στις κλάσεις παρασκηνίου και προσκηνίου, αντίστοιχα. n ο συνολικός αριθμός των pixel στην εικόνα τότε,

ΤΟ μέσος όρος της κλάσης υποβάθρου και της κλάσης προσκηνίου αντιπροσωπεύεται ως

Ο αλγόριθμος του Otsu υπολογίζει τη διακύμανση μεταξύ των κλάσεων για όλες τις πιθανές τιμές κατωφλίου. Ως βέλτιστη τιμή κατωφλίου λαμβάνεται το όριο με την υψηλότερη απόκλιση μεταξύ των κατηγοριών. Τιμές μικρότερες από τη βέλτιστη τιμή κατωφλίου εμπίπτουν σε μια κλάση και άλλες τιμές σε άλλη κλάση.

Εφαρμογή του κατωφλίου του Otsu:

Υλοποίηση του κατωφλίου του Otsu με χρήση OpenCV

blur = cv2.GaussianBlur(orig_img,(5,5),0) #Applying Gaussian Blurr on image to get better threshold

t,thresh5 = cv2.threshold(blur,128,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
print('Threshold obtained by Otsu Thresholding : ', t)
cv2_imshow(thresh5)

Η παρακάτω εικόνα ελήφθη μετά την εφαρμογή του ορίου δυαδοποίησης του Otsu.

Προσαρμοστικό κατώφλι

Τόσο το Simple thresholding όσο και το thresholding του Otsu είναι καθολικές τεχνικές κατωφλίου που χρησιμοποιούν μια ενιαία τιμή κατωφλίου στο όριο εικόνας. Αλλά μια μεμονωμένη τιμή κατωφλίου μπορεί να μην είναι επαρκής επειδή μπορεί να λειτουργεί καλά σε ένα συγκεκριμένο μέρος της εικόνας, αλλά μπορεί να αποτύχει σε ένα άλλο μέρος. Για την επίλυση αυτών των περιορισμών, μπορεί να χρησιμοποιηθεί προσαρμοστικό όριο.

Το Adaptive thresholding είναι μια τοπική τεχνική κατωφλίου. Αυτή η τεχνική λαμβάνει υπόψη κάθε pixel και τη γειτονιά του. Ο αριθμητικός μέσος ή ο Gaussian μέσος όρος της έντασης των εικονοστοιχείων χρησιμοποιείται συνήθως για τον υπολογισμό του ορίου της γειτονιάς. τότε η τιμή κατωφλίου χρησιμοποιείται για την ταξινόμηση του εικονοστοιχείου. Στον Gaussian μέσο όρο, η τιμή pixel μακρύτερα από το κέντρο της περιοχής συμβάλλει λιγότερο στην εύρεση του ορίου της περιοχής, ενώ στον αριθμητικό μέσο όρο, όλες οι τιμές pixel συνεισφέρουν εξίσου.

Εφαρμογή του Προσαρμοστικού ορίου χρησιμοποιώντας το OpenCV:

# Arithmatic Mean Adaptive thresholding

thresh6 = cv2.adaptiveThreshold(orig_img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,5,4)
cv2_imshow(thresh6)
# Gaussian Mean Thresholding

thresh7 = cv2.adaptiveThreshold(orig_img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,5,4)
cv2_imshow(thresh7)


Οι παρακάτω εικόνες ελήφθησαν μετά την εφαρμογή προσαρμοστικού κατωφλίου:

Κατώφλι εικόνας

Εισαγωγή στο UNet: Deep Learning Model for Image Segmentation

Σε αυτό το άρθρο, θα συζητήσουμε την αρχιτεκτονική U-Net για τμηματοποίηση εικόνας. Η αρχιτεκτονική UNet εισήχθη για την τμηματοποίηση της BioMedical Image από τους Olag Ronneberger et al. Με αυτήν την αρχιτεκτονική U-Net, η τμηματοποίηση των εικόνων μπορεί να υπολογιστεί με μια σύγχρονη GPU μέσα σε μικρό χρονικό διάστημα. Το UNet χρησιμοποιεί την έννοια του Fully Convolution Network μαζί με ελάχιστες τροποποιήσεις. Αυτό το μοντέλο βοηθά στον εντοπισμό του αντικειμένου σε μια εικόνα και στην εύρεση της μάσκας αυτού του αντικειμένου.

Αρχιτεκτονική U-Net:

Η παρακάτω εικόνα δείχνει την αρχιτεκτονική του U-Net.

Αρχιτεκτονική σε σχήμα U

  • Αυτό το μοντέλο πήρε το όνομά του από την αρχιτεκτονική σε σχήμα U.
  • Όπως μπορούμε να δούμε στην εικόνα, αυτή η αρχιτεκτονική έχει δύο μονοπάτια που δημιουργήθηκαν ως δίκτυο κωδικοποίησης-αποκωδικοποιητή.
  • Εφαρμόζουμε δύο στρώματα συνέλιξης και μέγιστες στρώσεις συγκέντρωσης στην αριστερή διαδρομή.
  • Η λειτουργία ενεργοποίησης ReLU ακολουθεί κάθε συνέλιξη.
  • Στη σωστή διαδρομή, εφαρμόζουμε συνελίξεις μετάθεσης μαζί με δύο κανονικές συνελίξεις

Υλοποίηση UNet χρησιμοποιώντας Keras:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import tensorflow_datasets as tfds
import matplotlib.pyplot as plt
import numpy as np
dataset, info = tfds.load('oxford_iiit_pet:3.*.*', with_info=True)
def resize(input_image, input_mask):
input_image = tf.image.resize(input_image, (128, 128), method="nearest")
input_mask = tf.image.resize(input_mask, (128, 128), method="nearest")
return input_image, input_mask
def augment(input_image, input_mask):
   if tf.random.uniform(()) > 0.5:
       # Random flipping of the image and mask
       input_image = tf.image.flip_left_right(input_image)
       input_mask = tf.image.flip_left_right(input_mask)
   return input_image, input_mask
def normalize(input_image, input_mask):
   input_image = tf.cast(input_image, tf.float32) / 255.0
   input_mask -= 1
   return input_image, input_mask
def load_image_train(datapoint):
   input_image = datapoint["image"]
   input_mask = datapoint["segmentation_mask"]
   input_image, input_mask = resize(input_image, input_mask)
   input_image, input_mask = augment(input_image, input_mask)
   input_image, input_mask = normalize(input_image, input_mask)
   return input_image, input_mask
def load_image_test(datapoint):
   input_image = datapoint["image"]
   input_mask = datapoint["segmentation_mask"]
   input_image, input_mask = resize(input_image, input_mask)
   input_image, input_mask = normalize(input_image, input_mask)
   return input_image, input_mask
train_dataset = dataset["train"].map(load_image_train, num_parallel_calls=tf.data.AUTOTUNE)
test_dataset = dataset["test"].map(load_image_test, num_parallel_calls=tf.data.AUTOTUNE)
BATCH_SIZE = 64
BUFFER_SIZE = 1000
train_batches = train_dataset.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()
train_batches = train_batches.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
validation_batches = test_dataset.take(3000).batch(BATCH_SIZE)
test_batches = test_dataset.skip(3000).take(669).batch(BATCH_SIZE)
def display(display_list):
 plt.figure(figsize=(15, 15))
 title = ["Input Image", "True Mask", "Predicted Mask"]
 for i in range(len(display_list)):
   plt.subplot(1, len(display_list), i+1)
   plt.title(title[i])
   plt.imshow(tf.keras.utils.array_to_img(display_list[i]))
   plt.axis("off")
 plt.show()
sample_batch = next(iter(train_batches))
random_index = np.random.choice(sample_batch[0].shape[0])
#Displaying an image and it's corresponding masked image
sample_image, sample_mask = sample_batch[0][random_index], sample_batch[1][random_index]
display([sample_image, sample_mask])
#Creating 2 convolution blocks with ReLU activation function
def double_conv_block(x, n_filters):
   # Conv2D then ReLU activation
   x = layers.Conv2D(n_filters, 3, padding = "same", activation = "relu", kernel_initializer = "he_normal")(x)
   # Conv2D then ReLU activation
   x = layers.Conv2D(n_filters, 3, padding = "same", activation = "relu", kernel_initializer = "he_normal")(x)
   return x
#Creating downsampling or encoder blocks
def downsample_block(x, n_filters):
   f = double_conv_block(x, n_filters)
   p = layers.MaxPool2D(2)(f)
   p = layers.Dropout(0.3)(p)
   return f, p
# Creating Upsampling or decoder blocks
def upsample_block(x, conv_features, n_filters):
   # Transpose convolution Layer
   x = layers.Conv2DTranspose(n_filters, 3, 2, padding="same")(x)
   # concatenate
   x = layers.concatenate([x, conv_features])
   # dropout
   x = layers.Dropout(0.3)(x)
   # Conv2D twice with ReLU activation
   x = double_conv_block(x, n_filters)
   return x

def build_unet_model(Image_Size):
    # Input Layer
    inputs = layers.Input(shape=Image_Size)
    # Creating 4 downsampling layers
    f1, p1 = downsample_block(inputs, 64)
    f2, p2 = downsample_block(p1, 64*2)
    f3, p3 = downsample_block(p2, 64*4)
    f4, p4 = downsample_block(p3, 64*8)
    # Bottleneck
    bottleneck = double_conv_block(p4, 1024)
    # Creating 4 upsampling layers
    u6 = upsample_block(bottleneck, f4, 512)
    u7 = upsample_block(u6, f3, 256)
    u8 = upsample_block(u7, f2, 128)
    u9 = upsample_block(u8, f1, 64)
    # Output Layer
    outputs = layers.Conv2D(3, 1, padding="same", activation = "softmax")(u9)
    # Creating model with Keras
    unet_model = tf.keras.Model(inputs, outputs, name="U-Net")
    return unet_model
# Creating a model with input shape(128, 128, 3)
unet_model = build_unet_model((128,128,3))

# Compiling the model
# Optimizer - Adam
# loss Categorical cross entropy
# Metrics - Accuracy
unet_model.compile(optimizer=tf.keras.optimizers.Adam(), loss="sparse_categorical_crossentropy", metrics="accuracy")
# Model Training
TRAIN_LENGTH = info.splits["train"].num_examples
STEPS_PER_EPOCH = TRAIN_LENGTH // BATCH_SIZE
VAL_SUBSPLITS = 5
TEST_LENTH = info.splits["test"].num_examples
VALIDATION_STEPS = TEST_LENTH // BATCH_SIZE // VAL_SUBSPLITS
model_history = unet_model.fit(train_batches,epochs=15,steps_per_epoch=STEPS_PER_EPOCH,validation_steps=VALIDATION_STEPS,validation_data=test_batches)
# Creating mask for predicted class
def create_mask(pred_mask):
 pred_mask = tf.argmax(pred_mask, axis=-1)
 pred_mask = pred_mask[..., tf.newaxis]
 return pred_mask[0]
# Prediction
def show_predictions(dataset=None, num=1):
 if dataset:
   for image, mask in dataset.take(num):
     pred_mask = unet_model.predict(image)
     display([image[0], mask[0], create_mask(pred_mask)])
 else:
   display([sample_image, sample_mask,
            create_mask(model.predict(sample_image[tf.newaxis, ...]))])
import cv2
image = cv2.imread('/content/drive/MyDrive/AV/OpenCV/test.jpg')
image1 = cv2.resize(image, (128,128))
cv2_imshow(image1)

image1 = tf.expand_dims(image1, axis=0)
pred_mask = unet_model.predict(image1)

pred_mask1 = tf.expand_dims(pred_mask, axis=0)
display(create_mask(pred_mask1))

συμπέρασμα

Ο κύριος στόχος αυτού του άρθρου είναι να μάθετε για το κατώφλι εικόνας. Βρήκαμε μια σύντομη εισαγωγή στο κατώφλι εικόνας και στις τεχνικές που χρησιμοποιούνται για την εκτέλεση του κατωφλίου εικόνας. Οι τεχνικές κατωφλίου που είδαμε σε αυτό το άρθρο είναι οι εξής:

  1. Η απλή τεχνική κατωφλίου είναι μια συνολική τεχνική κατωφλίου και ο χρήστης παρέχει το όριο εδώ. Είδαμε επίσης διαφορετικούς τύπους απλών τεχνικών κατωφλίου.
  2. Το κατώφλι του Otsu – Είναι επίσης μια παγκόσμια τεχνική κατωφλίου. Το όριο του Otsu χρησιμοποιείται για να βρεθεί η βέλτιστη τιμή κατωφλίου.
  3. Το Adaptive thresholding – είναι μια τοπική τεχνική κατωφλίου. Στο άρθρο δόθηκε επίσης μια σύντομη εισαγωγή στον αριθμητικό μέσο όρο και στις προσαρμοστικές τεχνικές μέσης Gaussian.

Οι παραπάνω τεχνικές χρησιμοποιούνται στο κατώφλι εικόνας. μελετήσαμε επίσης το μοντέλο UNet που χρησιμοποιείται στην τμηματοποίηση εικόνων.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button