Spaces:
Sleeping
Sleeping
import tensorflow as tf | |
import numpy as np | |
from PIL import Image | |
import joblib | |
import os | |
from tensorflow.keras.models import Sequential | |
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten | |
class BoundingBoxPredictor: | |
def __init__(self): | |
self.cnn_model = None | |
self.knn_model = None | |
self.input_shape = (128, 128) | |
# Updated normalization values based on actual dataset analysis | |
self.y_min = np.array([0., 0., 30., 30.]) # min values for x, y, width, height | |
self.y_max = np.array([97., 97., 49., 49.]) # max values for x, y, width, height | |
def create_cnn_model(self): | |
model = Sequential([ | |
Conv2D(32, (3, 3), activation='relu', input_shape=(*self.input_shape, 1)), | |
MaxPooling2D((2, 2)), | |
Conv2D(64, (3, 3), activation='relu'), | |
MaxPooling2D((2, 2)), | |
Flatten(), | |
Dense(128, activation='relu'), | |
Dense(4, activation='sigmoid') | |
]) | |
model.compile(optimizer='adam', loss='mse', metrics=['mse']) | |
return model | |
def load_models(self, cnn_path, knn_path): | |
# Check if files exist | |
if not os.path.exists(cnn_path): | |
raise FileNotFoundError(f"CNN model file not found: {cnn_path}") | |
if not os.path.exists(knn_path): | |
raise FileNotFoundError(f"KNN model file not found: {knn_path}") | |
print(f"Loading CNN model from: {cnn_path}") | |
try: | |
self.cnn_model = tf.keras.models.load_model(cnn_path) | |
except Exception as e: | |
print(f"Error loading CNN model: {str(e)}") | |
print("Creating new CNN model...") | |
self.cnn_model = self.create_cnn_model() | |
try: | |
self.cnn_model.load_weights(cnn_path) | |
print("Successfully loaded CNN weights") | |
except: | |
print("Could not load CNN weights, using uninitialized model") | |
print("CNN model ready") | |
print(f"Loading KNN model from: {knn_path}") | |
self.knn_model = joblib.load(knn_path) | |
print("KNN model loaded successfully") | |
def preprocess_image(self, image): | |
# Convert to grayscale if needed | |
if image.mode != 'L': | |
image = image.convert('L') | |
# Resize image | |
image = image.resize(self.input_shape) | |
# Convert to numpy array and normalize | |
img_array = np.array(image) | |
img_array = img_array / 255.0 | |
return img_array | |
def predict(self, image, model_type='cnn'): | |
# Check if models are loaded | |
if model_type == 'cnn' and self.cnn_model is None: | |
raise ValueError("CNN model not loaded. Please call load_models first.") | |
if model_type == 'knn' and self.knn_model is None: | |
raise ValueError("KNN model not loaded. Please call load_models first.") | |
# Preprocess the image | |
processed_image = self.preprocess_image(image) | |
try: | |
if model_type == 'cnn': | |
# Reshape for CNN input | |
img_array = processed_image.reshape(1, *self.input_shape, 1) | |
# Get normalized predictions (between 0 and 1) | |
prediction = self.cnn_model.predict(img_array)[0] | |
# Denormalize predictions to original scale | |
prediction = prediction * (self.y_max - self.y_min) + self.y_min | |
else: # KNN | |
# Flatten for KNN input | |
img_array = processed_image.flatten().reshape(1, -1) | |
# Get normalized predictions | |
prediction = self.knn_model.predict(img_array)[0] | |
# Denormalize predictions to original scale | |
prediction = prediction * (self.y_max - self.y_min) + self.y_min | |
# Ensure predictions are within valid ranges | |
prediction = np.clip(prediction, self.y_min, self.y_max) | |
return { | |
'x': float(prediction[0]), | |
'y': float(prediction[1]), | |
'width': float(prediction[2]), | |
'height': float(prediction[3]) | |
} | |
except Exception as e: | |
print(f"Error during prediction with {model_type.upper()} model: {str(e)}") | |
raise | |