Обнаружение квадрата в изображении - PullRequest
3 голосов
/ 14 марта 2019

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

image3 image4

Вот код, который я получил, но в нем отсутствуют некоторые квадраты.

def find_squares(img):
    img = cv2.GaussianBlur(img, (5, 5), 0)
    squares = []
    for gray in cv2.split(img):
        for thrs in range(0, 255, 26):
            if thrs == 0:
                bin = cv2.Canny(gray, 0, 50, apertureSize=5)
                bin = cv2.dilate(bin, None)
            else:
                _retval, bin = cv2.threshold(gray, thrs, 255, cv2.THRESH_BINARY)
            bin, contours, _hierarchy = cv2.findContours(bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
            for cnt in contours:
                cnt_len = cv2.arcLength(cnt, True)
                cnt = cv2.approxPolyDP(cnt, 0.02*cnt_len, True)
                if len(cnt) == 4 and cv2.contourArea(cnt) > 1000 and cv2.isContourConvex(cnt):
                    cnt = cnt.reshape(-1, 2)
                    max_cos = np.max([angle_cos( cnt[i], cnt[(i+1) % 4], cnt[(i+2) % 4] ) for i in range(4)])
                    #print(cnt)
                    a = (cnt[1][1] - cnt[0][1])

                    if max_cos < 0.1 and a < img.shape[0]*0.8:

                        squares.append(cnt)
    return squares

dice = cv2.imread('img1.png')
squares = find_squares(dice)
cv2.drawContours(dice, squares, -1, (0, 255, 0), 3)

Вот выходные изображения: Image1Image2

Согласно моему анализу, некоторые квадраты отсутствуют из-заотсутствующие плавные края вдоль костей из-за плавного перехода интенсивности между костью и фоном.

Учитывая ограничение, что в квадратной сетке всегда будет 25 кубиков (5 * 5), можем ли мы предсказать недостающие позиции квадратов на основе распознанных квадратов?Или мы можем изменить алгоритм выше для алгоритма обнаружения квадрата?

Ответы [ 2 ]

3 голосов
/ 25 июля 2019

Вот подход

  • Преобразование изображения в оттенки серого и медианное размытие в сглаженное изображение
  • Резкость изображения для улучшения краев
  • Порог
  • Выполнитьморфологические преобразования
  • Поиск контуров и фильтра с использованием минимальной / максимальной пороговой области
  • Обрезка и сохранение ROI

Резкость изображения с помощью cv2.filter2D().Мы используем универсальное ядро ​​повышения резкости, другие ядра можно найти здесь

enter image description here

Теперь порог для получения двоичного изображения

enter image description here

Выполнение морфологических операций

enter image description here

Отсюда мы находим контуры и фильтруем, используяcv2.contourArea() с минимальными / максимальными пороговыми областями.

enter image description here

Мы можем обрезать каждую нужную квадратную область, используя Numpy, и сохранять каждый ROI следующим образом:

x,y,w,h = cv2.boundingRect(c)
ROI = image[y:y+h, x:x+h]
cv2.imwrite('ROI_{}.png'.format(image_number), ROI)

enter image description here

import cv2
import numpy as np

image = cv2.imread('1.png')

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.medianBlur(gray, 5)
sharpen_kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
sharpen = cv2.filter2D(blur, -1, sharpen_kernel)

thresh = cv2.threshold(sharpen,160,255, cv2.THRESH_BINARY_INV)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)

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

min_area = 100
max_area = 1500
image_number = 0
for c in cnts:
    area = cv2.contourArea(c)
    if area > min_area and area < max_area:
        x,y,w,h = cv2.boundingRect(c)
        ROI = image[y:y+h, x:x+h]
        cv2.imwrite('ROI_{}.png'.format(image_number), ROI)
        cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
        image_number += 1

cv2.imshow('sharpen', sharpen)
cv2.imshow('close', close)
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()
0 голосов
/ 15 марта 2019

Эта дополнительная информация абсолютно золотая. Да, учитывая матрицу костей 5x5, вы можете неплохо распределить позиции. Кости, которые вы можете определить, дают вам центр, размер и ориентацию костей. Просто продолжайте эти шаблоны вдоль обеих осей. Для вашего второго прохода увеличьте контраст в каждой «области интереса», где вы ожидаете найти край douse (никогда не говорите «умри!»). В пределах нескольких пикселей вы знаете, где будут находиться края: просто ослабьте изображение, пока не определите эти края.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...