import os import json import tensorflow as tf import numpy as np import cv2 from video_compression_model import NUM_CHANNELS, NUM_FRAMES, VideoCompressionModel, PRESET_SPEED_CATEGORIES from tensorflow.keras.callbacks import EarlyStopping # Constants BATCH_SIZE = 16 EPOCHS = 1 TRAIN_SAMPLES = 1 def load_list(list_path): with open(list_path, "r") as json_file: video_details_list = json.load(json_file) return video_details_list def load_frames_from_video(video_file, num_frames): print("Extracting video frames...") cap = cv2.VideoCapture(video_file) frames = [] count = 0 while True: ret, frame = cap.read() if not ret: break frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) frames.append(frame) count += 1 if count >= num_frames: break cap.release() width, height = frame.shape[:2] return frames, width, height def preprocess(frames): return np.array(frames) / 255.0 def save_model(model, file): os.makedirs("models", exist_ok=True) model.save(os.path.join("models/", file)) print("Model saved successfully!") def load_video_from_list(list_path): details_list = load_list(list_path) all_frames = [] all_details = [] for video_details in details_list: VIDEO_FILE = video_details["video_file"] CRF = video_details['crf'] / 63.0 PRESET_SPEED = PRESET_SPEED_CATEGORIES.index(video_details['preset_speed']) video_details['preset_speed'] = PRESET_SPEED train_frames, w, h = load_frames_from_video(os.path.join("test_data/", VIDEO_FILE), NUM_FRAMES * TRAIN_SAMPLES) all_frames.extend(train_frames) all_details.append({ "frames": train_frames, "width": w, "height": h, "crf": CRF, "preset_speed": PRESET_SPEED, "video_file": VIDEO_FILE }) return all_details def generate_frame_sequences(frames): sequences = [] labels = [] for i in range(len(frames) - NUM_FRAMES + 2): sequence = frames[i:i+NUM_FRAMES-1] sequences.append(sequence) labels.append(sequence[-1]) return np.array(sequences), np.array(labels) def frame_difference(frames): differences = [] for i in range(1, len(frames)): differences.append(cv2.absdiff(frames[i], frames[i-1])) return differences def main(): all_video_details_train = load_video_from_list("test_data/training.json") all_video_details_val = load_video_from_list("test_data/validation.json") model = VideoCompressionModel(NUM_CHANNELS, NUM_FRAMES) model.compile(loss='mean_squared_error', optimizer='adam') early_stop = EarlyStopping(monitor='val_loss', patience=3, verbose=1, restore_best_weights=True) for video_details_train, video_details_val in zip(all_video_details_train, all_video_details_val): train_frames = video_details_train["frames"] val_frames = video_details_val["frames"] train_differences = frame_difference(preprocess(train_frames)) val_differences = frame_difference(preprocess(val_frames)) train_sequences, train_labels = generate_frame_sequences(train_differences) val_sequences, val_labels = generate_frame_sequences(val_differences) num_sequences_train = len(train_sequences) num_sequences_val = len(val_sequences) crf_array_train = np.full((num_sequences_train, 1), video_details_train['crf']) crf_array_val = np.full((num_sequences_val, 1), video_details_val['crf']) preset_speed_array_train = np.full((num_sequences_train, 1), video_details_train['preset_speed']) preset_speed_array_val = np.full((num_sequences_val, 1), video_details_val['preset_speed']) print(len(train_sequences)) print(len(val_sequences)) print("\nTraining the model for video:", video_details_train["video_file"]) model.fit( {"frames": train_sequences, "crf": crf_array_train, "preset_speed": preset_speed_array_train}, train_labels, batch_size=BATCH_SIZE, epochs=EPOCHS, validation_data=({"frames": val_sequences, "crf": crf_array_val, "preset_speed": preset_speed_array_val}, val_labels), callbacks=[early_stop] ) print("\nTraining completed for video:", video_details_train["video_file"]) save_model(model, 'model_differencing.keras') if __name__ == "__main__": main()