Определение формы с помощью opencv / python - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь научить мою инфраструктуру автоматизации тестирования обнаруживать выбранный элемент в приложении, используя opencv (платформа берет кадры / снимки экрана с тестируемого устройства).Выбранные элементы всегда имеют определенный размер и всегда имеют синюю рамку, которая помогает, но они содержат разные миниатюрные изображения.См. Приведенный пример изображения.

Я много гуглил и читал по этой теме, и я близок к тому, чтобы заставить его работать, ожидаю для одного сценария, который является изображением C на изображении примера. пример изображения Здесь на выбранном элементе есть символ воспроизведения.

Моя теория заключается в том, что OpenCV в этом случае запутывается, потому что символ воспроизведения в основном представляет собой круг с треугольником в нем иЯ прошу его найти прямоугольную форму.

Я нашел это очень полезным: https://www.learnopencv.com/blob-detection-using-opencv-python-c/

Мой код выглядит так:

import cv2
import numpy as np

img = "testimg.png"

values = {"min threshold": {"large": 10, "small": 1},
          "max threshold": {"large": 200, "small": 800},
          "min area": {"large": 75000, "small": 100},
          "max area": {"large": 80000, "small": 1000},
          "min circularity": {"large": 0.7, "small": 0.60},
          "max circularity": {"large": 0.82, "small": 63},
          "min convexity": {"large": 0.87, "small": 0.87},
          "min inertia ratio": {"large": 0.01, "small": 0.01}}
size = "large"

# Read image
im = cv2.imread(img, cv2.IMREAD_GRAYSCALE)

# Setup SimpleBlobDetector parameters.
params = cv2.SimpleBlobDetector_Params()

# Change thresholds
params.minThreshold = values["min threshold"][size]
params.maxThreshold = values["max threshold"][size]

# Filter by Area.
params.filterByArea = True
params.minArea = values["min area"][size]
params.maxArea = values["max area"][size]

# Filter by Circularity
params.filterByCircularity = True
params.minCircularity = values["min circularity"][size]
params.maxCircularity = values["max circularity"][size]


# Filter by Convexity
params.filterByConvexity = False
params.minConvexity = values["min convexity"][size]

# Filter by Inertia
params.filterByInertia = False
params.minInertiaRatio = values["min inertia ratio"][size]

# Create a detector with the parameters
detector = cv2.SimpleBlobDetector(params)

# Detect blobs.
keypoints = detector.detect(im)

for k in keypoints:
    print k.pt
    print k.size

# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures
# the size of the circle corresponds to the size of blob   
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0, 0, 255),
                                      cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

# Show blobs
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)

Какя могу заставить OpenCV смотреть только на внешнюю форму, определяемую синей рамкой, и игнорировать внутренние формы (символ воспроизведения и, конечно, миниатюрное изображение)?Я уверен, что это как-то выполнимо.

Ответы [ 3 ]

0 голосов
/ 22 сентября 2018

Если я правильно понял, вам нужен прямоугольник, ограничивающий синюю коробку изогнутыми краями.Если это так, то это очень просто.Примените это -

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
edged = cv2.Canny(gray, 75, 200) # You'll have to tune these

# Find contours

(_, contour, _) = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 
# This should return only one contour in 'contour' in your case

Это должно сделать, но если вы все еще получаете контур (ограничивающий прямоугольник) с изогнутыми краями, примените это -

rect = cv2.approxPolyDP(contour, 0.02 * cv2.arcLength(contour, True), True) 
# Play with the second parameter, appropriate range would be from 1% to 5%
0 голосов
/ 24 сентября 2018

Я немного поигрался с этим после того, как прочитал ваши предложения и обнаружил, что обнаружение BLOB-объектов - не лучший способ.Использование распознавания цвета для нахождения контуров решило проблему, как было предложено выше.Еще раз спасибо!

Мое решение выглядит так:

frame = cv2.imread("image.png")
color = ((200, 145, 0), (255, 200, 50))
lower_color = numpy.array(color[0], dtype="uint8")
upper_color = numpy.array(color[1], dtype="uint8")

# Look for the color in the frame and identify contours
color = cv2.GaussianBlur(cv2.inRange(frame, lower_color, upper_color), (3, 3), 0)
contours, _ = cv2.findContours(color.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

if contours:

    for c in contours:
        rectangle = numpy.int32(cv2.cv.BoxPoints(cv2.minAreaRect(c)))

        # Draw a rectangular frame around the detected object
        cv2.drawContours(frame, [rectangle], -1, (0, 0, 255), 4)

    cv2.imshow("frame", frame)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
0 голосов
/ 22 сентября 2018

Есть много разных техник, которые сделают эту работу.Я не совсем уверен, как работает BlobDetector, поэтому я выбрал другой подход.Также я не совсем уверен, что вам нужно, но вы можете изменить это решение для своих нужд.

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

img_name = "CbclA.png" #Image you have provided

min_color = 150 #Color you are interested in (from green channel)
max_color = 170

min_size = 4000 #Size of border you are interested in (number of pixels)
max_size = 30000


img_rgb = cv2.imread(img_name)
img = img_rgb[:,:,1] #Extract green channel
img_filtered = np.bitwise_and(img>min_color, img < max_color) #Get only colors of your border


nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(img_filtered.astype(np.uint8))

good_area_index = np.where(np.logical_and(stats[:,4] > min_size,stats[:,4] < max_size)) #Filter only areas we are interested in

for area in stats[good_area_index] : #Draw it
    cv2.rectangle(img_rgb, (area[0],area[1]), (area[0] + area[2],area[1] + area[3]), (0,0,255), 2)

cv2.imwrite('result.png',img_rgb)

Ознакомьтесь с документацией connectedComponentsWithStats

Примечание:Я использую Python 3

result - red rectangles around detected areas

Редактировать: добавлено изображение результата

...