Как найти центроид пикселей одного цвета в видео 360 °?

Пусть я будет кадром w x h из видеопотока 360 °. Пусть р будет красным прямоугольником на этом кадре. р меньше ширины изображения.

Чтобы вычислить центроид этого прямоугольника, нам нужно различать два случая:

  • случай 1, когда р находится на краях
  • случай 2, когда р полностью находится внутри кадра

Как найти центроид пикселей одного цвета в видео 360 °?

Как видите, в случае 1 будет проблема вычислить центроид классическими методами. Обратите внимание, что меня интересует только горизонтальное перекрытие.

На данный момент я так и делаю. Сначала мы определяем первую найденную точку и используем ее в качестве эталона, затем нормализуем dx, который является разницей между точкой и эталоном, а затем накапливаем:

width = frame.width
rectangle_pixel = (255,0,0)
first_found_coord = (-1,-1)
centroid = (0,0)
centroid_count = 0

for pixel, coordinates in image:
  if (pixel != rectangle_pixel): 
    continue
  if (first_found_coord == (-1,-1)):
    first_found_coord = coordinates 
    centroid = coordinates
    continue

  dx = coordinates.x - first_found_coord.x
  if (dx > width/2):
    dx -= width
  else if (dx < - width/2):
    dx -= width

  centroid += (dx, coordinates.y)
  centroid_count++


final_centroid = centroid / centroid_count 

Но это работает не так, как ожидалось. В чем проблема, есть ли более быстрое решение?

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

meowgoesthedog 30.07.2018 12:45

Теоретически это верно, но я никогда не столкнусь с этим случаем в своих сценариях. «(...) Меня волнует только горизонтальное перекрытие».

verygolo 30.07.2018 15:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
101
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вот решение, основанное на точках перехода, то есть при переходе от красного к не-красному или другим способом. Чтобы запечатлеть центр по горизонтали, мне понадобилась следующая информация:

gridSize.x: ширина пространства, в котором могут располагаться прямоугольники. w: ширина вашего прямоугольника.

Псевдокод:

redPixel = (255,0,0);

transitionPoints = [];
betweenTransitionsColor = -1;

// take i and i+1 pixel+position, increment i by one at each step. 
for (pixel1, P1), (pixel1, P2) in gridX : // horizontal points for a fixed `y` 
  if pixel1 != pixel2: // one is red, the other white
     nonRedPosition = (pixel1 != redPixel ? P1 : P2)
     transitionPoints.append(nonRedPosition)
     continue
  if (transitionPoints.length == 1 && betweenTransitionsColor == -1):
     betweenTransitionsColor = pixel2

  if transitionPoints.length == 2:
      break

//Case where your rectangle is on the edge (left or right)
if (transitionPoints.length == 1):
  if (abs(transitionPoints[0].x - w) < 2):
    xCenter = w/2
  else:
    xCenter = gridSize.x - w/2

else:
  [tP1, tP2] = transitionPoints

  // case 1 : The rectangle is splitted
  if betweenTransitionsColor != redPixel:
    xCenter = (tP2.x - gridSize.x + tP1.x)/2
  else:
    xCenter = (tP1.x + tP1.x)/2

Примечание :

вы должны начать с позиции y, где вы можете получить красные пиксели. Достичь этого не должно быть очень сложно. Если ваш rectangle's height больше, чем gridSize.y/2, вы можете начать с gridSize.y/2. В противном случае вы можете найти первый красный пиксель и установить y в соответствующее положение.

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

verygolo 31.07.2018 12:47
Ответ принят как подходящий

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

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


Альтернативно:

def get_centroid(image, interest_color):
    acc_x = 0
    acc_y = 0
    count = 0
    first_pixel = (0,0)

    for (x,y, color) in image:
      if (color not in interest_color):
        continue

      if (count == 0):
        first_pixel = (x,y)

      dx = x - first_pixel.x

      if (dx > L/2)
        dx -= L
      else if (dx < -L/2)
        dx += L

      acc_x += x
      acc_y += y
      count++

    non_scaled_result = acc_x / count, acc_y / count
    result = non_scaled_result + first_pixel

    return result

Другие вопросы по теме