Как исправить этот код Python для подсчета повторяющихся образцов в изображениях?Python

Программы на Python
Anonymous
Как исправить этот код Python для подсчета повторяющихся образцов в изображениях?

Сообщение Anonymous »

Я хочу посчитать образцы на изображении и измерить длину каждого образца, как показано ниже. Но я столкнулся с большой проблемой: когда выборка перекрывается, она не может произвести точный подсчет, например, количество выборок на самом деле должно быть 2, но оно перекрывается, поэтому результат становится равным 4. Что мне делать? Или может кто-нибудь исправить мой код?
Вот мой код:

Код: Выделить всё

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")
мой результат
Изображение

Исходное изображение
Изображение


Подробнее здесь: https://stackoverflow.com/questions/797 ... the-images

Вернуться в «Python»