EX6 = r"""print("6.1: Scale Invariant Feature Transform (SIFT)")

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread("your_image.jpg", cv2.IMREAD_GRAYSCALE)

plt.figure(figsize=(6,6))
plt.imshow(img, cmap='gray')
plt.title("Input Image")
plt.axis("off")
plt.show()

def build_gaussian_pyramid(image, num_octaves=4, num_scales=5, sigma=1.6):
    pyramid = []
    
    for octave in range(num_octaves):
        octave_images = []
        for scale in range(num_scales):
            sigma_eff = sigma * (2 ** (scale / float(num_scales)))
            blurred = cv2.GaussianBlur(image, (0,0), sigma_eff)
            octave_images.append(blurred)
        pyramid.append(octave_images)
        image = cv2.pyrDown(image)  
    return pyramid

gaussian_pyramid = build_gaussian_pyramid(img)

print("Gaussian pyramid constructed.")

plt.figure(figsize=(12,4))
for i in range(len(gaussian_pyramid[0])):
    plt.subplot(1,5,i+1)
    plt.imshow(gaussian_pyramid[0][i], cmap='gray')
    plt.title(f"Scale {i}")
    plt.axis("off")
plt.show()

def build_DoG_pyramid(gaussian_pyr):
    DoG_pyramid = []
    for octave in gaussian_pyr:
        DoG_images = []
        for i in range(1, len(octave)):
            DoG = cv2.subtract(octave[i], octave[i-1])
            DoG_images.append(DoG)
        DoG_pyramid.append(DoG_images)
    return DoG_pyramid

DoG_pyramid = build_DoG_pyramid(gaussian_pyramid)

print("Difference of Gaussians pyramid constructed.")

# Show first octave DoG
plt.figure(figsize=(12,4))
for i in range(len(DoG_pyramid[0])):
    plt.subplot(1,4,i+1)
    plt.imshow(DoG_pyramid[0][i], cmap='gray')
    plt.title(f"DoG {i}")
    plt.axis("off")
plt.show()

sift = cv2.SIFT_create()
keypoints, descriptors = sift.detectAndCompute(img, None)

print("Total keypoints:", len(keypoints))
print("Descriptor shape:", descriptors.shape)

img_with_orient = cv2.drawKeypoints(
    img, keypoints, None,
    flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
)

plt.figure(figsize=(6,6))
plt.imshow(img_with_orient, cmap='gray')
plt.title("Keypoints with Orientation")
plt.axis("off")
plt.show()

print("\nSIFT Descriptor example (first keypoint):")
print(descriptors[0])

print("\n6.2: Transfer Learning using ResNet50")

import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import ResNet50
from tensorflow.keras import layers, models
import matplotlib.pyplot as plt
import os

train_dir = r"D:\Studies\Sem-7\Image Processing and Computer Vision\Model\horse-or-human\train"
test_dir  = r"D:\Studies\Sem-7\Image Processing and Computer Vision\Model\horse-or-human\validation"

num_train = sum([len(files) for r, d, files in os.walk(train_dir)])
num_test  = sum([len(files) for r, d, files in os.walk(test_dir)])
print(f"Number of training images: {num_train}")
print(f"Number of testing images: {num_test}")

train_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir, target_size=(128,128), batch_size=32, class_mode='binary')

x_batch, y_batch = next(train_generator)
plt.figure(figsize=(8,8))
for i in range(9):
    plt.subplot(3,3,i+1)
    plt.imshow(x_batch[i])
    plt.title('Horse' if y_batch[i]==0 else 'Human')
    plt.axis('off')
plt.show()

test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir, target_size=(128,128), batch_size=32, class_mode='binary')
test_generator  = test_datagen.flow_from_directory(test_dir, target_size=(128,128), batch_size=32, class_mode='binary')

base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(128,128,3))
base_model.trainable = False  

model = models.Sequential([
    base_model,
    layers.GlobalAveragePooling2D(),
    layers.Dense(128, activation='relu'),
    layers.Dense(1, activation='sigmoid')
])

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()

history = model.fit(train_generator, validation_data=test_generator, epochs=5)

plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Test Accuracy')
plt.title('Training vs Testing Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
"""
def get6():
    print(EX6)