Wie kann dieser Python-Code korrigiert werden, um doppelte Beispiele in den Bildern zu zählen?Python

Python-Programme
Anonymous
 Wie kann dieser Python-Code korrigiert werden, um doppelte Beispiele in den Bildern zu zählen?

Post by Anonymous »

Ich möchte Proben im Bild zählen und die Länge jeder Probe messen, wie ich unten zeige. Ich stehe jedoch vor dem großen Problem, dass bei überlappenden Stichproben keine genaue Zählung durchgeführt werden kann. Die Stichprobenanzahl sollte beispielsweise eigentlich 2 betragen, sie überlappen sich jedoch, sodass das Ergebnis bei 4 liegt. Was soll ich tun? Oder kann bitte jemand meinen Code reparieren?
Hier ist mein Code:

Code: Select all

import cv2
import numpy as np
import matplotlib.pyplot as plt

# === Load and preprocess image ===
image = cv2.imread('GF sample/4.jpg')  # ⬅️ Load input image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # Convert to grayscale
blur = cv2.GaussianBlur(gray, (11, 11), 0)      # Apply Gaussian blur to reduce noise
canny = cv2.Canny(blur, 10, 150, 3)              # Edge detection using Canny
dilated = cv2.dilate(canny, (1, 1), iterations=0)  # Slightly enhance edges

# === Image dimensions ===
height, width = gray.shape

# === Find external contours ===
cnts, hierarchy = cv2.findContours(
dilated.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# === Calibration (based on your scale)
MICRONS_PER_PIXEL = 1.585  # ⬅️ Adjust based on scale bar (1000 µm = 631 px)

# === Filtering thresholds
MIN_AREA = 1                # Eliminate tiny specks
MIN_WIDTH_HEIGHT = 15       # Filter very small bounding boxes
MARGIN = 5                 # Avoid counting fibers near the image border

# === Output image and result storage
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
font = cv2.FONT_HERSHEY_SIMPLEX
filtered_cnt = []
fiber_lengths_um = []

# === Loop through contours and apply filters
for c in cnts:
area = cv2.contourArea(c)
x, y, w, h = cv2.boundingRect(c)

if (area > MIN_AREA and
w > MIN_WIDTH_HEIGHT and h > MIN_WIDTH_HEIGHT and
x > MARGIN and y > MARGIN and
(x + w) < (width - MARGIN) and
(y + h) < (height - MARGIN)):

# Keep only filtered contours
filtered_cnt.append(c)

# Estimate length using minAreaRect
rect = cv2.minAreaRect(c)
(w_rect, h_rect) = rect[1]
length_px = max(w_rect, h_rect)
real_length_um = length_px * MICRONS_PER_PIXEL
fiber_lengths_um.append(real_length_um)

# === Label and draw only the accepted contours ===
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 0.5
thickness = 1
color = (255, 0, 0)  # red

for i, c in enumerate(filtered_cnt, 1):
M = cv2.moments(c)
if M["m00"] != 0:
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])

# Draw contour
cv2.drawContours(rgb, [c], -1, (0, 255, 0), 1)

# Get label text size
label = str(i)
(text_width, text_height), baseline = cv2.getTextSize(label, font, font_scale, thickness)

# Shift to center
text_x = int(cx - text_width / 2)
text_y = int(cy + text_height / 2)

# Draw label centered
cv2.putText(rgb, label, (text_x, text_y), font, font_scale, color, thickness)

# === Show results ===
plt.figure(figsize=(14, 10))
plt.imshow(rgb)
plt.title(f" Counted Glass Fibers: {len(filtered_cnt)}")
plt.axis('off')
plt.show()

# === Print lengths of fibers ===
print("\n📏 List of Detected Fibers (µm):")
for idx, length in enumerate(fiber_lengths_um, 1):
print(f"{idx}. {length:.2f} µm")

# === Summary statistics ===
print(f"\n📊 Total detected: {len(filtered_cnt)} fibers")
print(f"📉 Min: {min(fiber_lengths_um):.2f} µm")
print(f"📈 Max: {max(fiber_lengths_um):.2f} µm")
print(f"📌 Average: {np.mean(fiber_lengths_um):.2f} µm")
mein Ergebnis
Image

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post