├── OIP.jpg ├── OIP1.jpg ├── th.jpg ├── th1.jpg ├── file1 ├── file 1 python file.py ├── README.md ├── file2 ├── file 2 python file.py └── file4 /OIP.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Otutu11/Marine-Debris-Detection/main/OIP.jpg -------------------------------------------------------------------------------- /OIP1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Otutu11/Marine-Debris-Detection/main/OIP1.jpg -------------------------------------------------------------------------------- /th.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Otutu11/Marine-Debris-Detection/main/th.jpg -------------------------------------------------------------------------------- /th1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Otutu11/Marine-Debris-Detection/main/th1.jpg -------------------------------------------------------------------------------- /file1: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import tensorflow as tf 4 | import matplotlib.pyplot as plt 5 | from tensorflow.keras.models import load_model 6 | 7 | # === Step 1: Load and preprocess image === 8 | def load_and_preprocess_image(image_path, target_size=(256, 256)): 9 | img = cv2.imread(image_path) 10 | img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 11 | img = cv2.resize(img, target_size) 12 | img = img / 255.0 # normalize 13 | return img[np.newaxis, ...] 14 | 15 | # === Step 2: Load trained model === 16 | def load_segmentation_model(model_path='marine_debris_unet.h5'): 17 | return load_model(model_path) 18 | 19 | # === Step 3: Predict mask === 20 | def predict_debris(model, preprocessed_image): 21 | pred_mask = model.predict(preprocessed_image) 22 | pred_mask = (pred_mask[0] > 0.5).astype(np.uint8) 23 | return pred_mask 24 | 25 | # === Step 4: Visualize === 26 | def visualize_results(image_path, pred_mask): 27 | original = cv2.imread(image_path) 28 | original = cv2.cvtColor(original, cv2.COLOR_BGR2RGB) 29 | original = cv2.resize(original, (256, 256)) 30 | 31 | plt.figure(figsize=(10, 5)) 32 | plt.subplot(1, 2, 1) 33 | plt.title('Original Image') 34 | plt.imshow(original) 35 | plt.axis('off') 36 | 37 | plt.subplot(1, 2, 2) 38 | plt.title('Detected Marine Debris') 39 | plt.imshow(pred_mask, cmap='gray') 40 | plt.axis('off') 41 | 42 | plt.tight_layout() 43 | plt.show() 44 | 45 | # === Step 5: Run the pipeline === 46 | if __name__ == "__main__": 47 | image_path = 'sample_ocean_image.jpg' # replace with your image 48 | model_path = 'marine_debris_unet.h5' # trained U-Net model 49 | 50 | image = load_and_preprocess_image(image_path) 51 | model = load_segmentation_model(model_path) 52 | pred_mask = predict_debris(model, image) 53 | visualize_results(image_path, pred_mask) 54 | -------------------------------------------------------------------------------- /file 1 python file.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import tensorflow as tf 4 | import matplotlib.pyplot as plt 5 | from tensorflow.keras.models import load_model 6 | 7 | # === Step 1: Load and preprocess image === 8 | def load_and_preprocess_image(image_path, target_size=(256, 256)): 9 | img = cv2.imread(image_path) 10 | img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 11 | img = cv2.resize(img, target_size) 12 | img = img / 255.0 # normalize 13 | return img[np.newaxis, ...] 14 | 15 | # === Step 2: Load trained model === 16 | def load_segmentation_model(model_path='marine_debris_unet.h5'): 17 | return load_model(model_path) 18 | 19 | # === Step 3: Predict mask === 20 | def predict_debris(model, preprocessed_image): 21 | pred_mask = model.predict(preprocessed_image) 22 | pred_mask = (pred_mask[0] > 0.5).astype(np.uint8) 23 | return pred_mask 24 | 25 | # === Step 4: Visualize === 26 | def visualize_results(image_path, pred_mask): 27 | original = cv2.imread(image_path) 28 | original = cv2.cvtColor(original, cv2.COLOR_BGR2RGB) 29 | original = cv2.resize(original, (256, 256)) 30 | 31 | plt.figure(figsize=(10, 5)) 32 | plt.subplot(1, 2, 1) 33 | plt.title('Original Image') 34 | plt.imshow(original) 35 | plt.axis('off') 36 | 37 | plt.subplot(1, 2, 2) 38 | plt.title('Detected Marine Debris') 39 | plt.imshow(pred_mask, cmap='gray') 40 | plt.axis('off') 41 | 42 | plt.tight_layout() 43 | plt.show() 44 | 45 | # === Step 5: Run the pipeline === 46 | if __name__ == "__main__": 47 | image_path = 'sample_ocean_image.jpg' # replace with your image 48 | model_path = 'marine_debris_unet.h5' # trained U-Net model 49 | 50 | image = load_and_preprocess_image(image_path) 51 | model = load_segmentation_model(model_path) 52 | pred_mask = predict_debris(model, image) 53 | visualize_results(image_path, pred_mask) 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🌊 Marine Debris Detection using U-Net 2 | 3 | This project applies deep learning (U-Net architecture) to detect marine debris from satellite or drone imagery. It supports image segmentation for environmental monitoring using datasets like MARIDA and NASA's marine debris archive. 4 | 5 | ## 🧠 Model Overview 6 | 7 | - **Architecture**: U-Net (custom implementation in TensorFlow/Keras) 8 | - **Input Size**: 256x256 RGB images 9 | - **Output**: Binary segmentation mask (debris vs. non-debris) 10 | 11 | ## 📂 Project Structure 12 | 13 | Marine-Debris-Detection/ 14 | │ 15 | ├── train_images/ # Training images (RGB) 16 | ├── train_masks/ # Corresponding binary masks 17 | ├── marine_debris_unet.h5 # Saved U-Net model 18 | ├── marine_debris_detection.py # Inference script 19 | ├── train_unet.py # Training script 20 | ├── requirements.txt # Dependencies 21 | └── README.md # Project documentation 22 | 23 | 24 | ## 📥 Dataset Links 25 | 26 | 1. **[MARIDA: Marine Debris Archive](https://doi.org/10.5281/zenodo.5151941)** 27 | 2. **[NASA Marine Debris Detection](https://github.com/NASA-IMPACT/marine_debris_ML)** 28 | 3. **[Seaclear Dataset (Underwater)](https://www.nature.com/articles/s41597-024-03759-2)** 29 | 30 | ## ⚙️ Installation 31 | 32 | ```bash 33 | git clone https://github.com/YOUR_USERNAME/Marine-Debris-Detection.git 34 | cd Marine-Debris-Detection 35 | pip install -r requirements.txt 36 | 37 | 🏋️‍♂️ Training the U-Net Model 38 | 39 | python train_unet.py 40 | 41 | Ensure you have the following folder structure for training: 42 | 43 | train_images/ 44 | debris1.jpg 45 | debris2.jpg 46 | train_masks/ 47 | debris1_mask.png 48 | debris2_mask.png 49 | 50 | 📌 Images and masks must be size-matched and preprocessed to 256x256. 51 | 52 | 🔍 Running Inference 53 | 54 | python marine_debris_detection.py 55 | 56 | Edit marine_debris_detection.py to update the image path and model path before running. 57 | 📊 Evaluation (optional) 58 | 59 | You can include IoU, Dice score, and precision/recall metrics if you use additional evaluation scripts. 60 | 🛠 Dependencies 61 | 62 | tensorflow 63 | numpy 64 | opencv-python 65 | matplotlib 66 | 67 | Install with: 68 | 69 | pip install tensorflow numpy opencv-python matplotlib 70 | 71 | 🙌 Credits 72 | 73 | Sentinel-2 Imagery via Copernicus Open Access Hub 74 | 75 | MARIDA Dataset – Zenodo 76 | 77 | NASA IMPACT – Marine Debris ML Research 78 | 79 | Author Name: Otutu Anslem 80 | Github: https://github.com/Otutu11 81 | 82 | 📜 License 83 | 84 | MIT License – free to use, adapt, and distribute with attribution. 85 | 86 | 87 | -------------------------------------------------------------------------------- /file2: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import tensorflow as tf 4 | from tensorflow.keras import layers, models 5 | from tensorflow.keras.preprocessing.image import ImageDataGenerator 6 | 7 | # Define U-Net architecture 8 | def unet_model(input_size=(256, 256, 3)): 9 | inputs = tf.keras.Input(input_size) 10 | # Encoder 11 | c1 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(inputs) 12 | c1 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(c1) 13 | p1 = layers.MaxPooling2D((2, 2))(c1) 14 | 15 | c2 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(p1) 16 | c2 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(c2) 17 | p2 = layers.MaxPooling2D((2, 2))(c2) 18 | 19 | c3 = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(p2) 20 | c3 = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(c3) 21 | p3 = layers.MaxPooling2D((2, 2))(c3) 22 | 23 | c4 = layers.Conv2D(512, (3, 3), activation='relu', padding='same')(p3) 24 | c4 = layers.Conv2D(512, (3, 3), activation='relu', padding='same')(c4) 25 | p4 = layers.MaxPooling2D(pool_size=(2, 2))(c4) 26 | 27 | # Bottleneck 28 | c5 = layers.Conv2D(1024, (3, 3), activation='relu', padding='same')(p4) 29 | c5 = layers.Conv2D(1024, (3, 3), activation='relu', padding='same')(c5) 30 | 31 | # Decoder 32 | u6 = layers.Conv2DTranspose(512, (2, 2), strides=(2, 2), padding='same')(c5) 33 | u6 = layers.concatenate([u6, c4]) 34 | c6 = layers.Conv2D(512, (3, 3), activation='relu', padding='same')(u6) 35 | c6 = layers.Conv2D(512, (3, 3), activation='relu', padding='same')(c6) 36 | 37 | u7 = layers.Conv2DTranspose(256, (2, 2), strides=(2, 2), padding='same')(c6) 38 | u7 = layers.concatenate([u7, c3]) 39 | c7 = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(u7) 40 | c7 = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(c7) 41 | 42 | u8 = layers.Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same')(c7) 43 | u8 = layers.concatenate([u8, c2]) 44 | c8 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(u8) 45 | c8 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(c8) 46 | 47 | u9 = layers.Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(c8) 48 | u9 = layers.concatenate([u9, c1], axis=3) 49 | c9 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(u9) 50 | c9 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(c9) 51 | 52 | outputs = layers.Conv2D(1, (1, 1), activation='sigmoid')(c9) 53 | 54 | model = models.Model(inputs=[inputs], outputs=[outputs]) 55 | return model 56 | 57 | # Compile the model 58 | model = unet_model() 59 | model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) 60 | 61 | # Data generators 62 | train_datagen = ImageDataGenerator(rescale=1./255) 63 | train_generator = train_datagen.flow_from_directory( 64 | 'path_to_training_data', 65 | target_size=(256, 256), 66 | batch_size=16, 67 | class_mode='binary') 68 | 69 | # Train the model 70 | model.fit(train_generator, epochs=25) 71 | 72 | # Save the model 73 | model.save('marine_debris_unet.h5') 74 | -------------------------------------------------------------------------------- /file 2 python file.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import tensorflow as tf 4 | from tensorflow.keras import layers, models 5 | from tensorflow.keras.preprocessing.image import ImageDataGenerator 6 | 7 | # Define U-Net architecture 8 | def unet_model(input_size=(256, 256, 3)): 9 | inputs = tf.keras.Input(input_size) 10 | # Encoder 11 | c1 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(inputs) 12 | c1 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(c1) 13 | p1 = layers.MaxPooling2D((2, 2))(c1) 14 | 15 | c2 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(p1) 16 | c2 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(c2) 17 | p2 = layers.MaxPooling2D((2, 2))(c2) 18 | 19 | c3 = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(p2) 20 | c3 = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(c3) 21 | p3 = layers.MaxPooling2D((2, 2))(c3) 22 | 23 | c4 = layers.Conv2D(512, (3, 3), activation='relu', padding='same')(p3) 24 | c4 = layers.Conv2D(512, (3, 3), activation='relu', padding='same')(c4) 25 | p4 = layers.MaxPooling2D(pool_size=(2, 2))(c4) 26 | 27 | # Bottleneck 28 | c5 = layers.Conv2D(1024, (3, 3), activation='relu', padding='same')(p4) 29 | c5 = layers.Conv2D(1024, (3, 3), activation='relu', padding='same')(c5) 30 | 31 | # Decoder 32 | u6 = layers.Conv2DTranspose(512, (2, 2), strides=(2, 2), padding='same')(c5) 33 | u6 = layers.concatenate([u6, c4]) 34 | c6 = layers.Conv2D(512, (3, 3), activation='relu', padding='same')(u6) 35 | c6 = layers.Conv2D(512, (3, 3), activation='relu', padding='same')(c6) 36 | 37 | u7 = layers.Conv2DTranspose(256, (2, 2), strides=(2, 2), padding='same')(c6) 38 | u7 = layers.concatenate([u7, c3]) 39 | c7 = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(u7) 40 | c7 = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(c7) 41 | 42 | u8 = layers.Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same')(c7) 43 | u8 = layers.concatenate([u8, c2]) 44 | c8 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(u8) 45 | c8 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(c8) 46 | 47 | u9 = layers.Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(c8) 48 | u9 = layers.concatenate([u9, c1], axis=3) 49 | c9 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(u9) 50 | c9 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(c9) 51 | 52 | outputs = layers.Conv2D(1, (1, 1), activation='sigmoid')(c9) 53 | 54 | model = models.Model(inputs=[inputs], outputs=[outputs]) 55 | return model 56 | 57 | # Compile the model 58 | model = unet_model() 59 | model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) 60 | 61 | # Data generators 62 | train_datagen = ImageDataGenerator(rescale=1./255) 63 | train_generator = train_datagen.flow_from_directory( 64 | 'path_to_training_data', 65 | target_size=(256, 256), 66 | batch_size=16, 67 | class_mode='binary') 68 | 69 | # Train the model 70 | model.fit(train_generator, epochs=25) 71 | 72 | # Save the model 73 | model.save('marine_debris_unet.h5') 74 | -------------------------------------------------------------------------------- /file4: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import tensorflow as tf 4 | from tensorflow.keras import layers, models 5 | from tensorflow.keras.preprocessing.image import ImageDataGenerator 6 | 7 | def unet_model(input_size=(256, 256, 3)): 8 | inputs = tf.keras.Input(input_size) 9 | c1 = layers.Conv2D(64, 3, activation='relu', padding='same')(inputs) 10 | c1 = layers.Conv2D(64, 3, activation='relu', padding='same')(c1) 11 | p1 = layers.MaxPooling2D()(c1) 12 | 13 | c2 = layers.Conv2D(128, 3, activation='relu', padding='same')(p1) 14 | c2 = layers.Conv2D(128, 3, activation='relu', padding='same')(c2) 15 | p2 = layers.MaxPooling2D()(c2) 16 | 17 | c3 = layers.Conv2D(256, 3, activation='relu', padding='same')(p2) 18 | c3 = layers.Conv2D(256, 3, activation='relu', padding='same')(c3) 19 | p3 = layers.MaxPooling2D()(c3) 20 | 21 | c4 = layers.Conv2D(512, 3, activation='relu', padding='same')(p3) 22 | c4 = layers.Conv2D(512, 3, activation='relu', padding='same')(c4) 23 | p4 = layers.MaxPooling2D()(c4) 24 | 25 | c5 = layers.Conv2D(1024, 3, activation='relu', padding='same')(p4) 26 | c5 = layers.Conv2D(1024, 3, activation='relu', padding='same')(c5) 27 | 28 | u6 = layers.Conv2DTranspose(512, 2, strides=2, padding='same')(c5) 29 | u6 = layers.concatenate([u6, c4]) 30 | c6 = layers.Conv2D(512, 3, activation='relu', padding='same')(u6) 31 | c6 = layers.Conv2D(512, 3, activation='relu', padding='same')(c6) 32 | 33 | u7 = layers.Conv2DTranspose(256, 2, strides=2, padding='same')(c6) 34 | u7 = layers.concatenate([u7, c3]) 35 | c7 = layers.Conv2D(256, 3, activation='relu', padding='same')(u7) 36 | c7 = layers.Conv2D(256, 3, activation='relu', padding='same')(c7) 37 | 38 | u8 = layers.Conv2DTranspose(128, 2, strides=2, padding='same')(c7) 39 | u8 = layers.concatenate([u8, c2]) 40 | c8 = layers.Conv2D(128, 3, activation='relu', padding='same')(u8) 41 | c8 = layers.Conv2D(128, 3, activation='relu', padding='same')(c8) 42 | 43 | u9 = layers.Conv2DTranspose(64, 2, strides=2, padding='same')(c8) 44 | u9 = layers.concatenate([u9, c1]) 45 | c9 = layers.Conv2D(64, 3, activation='relu', padding='same')(u9) 46 | c9 = layers.Conv2D(64, 3, activation='relu', padding='same')(c9) 47 | 48 | outputs = layers.Conv2D(1, 1, activation='sigmoid')(c9) 49 | 50 | model = models.Model(inputs, outputs) 51 | return model 52 | 53 | # Compile and summarize the model 54 | model = unet_model() 55 | model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) 56 | model.summary() 57 | 58 | # Example training loop (requires masks and preprocessed images) 59 | # Define data generators 60 | train_gen = ImageDataGenerator(rescale=1./255) 61 | train_data = train_gen.flow_from_directory( 62 | 'train_images/', # folder with image data 63 | target_size=(256, 256), 64 | class_mode=None, 65 | batch_size=8 66 | ) 67 | 68 | mask_gen = ImageDataGenerator(rescale=1./255) 69 | mask_data = mask_gen.flow_from_directory( 70 | 'train_masks/', # folder with mask data 71 | target_size=(256, 256), 72 | class_mode=None, 73 | batch_size=8 74 | ) 75 | 76 | # Train 77 | model.fit(zip(train_data, mask_data), steps_per_epoch=100, epochs=25) 78 | 79 | # Save model 80 | model.save("marine_debris_unet.h5") 81 | --------------------------------------------------------------------------------