Ищем подход, чтобы вписать прямоугольники в контуры - PullRequest
1 голос
/ 13 апреля 2020

Это более общий вопрос, так как я не знаю, как эффективно решить или решить эту проблему:

  • Я использую OpenCV для получения точек контура движущихся объектов в режиме реального времени (список (x, y) координаты кортежей)
  • Я хочу нарисовать прямоугольники внутри этих точек контура в зависимости от того, есть ли в нем углы

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

enter image description here

Вся идея заключается в том, чтобы заставить его взаимодействовать с некоторыми игровыми объектами (например, мячом) в Pygame позже. Например, передвиньте шарик руками , палкой или любым другим предметом , который движется перед камерой.

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

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

Подходы, о которых я думал до сих пор:

  • Моя первоначальная идея - рассчитать расстояние, а также угол каждой соседней точки контура. Если угол больше некоторой определенной степени, он будет рассматриваться как новый кластер. Тем не менее, это не кажется надежным, так как рука (пальцы) имеют острые края, и я не хочу получать скелет из мелких вещей, но довольно простых крупных фигур, как на картинке выше

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

1 Ответ

1 голос
/ 14 апреля 2020

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

#check if 2 lines are intersecting
#lines are 2 pygame Vector2 
def LineIntersect(line1, line2):
    #the math is from wikipedia
    x1 = line1[0].x
    y1 = line1[0].y
    x2 = line1[1].x
    y2 = line1[1].y

    x3 = line2[0].x
    y3 = line2[0].y
    x4 = line2[1].x
    y4 = line2[1].y

    #denominator 
    den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
    if den == 0:
        return 
    t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den

    u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / den

    if t > 0 and t < 1 and u > 0 and u < 1:
        pt = Vector2()
        pt.x = x1 + t * (x2 - x1)
        pt.y = y1 + t * (y2 - y1)
        return pt
    return

Еще один подход, который вы могли бы сделать с первым, - это упростить фигуру, избавившись от точек на прямой линия. Я сделал тест и получил следующий результат Bunch of circled, где черные точки удаляются, а красная - это упрощенная форма. Не совсем уверен, что делать дальше, так что я думаю, что мой первый подход будет работать лучше? Вот код для этого

def Prepare(Points):
    New_points = [Points[0]]
    last_point = Vector2(Points[0])
    for i in range(1,len(Points)-1,1):
        p = Vector2(Points[i])
        Dir = p - last_point
        if i < len(Points) - 1:
            New_dir = Points[i+1] - p
            New_dir = New_dir.normalize()
            angle = Dir.angle_to(New_dir)
            if abs(angle) > 15:
                New_points.append(Points[i])
        #print(last_point.angle_to(p))
        pygame.draw.circle(screen,(255,0,0),(int(p.x),int(p.y)),5)    
        last_point = p
    New_points.append(Points[-1])
    return New_points

То, что я сделал, получило направление от предыдущей точки к текущей точке и следующей точке, если разница была больше 15 градусов, это был угол, и я добавлено в новые точки

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