|
| 1 | +import cv2 |
| 2 | +import os |
| 3 | +import numpy as np |
| 4 | +# Input and output folders |
| 5 | +input_folder = "input" |
| 6 | +output_folder = "output" |
| 7 | + |
| 8 | +# Ensure the output folder exists |
| 9 | +if not os.path.exists(output_folder): |
| 10 | + os.makedirs(output_folder) |
| 11 | + |
| 12 | +# Function to process an image |
| 13 | +def process_image(filename): |
| 14 | + # Read the image |
| 15 | + img = cv2.imread(filename) |
| 16 | + |
| 17 | + # Convert the image to grayscale |
| 18 | + gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) |
| 19 | + |
| 20 | + # Invert the image to make black figures on a white background |
| 21 | + inverted = cv2.bitwise_not(gray) |
| 22 | + |
| 23 | + # Apply thresholding to segment the black figures (adjust threshold value as needed) |
| 24 | + _, thresh = cv2.threshold(inverted, 128, 255, cv2.THRESH_BINARY) |
| 25 | + |
| 26 | + # Find contours in the binary image |
| 27 | + contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) |
| 28 | + |
| 29 | + # Draw the calculations for each black figure on the image |
| 30 | + img_processed = img.copy() |
| 31 | + for contour in contours: |
| 32 | + # Calculate the minimum enclosing circle |
| 33 | + (x, y), radius = cv2.minEnclosingCircle(contour) |
| 34 | + center = (int(x), int(y)) |
| 35 | + radius = int(radius) |
| 36 | + |
| 37 | + # Calculate the surface area |
| 38 | + area = cv2.contourArea(contour) |
| 39 | + |
| 40 | + # Calculate the major axis as the longest distance between any two points |
| 41 | + #points = contour.squeeze() |
| 42 | + #distances = [((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)**0.5 for p1 in points for p2 in points] |
| 43 | + #major_axis = max(distances) |
| 44 | + # Calculate the major axis points |
| 45 | + points = contour.squeeze() |
| 46 | + max_distance = 0 |
| 47 | + major_axis_points = None |
| 48 | + for i, p1 in enumerate(points): |
| 49 | + for p2 in points[i + 1:]: |
| 50 | + distance = np.linalg.norm(p1 - p2) |
| 51 | + if distance > max_distance: |
| 52 | + max_distance = distance |
| 53 | + major_axis_points = p1, p2 |
| 54 | + |
| 55 | + # Draw a line representing the major axis |
| 56 | + if major_axis_points is not None: |
| 57 | + p1, p2 = major_axis_points |
| 58 | + cv2.line(img_processed, tuple(p1), tuple(p2), (0, 0, 255), 2) # Red line |
| 59 | + # Calculate the perimeter of the contour |
| 60 | + perimeter = cv2.arcLength(contour, closed=True) |
| 61 | + |
| 62 | + # Calculate the centroid of the contour |
| 63 | + M = cv2.moments(contour) |
| 64 | + cx = int(M['m10'] / M['m00']) |
| 65 | + cy = int(M['m01'] / M['m00']) |
| 66 | + centroid = (cx, cy) |
| 67 | + |
| 68 | + # Draw the minimum enclosing circle |
| 69 | + cv2.circle(img_processed, center, radius, (0, 0, 255), 2) # Red circle |
| 70 | + # Draw a marker at the centroid |
| 71 | + cv2.circle(img_processed, centroid, 5, (0, 0, 255), -1) # Red circle |
| 72 | + |
| 73 | + |
| 74 | + # Display the calculations as text |
| 75 | + cv2.putText(img_processed, f"Total surface area: {area:.2f}", (cx - 40, cy - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) |
| 76 | + cv2.putText(img_processed, f"Total Perimeter: {perimeter:.2f}", (cx - 60, cy + 40), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) |
| 77 | + cv2.putText(img_processed, f"Centroid: ({cx},{cy})", (cx - 40, cy + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) |
| 78 | + cv2.putText(img_processed, f"Major Axis Length: {max_distance:.2f}", (cx - 60, cy + 60),cv2.FONT_HERSHEY_SIMPLEX, 0.5,(0, 0, 255), 2) |
| 79 | + |
| 80 | + # Save the processed image with calculations |
| 81 | + output_filename = os.path.join(output_folder, os.path.basename(filename)) |
| 82 | + cv2.imwrite(output_filename, img_processed) |
| 83 | + |
| 84 | +# Process each image in the input folder |
| 85 | +for filename in os.listdir(input_folder): |
| 86 | + if filename.endswith((".jpg", ".png")): |
| 87 | + input_image_path = os.path.join(input_folder, filename) |
| 88 | + process_image(input_image_path) |
| 89 | + |
| 90 | +print("Processing complete.") |
0 commit comments