Необходимо сегментировать каждое число на изображении отдельно.

Вопрос или проблема

Я создал модель CNN, используя набор данных MNIST. Я хочу делать предсказания для последовательности чисел, присутствующих на изображениях. Техника включает в себя сегментацию каждого изображения и подачу его в модель, но я сталкиваюсь с трудностями при сегментации чисел из изображений, потому что присутствует два разных типа изображений. Мне нужна надежная техника, которая удаляет все шумы и тени, присутствующие на изображениях, и сегментирует каждое число отдельно. Я также делюсь изображениями здесь. Я ищу надежную технику и код.

введите описание изображения здесь

введите описание изображения здесь

Я пытался использовать этот код и технику, но они не работают для прикрепленных изображений

def segment_and_display_digits(image_path):# Считывание изображенияimg = cv2.imread(image_path)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Получение размеров изображения
height, width = gray.shape
total_area = height * width

# Применение адаптивного порогового значения
thresh = cv2.adaptiveThreshold(
    gray,
    255,
    cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
    cv2.THRESH_BINARY_INV,
    21,  # Размер блока
    10   # Константа C
)

# Поиск контуров
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Фильтрация контуров на основе площади
valid_contours = []
min_area = total_area * 0.001  # Минимум 0.1% от площади изображения
max_area = total_area * 0.5    # Максимум 50% от площади изображения

for cnt in contours:
    area = cv2.contourArea(cnt)
    if min_area < area < max_area:
        x, y, w, h = cv2.boundingRect(cnt)
        aspect_ratio = w / float(h)
        # Проверка, является ли соотношение сторон разумным для цифры (не слишком широкое и не слишком высокое)
        if 0.2 < aspect_ratio < 2:
            valid_contours.append(cnt)

# Сортировка контуров слева направо
valid_contours = sorted(valid_contours, key=lambda x: cv2.boundingRect(x)[0])

# Извлечение и отображение цифр
digits = []
padding = int(min(height, width) * 0.02)  # Адаптивный отступ в зависимости от размера изображения

for cnt in valid_contours:
    x, y, w, h = cv2.boundingRect(cnt)
    # Добавление отступа, сохраняя его в пределах границ изображения
    x1 = max(0, x - padding)
    y1 = max(0, y - padding)
    x2 = min(width, x + w + padding)
    y2 = min(height, y + h + padding)
    digit = img[y1:y2, x1:x2]
    digits.append(digit)

# Отображение результатов
if digits:
    # Создание визуализации оригинального изображения с обнаруженными цифрами
    img_with_boxes = img.copy()
    for cnt in valid_contours:
        x, y, w, h = cv2.boundingRect(cnt)
        cv2.rectangle(img_with_boxes, (x, y), (x+w, y+h), (0, 255, 0), 2)
    
    # Построение оригинального изображения с рамками и сегментированными цифрами
    plt.figure(figsize=(15, 5))
    
    # Оригинальное изображение с рамками
    plt.subplot(2, 1, 1)
    plt.imshow(cv2.cvtColor(img_with_boxes, cv2.COLOR_BGR2RGB))
    plt.title('Обнаруженные цифры')
    plt.axis('off')
    
    # Сегментированные цифры
    plt.subplot(2, 1, 2)
    for i, digit in enumerate(digits):
        plt.subplot(2, len(digits), len(digits) + i + 1)
        plt.imshow(cv2.cvtColor(digit, cv2.COLOR_BGR2RGB))
        plt.axis('off')
        plt.title(f'Цифра {i+1}')
    
    plt.tight_layout()
    plt.show()
else:
    print("Цифры не найдены на изображении")

Ответ или решение

Эффективная сегментация чисел на изображениях: подробный подход

Для успешной сегментации отдельных цифр из изображений, представленных вами, необходимо учитывать наличие шума и теней, которые могут усложнять процесс. Правильная обработка изображений с использованием методов компьютерного зрения может значительно улучшить результаты. Давайте рассмотрим пошаговый процесс сегментации, используя OpenCV и подходы к предобработке изображений, которые помогут вам решить возникшие трудности.

Шаг 1: Предобработка изображения

Перед началом сегментации важно удалить шум и улучшить контраст изображения. Для этого можно использовать несколько методов:

  1. Преобразование в оттенки серого: Преобразуйте цветное изображение в оттенки серого для упрощения обработки.
  2. Устранение шума: Примените фильтр Гаусса для сглаживания изображения и уменьшения шума.
import cv2
import numpy as np

image = cv2.imread('path_to_image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
smoothed = cv2.GaussianBlur(gray, (5, 5), 0)

Шаг 2: Бинаризация с адаптивным порогом

Использование адаптивного порога поможет выделить цифры на фоне. Данный метод эффективен для изображений с неоднородным освещением.

thresh = cv2.adaptiveThreshold(smoothed, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)

Шаг 3: Поиск контуров и фильтрация

Последний этап – это поиск контуров и их отбор. Примените подходящую фильтрацию, чтобы отобрать контуры, соответствующие цифрам:

contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Настройка параметров для фильтрации контуров
valid_contours = []
for cnt in contours:
    area = cv2.contourArea(cnt)
    if 100 < area < 5000:  # Настройте область в зависимости от размеров ваших цифр
        valid_contours.append(cnt)

Шаг 4: Сегментация и отображение цифр

Теперь, когда у нас есть допустимые контуры, мы можем выделить каждую цифру и визуализировать результаты:

digits = []
for cnt in sorted(valid_contours, key=lambda c: cv2.boundingRect(c)[0]):
    x, y, w, h = cv2.boundingRect(cnt)
    digit = image[y:y+h, x:x+w]  # Извлечение цифры по границам контура
    digits.append(digit)

# Визуализация результатов
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 5))
for i, digit in enumerate(digits):
    plt.subplot(1, len(digits), i + 1)
    plt.imshow(cv2.cvtColor(digit, cv2.COLOR_BGR2RGB))
    plt.axis('off')
plt.show()

Заключение

Приведенные выше шаги должны помочь вам в сегментации отдельных цифр из ваших изображений с учетом шума и теней. Обратите внимание на настройки параметров фильтрации и область контуров, так как они могут потребовать подбора в зависимости от качества ваших изображений.

Если у вас возникнут дополнительные вопросы или трудности на каком-либо этапе, не стесняйтесь задавать их! Успехов в вашей работе с CNN и MNIST!

Оцените материал
Добавить комментарий

Капча загружается...