Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Untitled1.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[],"mount_file_id":"1Hi1q37BQmZjp7hNKV5nKFEnAHGDt4UJ6","authorship_tag":"ABX9TyMBvTg5ACXmjvG27VVQWfmE"},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":1000,"output_embedded_package_id":"18pqUFiLx-etkSEycYauUnnkreKbVHmI7"},"id":"c4fGXzVCgMlc","executionInfo":{"status":"ok","timestamp":1766762127328,"user_tz":-330,"elapsed":108320,"user":{"displayName":"Aradhya Stuti","userId":"13084479309528900862"}},"outputId":"62d9ab7b-da85-4d8b-fa97-f0eac2c6b247"},"outputs":[{"output_type":"display_data","data":{"text/plain":"Output hidden; open in https://colab.research.google.com to view."},"metadata":{}}],"source":["import cv2\n","import matplotlib.pyplot as plt\n","import os\n","import glob # Import the glob library\n","\n","from google.colab import drive\n","drive.mount('/content/drive')\n","\n","# --- CONFIGURATION PARAMETERS ---\n","# Define the size of the patch to save (in pixels)\n","PATCH_SIZE = 64\n","BW, BH = PATCH_SIZE, PATCH_SIZE\n","\n","# Define the paths\n","template_path = '/content/drive/MyDrive/PCB_DATASET/PCB_DATASET/PCB_USED/04.JPG'\n","folder_path = '/content/drive/MyDrive/PCB_DATASET/PCB_DATASET/images/Missing_hole/4'\n","out_dir = \"/content/drive/MyDrive/PCB_DATASET/PCB_DATASET/Missing_hole_4defects\"\n","\n","# Ensure the output directory exists\n","os.makedirs(out_dir, exist_ok=True)\n","\n","# Global counter for saved patches - MUST be initialized outside the loop\n","global_patch_id = 0\n","\n","# Define the area constraints for defect detection\n","MIN_AREA = 0\n","MAX_AREA = 1500\n","\n","\n","# Read template PCB 01 image\n","rgb_template_img = cv2.imread(template_path)\n","plt.figure(figsize=(10,6))\n","plt.imshow(rgb_template_img, cmap=\"gray\")\n","\n","# Calculate the resized dimensions (1/4th of original)\n","a = int(rgb_template_img.shape[0]/4)\n","b = int(rgb_template_img.shape[1]/4)\n","\n","# Read template PCB 01 image as grayscale\n","template_img = cv2.imread(template_path, 0)\n","# display the grayscale template PCB image\n","plt.figure(figsize=(10,6))\n","plt.imshow(template_img, cmap=\"gray\")\n","\n","# Resize template image of PCB\n","template_img_resize = cv2.resize(template_img, (b,a))\n","plt.figure(figsize=(10,6))\n","plt.imshow(template_img_resize, cmap=\"gray\")\n","\n","# Gaussian blur\n","blur_template_img = cv2.GaussianBlur(template_img_resize, (3,3),0)\n","# display the blurred image\n","plt.figure(figsize=(10,6))\n","plt.imshow(blur_template_img, cmap=\"gray\")\n","\n","# Adaptive thresholding\n","template_adap_thresh = cv2.adaptiveThreshold(blur_template_img, 255,\n"," cv2. ADAPTIVE_THRESH_MEAN_C,\n"," cv2.THRESH_BINARY, 15, 5)\n","# display the thresholded image\n","plt.figure(figsize=(10,6))\n","plt.imshow(template_adap_thresh, cmap=\"gray\")\n","# Note: Initial display code for template is removed here to keep the final script cleaner,\n","# but it can be re-added before the loop if needed for verification.\n","\n","\n","# Use glob to find all files ending with '.jpg' in the specified folder\n","image_files = glob.glob(os.path.join(folder_path, '*.jpg'))\n","\n","print(f\"Found {len(image_files)} images in the folder.\")\n","print(f\"Defect area filter range: {MIN_AREA} < Area < {MAX_AREA}\")\n","\n","\n","\n","# Iterate over each image file path found\n","for image_path in image_files:\n"," # 1. Read and prepare test image\n"," bgr_test_img = cv2.imread(image_path)\n"," filename = os.path.basename(image_path)\n","\n"," # Check if the image was loaded successfully\n"," if bgr_test_img is None:\n"," print(f\"Skipping file: {filename} (Not a readable image).\")\n"," continue\n","\n"," # Convert BGR to RGB for matplotlib display (if needed)\n"," rgb_test_img = cv2.cvtColor(bgr_test_img, cv2.COLOR_BGR2RGB) # Not used below, but good practice\n"," # 2. Display the original test PCB image\n"," plt.figure(figsize=(10,6))\n"," plt.imshow(rgb_test_img, cmap = \"gray\")\n"," plt.title(f\"Original Test PCB Image: {filename}\")\n","\n"," # Read grayscale\n"," test_img = cv2.imread(image_path, 0)\n","\n"," # Resize, Blur, and Threshold the test image\n"," test_img_resize = cv2.resize(test_img, (b, a))\n"," # 3. Display the grayscale resized test PCB image\n"," plt.figure(figsize=(10,6))\n"," plt.imshow(test_img_resize, cmap=\"gray\")\n"," plt.title(f\"Resized Grayscale PCB Image: {filename} ({b}x{a})\")\n"," blur_test_img = cv2.GaussianBlur(test_img_resize, (3,3),0)\n","\n"," test_adap_thresh = cv2.adaptiveThreshold(blur_test_img, 255,\n"," cv2. ADAPTIVE_THRESH_MEAN_C,\n"," cv2.THRESH_BINARY, 15, 5)\n","\n"," plt.figure(figsize=(10,6))\n"," plt.imshow(test_adap_thresh, cmap=\"gray\")\n","\n"," # 2. Difference Imaging (Core Defect Detection)\n"," sub_img = cv2.subtract(test_adap_thresh, template_adap_thresh)\n"," plt.figure(figsize=(10,6))\n"," plt.imshow(sub_img)\n"," final_img = cv2.medianBlur(sub_img, 3) # Noise reduction\n"," plt.figure(figsize=(10,6))\n"," plt.imshow(final_img, cmap=\"gray\")\n","\n"," # 3. Find Contours\n"," # Using RETR_EXTERNAL focuses on the outline of defect blobs\n"," # Note: final_img is the mask image used for finding contours\n","\n"," orig = test_img_resize\n"," mask_img = final_img\n"," _, thresh = cv2.threshold(mask_img, 127, 255, cv2.THRESH_BINARY)\n"," contours, _ = cv2.findContours(thresh, cv2.RETR_LIST,\n"," cv2.CHAIN_APPROX_SIMPLE) # CHANGE ***\n","\n"," current_defects_count = 0\n"," orig = test_img_resize # The source image for cropping\n"," h_img, w_img = final_img.shape[:2]\n","\n","\n"," # 4. Filter Contours and Save Patches (MUST be inside the image loop)\n"," for cnt in contours:\n"," area = cv2.contourArea(cnt)\n","\n"," # Apply the defect area filter to ensure quality and control quantity\n"," if MIN_AREA < area < MAX_AREA:\n"," current_defects_count += 1\n","\n"," # Get bounding box coordinates\n"," x, y, w, h = cv2.boundingRect(cnt)\n","\n"," # Center of defect\n"," cx = x + w // 2\n"," cy = y + h // 2\n","\n"," # Fixed PATCh_SIZE x PATCh_SIZE box centered on defect\n"," x0 = cx - BW // 2\n"," y0 = cy - BH // 2\n"," x1 = x0 + BW\n"," y1 = y0 + BH\n","\n"," # Clip coordinates to image bounds\n"," x0 = max(0, x0)\n"," y0 = max(0, y0)\n"," x1 = min(w_img, x1)\n"," y1 = min(h_img, y1)\n","\n"," # Crop patch from ORIGINAL resized image\n"," patch = orig[y0:y1, x0:x1]\n","\n"," # Ensure patch is the full desired size\n"," if patch.shape[0] != BH or patch.shape[1] != BW:\n"," continue\n","\n"," # Save patch\n"," base_name = os.path.splitext(filename)[0]\n"," # Use global_patch_id for unique sequential naming across ALL files\n"," out_path = os.path.join(out_dir, f\"defect_{base_name}_{global_patch_id:04d}.png\")\n"," cv2.imwrite(out_path, patch)\n","\n"," # Increment the global counter\n"," global_patch_id += 1\n","\n"," print(f\"Processed {filename}: Found {current_defects_count} defects (Total saved: {global_patch_id})\")\n","\n","print(f\"\\n--- Processing Complete ---\")\n","print(f\"Total patches saved to {out_dir}: {global_patch_id}\")"]},{"cell_type":"code","source":["import cv2\n","import matplotlib.pyplot as plt\n","import os\n","import glob # Import the glob library\n","\n","from google.colab import drive\n","drive.mount('/content/drive')\n","\n","# --- CONFIGURATION PARAMETERS ---\n","# Define the size of the patch to save (in pixels)\n","PATCH_SIZE = 64\n","BW, BH = PATCH_SIZE, PATCH_SIZE\n","\n","# Define the paths\n","template_path = '/content/drive/MyDrive/PCB_DATASET/PCB_DATASET/PCB_USED/01.JPG'\n","folder_path = '/content/drive/MyDrive/PCB_DATASET/PCB_DATASET/images/Spur/1'\n","out_dir = \"/content/drive/MyDrive/PCB_DATASET/PCB_DATASET/Spur_1defects\"\n","\n","# Ensure the output directory exists\n","os.makedirs(out_dir, exist_ok=True)\n","\n","# Global counter for saved patches - MUST be initialized outside the loop\n","global_patch_id = 0\n","\n","# Define the area constraints for defect detection\n","MIN_AREA = 1\n","MAX_AREA = 300\n","\n","\n","# Read template PCB 01 image\n","rgb_template_img = cv2.imread(template_path)\n","plt.figure(figsize=(10,6))\n","plt.imshow(rgb_template_img, cmap=\"gray\")\n","\n","# Calculate the resized dimensions (1/4th of original)\n","a = int(rgb_template_img.shape[0]/4)\n","b = int(rgb_template_img.shape[1]/4)\n","\n","# Read template PCB 01 image as grayscale\n","template_img = cv2.imread(template_path, 0)\n","# display the grayscale template PCB image\n","plt.figure(figsize=(10,6))\n","plt.imshow(template_img, cmap=\"gray\")\n","\n","# Resize template image of PCB\n","template_img_resize = cv2.resize(template_img, (b,a))\n","plt.figure(figsize=(10,6))\n","plt.imshow(template_img_resize, cmap=\"gray\")\n","\n","# Gaussian blur\n","blur_template_img = cv2.GaussianBlur(template_img_resize, (3,3),0)\n","# display the blurred image\n","plt.figure(figsize=(10,6))\n","plt.imshow(blur_template_img, cmap=\"gray\")\n","\n","# Adaptive thresholding\n","template_adap_thresh = cv2.adaptiveThreshold(blur_template_img, 255,\n"," cv2.ADAPTIVE_THRESH_MEAN_C,\n"," cv2.THRESH_BINARY, 25, 5)\n","# display the thresholded image\n","plt.figure(figsize=(10,6))\n","plt.imshow(template_adap_thresh, cmap=\"gray\")\n","# Note: Initial display code for template is removed here to keep the final script cleaner,\n","# but it can be re-added before the loop if needed for verification.\n","\n","\n","# Use glob to find all files ending with '.jpg' in the specified folder\n","image_files = glob.glob(os.path.join(folder_path, '*.jpg'))\n","\n","print(f\"Found {len(image_files)} images in the folder.\")\n","print(f\"Defect area filter range: {MIN_AREA} < Area < {MAX_AREA}\")\n","\n","\n","\n","# Iterate over each image file path found\n","for image_path in image_files:\n"," # 1. Read and prepare test image\n"," bgr_test_img = cv2.imread(image_path)\n"," filename = os.path.basename(image_path)\n","\n"," # Check if the image was loaded successfully\n"," if bgr_test_img is None:\n"," print(f\"Skipping file: {filename} (Not a readable image).\")\n"," continue\n","\n"," # Convert BGR to RGB for matplotlib display (if needed)\n"," rgb_test_img = cv2.cvtColor(bgr_test_img, cv2.COLOR_BGR2RGB) # Not used below, but good practice\n"," # 2. Display the original test PCB image\n"," plt.figure(figsize=(10,6))\n"," plt.imshow(rgb_test_img, cmap = \"gray\")\n"," plt.title(f\"Original Test PCB Image: {filename}\")\n","\n"," # Read grayscale\n"," test_img = cv2.imread(image_path, 0)\n","\n"," # Resize, Blur, and Threshold the test image\n"," test_img_resize = cv2.resize(test_img, (b, a))\n"," # 3. Display the grayscale resized test PCB image\n"," plt.figure(figsize=(10,6))\n"," plt.imshow(test_img_resize, cmap=\"gray\")\n"," plt.title(f\"Resized Grayscale PCB Image: {filename} ({b}x{a})\")\n"," blur_test_img = cv2.GaussianBlur(test_img_resize, (3,3),0)\n","\n"," test_adap_thresh = cv2.adaptiveThreshold(blur_test_img, 255,\n"," cv2. ADAPTIVE_THRESH_MEAN_C,\n"," cv2.THRESH_BINARY, 25, 5)\n","\n"," plt.figure(figsize=(10,6))\n"," plt.imshow(test_adap_thresh, cmap=\"gray\")\n","\n"," # 2. Difference Imaging (Core Defect Detection)\n"," sub_img = cv2.subtract(test_adap_thresh, template_adap_thresh)\n"," plt.figure(figsize=(10,6))\n"," plt.imshow(sub_img)\n"," final_img = cv2.medianBlur(sub_img, 3) # Noise reduction\n"," plt.figure(figsize=(10,6))\n"," plt.imshow(final_img, cmap=\"gray\")\n","\n"," # 3. Find Contours\n"," # Using RETR_EXTERNAL focuses on the outline of defect blobs\n"," # Note: final_img is the mask image used for finding contours\n","\n"," orig = test_img_resize\n"," mask_img = final_img\n"," _, thresh = cv2.threshold(mask_img, 127, 255, cv2.THRESH_BINARY)\n"," contours, _ = cv2.findContours(thresh, cv2.RETR_LIST,\n"," cv2.CHAIN_APPROX_SIMPLE) # CHANGE ***\n","\n"," current_defects_count = 0\n"," orig = test_img_resize # The source image for cropping\n"," h_img, w_img = final_img.shape[:2]\n","\n","\n"," # 4. Filter Contours and Save Patches (MUST be inside the image loop)\n"," for cnt in contours:\n"," area = cv2.contourArea(cnt)\n","\n"," # Apply the defect area filter to ensure quality and control quantity\n"," if MIN_AREA < area < MAX_AREA:\n"," current_defects_count += 1\n","\n"," # Get bounding box coordinates\n"," x, y, w, h = cv2.boundingRect(cnt)\n","\n"," # Center of defect\n"," cx = x + w // 2\n"," cy = y + h // 2\n","\n"," # Fixed PATCh_SIZE x PATCh_SIZE box centered on defect\n"," x0 = cx - BW // 2\n"," y0 = cy - BH // 2\n"," x1 = x0 + BW\n"," y1 = y0 + BH\n","\n"," # Clip coordinates to image bounds\n"," x0 = max(0, x0)\n"," y0 = max(0, y0)\n"," x1 = min(w_img, x1)\n"," y1 = min(h_img, y1)\n","\n"," # Crop patch from ORIGINAL resized image\n"," patch = orig[y0:y1, x0:x1]\n","\n"," # Ensure patch is the full desired size\n"," if patch.shape[0] != BH or patch.shape[1] != BW:\n"," continue\n","\n"," # Save patch\n"," base_name = os.path.splitext(filename)[0]\n"," # Use global_patch_id for unique sequential naming across ALL files\n"," out_path = os.path.join(out_dir, f\"defect_{base_name}_{global_patch_id:04d}.png\")\n"," cv2.imwrite(out_path, patch)\n","\n"," # Increment the global counter\n"," global_patch_id += 1\n","\n"," print(f\"Processed {filename}: Found {current_defects_count} defects (Total saved: {global_patch_id})\")\n","\n","print(f\"\\n--- Processing Complete ---\")\n","print(f\"Total patches saved to {out_dir}: {global_patch_id}\")"],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":1000,"output_embedded_package_id":"1BMivZVQlj5yg6Cy3MGt5gdQ6LZ3DQbrt"},"id":"HEXIWQHchMbj","executionInfo":{"status":"ok","timestamp":1766762221799,"user_tz":-330,"elapsed":94295,"user":{"displayName":"Aradhya Stuti","userId":"13084479309528900862"}},"outputId":"35f63010-2dca-41cb-dd3d-4cf1a3f421a5"},"execution_count":null,"outputs":[{"output_type":"display_data","data":{"text/plain":"Output hidden; open in https://colab.research.google.com to view."},"metadata":{}}]},{"cell_type":"code","source":["%cd /content/AI_PCB_Defect_Detection_Classification_System\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"cyoahIlbtRON","executionInfo":{"status":"ok","timestamp":1766870923586,"user_tz":-330,"elapsed":21,"user":{"displayName":"Aradhya Stuti","userId":"13084479309528900862"}},"outputId":"6b52c656-5b90-4ca4-94ed-458bd2b70912"},"execution_count":75,"outputs":[{"output_type":"stream","name":"stdout","text":["/content/AI_PCB_Defect_Detection_Classification_System\n"]}]},{"cell_type":"code","source":["!git checkout my-branch\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"mQhHAJJCtt03","executionInfo":{"status":"ok","timestamp":1766870936838,"user_tz":-330,"elapsed":66,"user":{"displayName":"Aradhya Stuti","userId":"13084479309528900862"}},"outputId":"80c9838d-9a11-4236-b639-776e23546ce0"},"execution_count":76,"outputs":[{"output_type":"stream","name":"stdout","text":["Branch 'my-branch' set up to track remote branch 'my-branch' from 'origin'.\n","Switched to a new branch 'my-branch'\n"]}]},{"cell_type":"code","source":["!git branch\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"hnEZhqRttx4C","executionInfo":{"status":"ok","timestamp":1766870953291,"user_tz":-330,"elapsed":132,"user":{"displayName":"Aradhya Stuti","userId":"13084479309528900862"}},"outputId":"d0083afc-6b86-402e-de5e-ba776cf4c7c3"},"execution_count":77,"outputs":[{"output_type":"stream","name":"stdout","text":[" main\u001b[m\n","* \u001b[32mmy-branch\u001b[m\n"]}]},{"cell_type":"code","source":["!ls /content\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"cnfjurj8t0gQ","executionInfo":{"status":"ok","timestamp":1766870963358,"user_tz":-330,"elapsed":64,"user":{"displayName":"Aradhya Stuti","userId":"13084479309528900862"}},"outputId":"9c0f8cb5-49c7-49ba-f2d8-babd7e50a8b6"},"execution_count":78,"outputs":[{"output_type":"stream","name":"stdout","text":["AI_PCB_Defect_Detection_Classification_System\n","drive\n","PCB-DEFECT-DETECTION-AND-CLASSIFICATION\n","sample_data\n"]}]},{"cell_type":"code","source":["!cp /content/drive/MyDrive/Colab Notebooks/Untitled1.ipynb .\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"CAsBzu3It5oP","executionInfo":{"status":"ok","timestamp":1766871012416,"user_tz":-330,"elapsed":71,"user":{"displayName":"Aradhya Stuti","userId":"13084479309528900862"}},"outputId":"6b20a369-5883-4856-aaa2-946bc3cff6ce"},"execution_count":80,"outputs":[{"output_type":"stream","name":"stdout","text":["cp: cannot stat '/content/drive/MyDrive/Colab': No such file or directory\n","cp: cannot stat 'Notebooks/Untitled1.ipynb': No such file or directory\n"]}]}]}
Binary file added images/defect_01_spur_06_0008.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/defect_01_spur_07_0003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/defect_04_missing_hole_02_0022.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/defect_04_missing_hole_02_0023.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.