Как определить контуры, связанные с моими объектами, и найти их геометрический центроид - PullRequest
0 голосов
/ 24 февраля 2019

Постановка проблемы и справочная информация:

РЕДАКТИРОВАТЬ : Ограничения: красный цвет на фланце меняется со временем, поэтому я не пытаюсь использовать цветпризнание, чтобы идентифицировать мой объект в этот момент, если он не может быть надежным.Кроме того, союзник внешнего освещения может быть фактором, так как это будет в наружной области в будущем.

У меня есть камера RGB-Depth, и я могу снимать эту сцену.Где каждый пиксель (x, y) имеет значение глубины.

enter image description here

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

enter image description here

Величинам градиента присваивается значение 0, если они имеют величину, которая не равна нулю.Черный (255) предназначен для значений амплитуд, связанных с 0 (однородная глубина или плоская поверхность).

Из этой карты краев я набрал края, чтобы было проще подобрать контуры.enter image description here

Затем я нашел контуры на изображении и попытался построить только 5 самых больших контуров.

enter image description here

ПРОБЛЕМА

Есть ли способ надежно найти контуры, связанные с моими объектами (красныйкоробка и металлический крепеж) а потом найти их геометрический центроид?Я продолжаю сталкиваться с проблемой, заключающейся в том, что я могу найти контуры на изображении, но у меня нет возможности выборочно проверять контуры, которые являются моими объектами, а не шумом.

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

gray = cv2.imread('GRAYTEST.jpeg', cv2.IMREAD_GRAYSCALE)

, оно выглядит синим, а не двоичнымчерно-белое изображение, как я показываю.Извините за это.

Вот изображение: enter image description here

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

МОЙ КОД

    gray = cv2.imread('GRAYTEST.jpeg', cv2.IMREAD_GRAYSCALE)
    plt.imshow(gray)
    plt.title('gray start image')
    plt.show()

    blurred = cv2.bilateralFilter(gray, 8, 25, 25)  # blurr image while preserving edges
    kernel = np.ones((3, 3), np.uint8)  # define a kernel (block) to apply filters to

    dialated = cv2.dilate(blurred, kernel, iterations=1)
    plt.title('dialated')
    plt.imshow(dialated)
    plt.show()

    #Just performs a canny edge dectection on an image
    edges_empty = self.Commons.CannyE_Auto(dialated)  # Canny edge image for some sigma
    #makes an empty image using the same diemensions of the given image
    empty2 = self.Commons.make_empty(gray)

    _, contours, _ = cv2.findContours(edges_empty, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = sorted(contours, key=cv2.contourArea, reverse=True)[:5]  # get largest five contour area
    cv2.drawContours(empty2, cnts, -1, (255, 0, 0), thickness=1)

    plt.title('contours')
    plt.imshow(empty2)
    plt.show()

1 Ответ

0 голосов
/ 25 февраля 2019
  1. Вместо того, чтобы выполнять размытие, набор номера, обнаружение неровных краев на моем уже пороговом изображении, я просто выполнил определение контура на моем исходном изображении.

  2. Затем я смог найти достойный контур для контура моего изображения, изменив команду findContour.

    _, contours, _ = cv2.findContours (серый, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

замена cv2.RETR_TREE на cv2.RETR_EXTERNAL Мне удалось получить только контуры, которые были связаны с контуром объекта, вместо того, чтобы пытаться получить контуры внутри объекта.Переключение на cv2.CHAIN_APPROX_NONE не показало каких-либо заметных улучшений, но оно может обеспечить лучшие контуры для более сложной геометрии.

        for c in cnts:
        # compute the center of the contour
        M = cv2.moments(c)
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])

        # draw the contour and center of the shape on the image
        cv2.drawContours(empty2, [c], -1, (255, 0, 0), thickness=1)
        perimeter = np.around(cv2.arcLength(c, True), decimals=3)
        area = np.around(cv2.contourArea(c), decimals=3)

        cv2.circle(empty2, (cX, cY), 7, (255, 255, 255), -1)
        cv2.putText(empty2, "center", (cX - 20, cY - 20),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)

        cv2.putText(empty2, "P:{}".format(perimeter), (cX - 50, cY - 50),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)

        cv2.putText(empty2, "A:{}".format(area), (cX - 100, cY - 100),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)

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

enter image description here

Однако я не смог выполнить тест, который бы определил, какой контур был моим желаемым контуром.У меня есть идея захватить мой объект в более идеальной обстановке и найти его центроид, периметр и связанную с ним область.Таким образом, когда я нахожу новый контур, я могу сравнить его с тем, насколько он близок к моим известным значениям.

Я думаю, что этот метод может работать для удаления слишком больших или слишком маленьких контуров.

Если кто-нибудь знает лучшее решение, которое было бы фантастическим!

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