{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":4521,"databundleVersionId":326986,"sourceType":"competition"}],"dockerImageVersionId":30805,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install ultralytics","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-03T21:41:43.457618Z","iopub.execute_input":"2024-12-03T21:41:43.458220Z","iopub.status.idle":"2024-12-03T21:41:52.952038Z","shell.execute_reply.started":"2024-12-03T21:41:43.458180Z","shell.execute_reply":"2024-12-03T21:41:52.950829Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118\n!pip install 'git+https://github.com/facebookresearch/detectron2.git'\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-03T21:52:52.900221Z","iopub.execute_input":"2024-12-03T21:52:52.900641Z","iopub.status.idle":"2024-12-03T21:54:51.856220Z","shell.execute_reply.started":"2024-12-03T21:52:52.900606Z","shell.execute_reply":"2024-12-03T21:54:51.855008Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport zipfile\nimport pandas as pd\n\n# Paths to files and folders\nbase_dir = '/kaggle/input/noaa-right-whale-recognition'\nzip_file_path = os.path.join(base_dir, 'imgs.zip')\ntrain_csv_path = os.path.join(base_dir, 'train.csv')\nextraction_dir = './extracted_images'\nimgs_dir = os.path.join(extraction_dir, 'imgs')\n\n# Step 1: Extract Images\nos.makedirs(extraction_dir, exist_ok=True)\nif not os.path.exists(imgs_dir):\n    with zipfile.ZipFile(zip_file_path, 'r') as zip_ref:\n        zip_ref.extractall(extraction_dir)\nprint(f\"Extracted images to {imgs_dir}\")\n\n# Step 2: Load Train CSV and Analyze Data\ntrain_df = pd.read_csv(train_csv_path)\ntrain_image_files = train_df['Image'].tolist()\nunique_classes = train_df['whaleID'].nunique()\n\n# Step 3: Count Training and Testing Images\nall_images = os.listdir(imgs_dir)\ntraining_images = [img for img in all_images if img in train_image_files]\ntest_images = [img for img in all_images if img not in train_image_files]\n\n# Print Statistics\nprint(f\"Total Images: {len(all_images)}\")\nprint(f\"Training Images: {len(training_images)}\")\nprint(f\"Testing Images: {len(test_images)}\")\nprint(f\"Unique Classes in Training Set: {unique_classes}\")\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-03T21:10:55.314527Z","iopub.execute_input":"2024-12-03T21:10:55.314934Z","iopub.status.idle":"2024-12-03T21:12:53.636017Z","shell.execute_reply.started":"2024-12-03T21:10:55.314909Z","shell.execute_reply":"2024-12-03T21:12:53.635197Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\n\n# Paths\nbase_dir = '/kaggle/working/extracted_images'\nimgs_dir = os.path.join(base_dir, 'imgs')\ntrain_csv_path = '/kaggle/input/noaa-right-whale-recognition/train.csv'\n\n# Load the train.csv\ntrain_df = pd.read_csv(train_csv_path)\n\n# Check dataset structure\nall_images = os.listdir(imgs_dir)\ntrain_images = train_df['Image'].tolist()\ntest_images = [img for img in all_images if img not in train_images]\n\n# Count images\nprint(f\"Total images in dataset: {len(all_images)}\")\nprint(f\"Training images (from train.csv): {len(train_images)}\")\nprint(f\"Test images (not in train.csv): {len(test_images)}\")\nprint(f\"Unique classes (whale IDs): {train_df['whaleID'].nunique()}\")\n\n# Display some sample images\ndef display_samples(img_list, title, img_dir=imgs_dir, max_samples=2):\n    fig, axes = plt.subplots(1, min(max_samples, len(img_list)), figsize=(10, 5))\n    for i, img_name in enumerate(img_list[:max_samples]):\n        img_path = os.path.join(img_dir, img_name)\n        img = cv2.imread(img_path)[..., ::-1]\n        axes[i].imshow(img)\n        axes[i].axis('off')\n        axes[i].set_title(img_name)\n    plt.suptitle(title)\n    plt.show()\n\n# Show 2 sample training images\nsample_train_images = train_images[:2]\nprint(\"Sample training images:\")\ndisplay_samples(sample_train_images, \"Sample Training Images\")\n\n# Show 2 sample test images\nsample_test_images = test_images[:2]\nprint(\"Sample test images:\")\ndisplay_samples(sample_test_images, \"Sample Test Images\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-03T21:12:53.638015Z","iopub.execute_input":"2024-12-03T21:12:53.638692Z","iopub.status.idle":"2024-12-03T21:12:57.888250Z","shell.execute_reply.started":"2024-12-03T21:12:53.638653Z","shell.execute_reply":"2024-12-03T21:12:57.887411Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nfrom detectron2.config import get_cfg\nfrom detectron2.engine import DefaultPredictor\nfrom detectron2 import model_zoo\nimport os\nimport cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom sklearn.cluster import KMeans\n\ndef setup_mask_rcnn():\n    cfg = get_cfg()\n    cfg.merge_from_file(model_zoo.get_config_file(\"COCO-InstanceSegmentation/mask_rcnn_R_101_FPN_3x.yaml\"))\n    cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(\"COCO-InstanceSegmentation/mask_rcnn_R_101_FPN_3x.yaml\")\n    cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.3  # Lower detection threshold\n    cfg.MODEL.ROI_HEADS.NMS_THRESH_TEST = 0.7  # Higher NMS IoU threshold\n    cfg.MODEL.RPN.POST_NMS_TOPK_TEST = 1500  # Increase number of proposals\n    cfg.MODEL.DEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"  # Use GPU if available\n    return DefaultPredictor(cfg)\n\nmask_rcnn_predictor = setup_mask_rcnn()\ndef detect_and_crop(image_path, predictor, output_dir, expansion=0.1):\n    \"\"\"\n    Detect and crop the whale using Mask R-CNN. Fall back to K-means clustering if detection fails.\n    \"\"\"\n    original_img = cv2.imread(image_path)\n    outputs = predictor(original_img)\n    instances = outputs[\"instances\"].to(\"cpu\")\n    \n    if len(instances) > 0:\n        # Get the largest detected mask\n        masks = instances.pred_masks.numpy()\n        largest_mask = masks[np.argmax(instances.pred_boxes.area())]\n\n        # Create bounding box around the mask\n        y, x = np.where(largest_mask)\n        x_min, x_max = x.min(), x.max()\n        y_min, y_max = y.min(), y.max()\n\n        # Expand the bounding box slightly\n        x_expansion = int((x_max - x_min) * expansion)\n        y_expansion = int((y_max - y_min) * expansion)\n        x_min = max(0, x_min - x_expansion)\n        y_min = max(0, y_min - y_expansion)\n        x_max = min(original_img.shape[1], x_max + x_expansion)\n        y_max = min(original_img.shape[0], y_max + y_expansion)\n\n        # Crop the region\n        cropped_img = original_img[y_min:y_max, x_min:x_max]\n\n        # Save cropped image\n        cropped_img_name = os.path.basename(image_path).replace('.jpg', '_cropped.jpg')\n        output_path = os.path.join(output_dir, cropped_img_name)\n        cv2.imwrite(output_path, cropped_img)\n\n        return original_img, cropped_img\n    else:\n        return segment_and_crop_kmeans(image_path, output_dir)  # Fallback to K-means\n\ndef segment_and_crop_kmeans(image_path, output_dir, expansion=0.1):\n    \"\"\"\n    Fallback method: Segment using K-means clustering and crop the largest connected component.\n    \"\"\"\n    original_img = cv2.imread(image_path)\n    img = cv2.cvtColor(original_img, cv2.COLOR_BGR2LAB)\n\n    # K-means clustering\n    pixel_values = img.reshape((-1, 3)).astype(np.float32)\n    _, labels, centers = cv2.kmeans(pixel_values, 2, None,\n                                    criteria=(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2),\n                                    attempts=10, flags=cv2.KMEANS_RANDOM_CENTERS)\n\n    # Map labels back to image dimensions\n    labels = labels.flatten().reshape(img.shape[:2])\n    largest_cluster = 1 if np.sum(labels == 1) > np.sum(labels == 0) else 0\n    binary_mask = (labels == largest_cluster).astype(np.uint8) * 255\n\n    # Refine the binary mask\n    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))\n    refined_mask = cv2.morphologyEx(binary_mask, cv2.MORPH_CLOSE, kernel)\n    refined_mask = cv2.morphologyEx(refined_mask, cv2.MORPH_OPEN, kernel)\n\n    # Find the largest contour (assumed to be the whale)\n    contours, _ = cv2.findContours(refined_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n    if contours:\n        largest_contour = max(contours, key=cv2.contourArea)\n        x, y, w, h = cv2.boundingRect(largest_contour)\n\n        # Expand the bounding box slightly\n        x_expansion = int(w * expansion)\n        y_expansion = int(h * expansion)\n        x = max(0, x - x_expansion)\n        y = max(0, y - y_expansion)\n        w = min(original_img.shape[1] - x, w + 2 * x_expansion)\n        h = min(original_img.shape[0] - y, h + 2 * y_expansion)\n\n        # Crop the region\n        cropped_img = original_img[y:y + h, x:x + w]\n\n        # Save cropped image\n        cropped_img_name = os.path.basename(image_path).replace('.jpg', '_kmeans.jpg')\n        output_path = os.path.join(output_dir, cropped_img_name)\n        cv2.imwrite(output_path, cropped_img)\n\n        return original_img, cropped_img\n    return original_img, None\n# Paths\nimgs_dir = './extracted_images/imgs'\noutput_cropped_dir = './cropped_images_combined'\nos.makedirs(output_cropped_dir, exist_ok=True)\n\n# Process and display results for random images\nrandom_images = random.sample(os.listdir(imgs_dir), 4)\nfor img_name in random_images:\n    img_path = os.path.join(imgs_dir, img_name)\n    original_img, cropped_img = detect_and_crop(img_path, mask_rcnn_predictor, output_cropped_dir)\n    show_images(original_img, cropped_img, img_name)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-03T21:59:45.795713Z","iopub.execute_input":"2024-12-03T21:59:45.796042Z","iopub.status.idle":"2024-12-03T22:00:11.338319Z","shell.execute_reply.started":"2024-12-03T21:59:45.796014Z","shell.execute_reply":"2024-12-03T22:00:11.337498Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}