Как найти все плитки прямоугольной формы на изображении? - PullRequest
2 голосов
/ 27 сентября 2019

Я хочу обнаружить и изолировать (получить подизображения) все плитки Rummikub в изображении.Это изображение плиток Rummikub:

Image of rummikub tiles

Я попытался найти контуры плиток на окантованном изображении.Однако мне не удалось найти все контуры всех плиток.

Это то, что я получил до сих пор:

import matplotlib.pyplot as plt
from skimage.color import rgb2gray
import cv2
import imutils
from imutils import contours

# Load image
img = cv2.imread('RK1.jpg',3)

# Converting the image to grayscale.
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Smoothing without removing edges.
gray_filtered = cv2.bilateralFilter(gray, 6, 400, 400)

# Applying the canny filter
edges_filtered = cv2.Canny(gray_filtered, 50, 30)

# find contours in the edged image
contours= cv2.findContours(edges_filtered, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = imutils.grab_contours(contours)

# loop over our contours
for contour in contours:
    # approximate the contour
    peri = cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, 0.015 * peri, True)

    # if our approximated contour has four points, then draw contour
    if len(approx) == 4:
        cv2.drawContours(img, [approx], -1, (0, 255, 0), 3)

Это результат:

Результат обнаружения прямоугольника

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

1 Ответ

1 голос
/ 27 сентября 2019

Вот простой метод

  • Преобразование изображения в оттенки серого и размытие по Гауссу
  • Адаптивный порог
  • Расширение для формирования одиночных контуров
  • Поиск контурови выполнить фильтрацию с использованием соотношения сторон и площади контура
  • Извлечение ROI с использованием Numpy срезов и сохранение ROI

Обнаруженные объекты

enter image description here

Вот каждый отдельно сохраненный ROI

enter image description here

Код

import cv2

image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,9,3)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
dilate = cv2.dilate(thresh, kernel, iterations=1)

cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

ROI_number = 0
for c in cnts:
    area = cv2.contourArea(c)
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.05 * peri, True)
    if len(approx) == 4 and area > 1000:
        x,y,w,h = cv2.boundingRect(approx)
        ROI = image[y:y+h, x:x+w]
        cv2.imwrite('ROI_{}.png'.format(ROI_number), ROI)
        ROI_number += 1

cv2.imshow('thresh', thresh)
cv2.imshow('dilate', dilate)
cv2.waitKey()
...