如何在 360° 视频中找到具有相同颜色的像素的质心?
How to find the centroid of pixels with same color in a 360° video?
设 I 为来自 360° 视频流的 w x h
帧。
设 R 为该帧上的红色矩形。 R小于图片的宽度
要计算这个矩形的质心,我们需要区分两种情况:
- 案例 1,其中 R 在边缘
- 情况 2 R 完全在框架内
如您所见,在情况 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
但它没有按预期工作。问题出在哪里,有没有更快的解决方案?
这是一个基于转换点的解决方案,即当您从红色移动到非红色时,或者以其他方式。要捕获水平中心,我需要以下信息:
gridSize.x
: space 矩形可以放置的宽度。
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 设置为相应的位置。
由于我是在同一范围内计算边界框,所以我分两步进行。
我首先累积感兴趣像素的坐标。然后,当我检查重叠边界框时,我为图像右半部分的每个重叠颜色减去 with。所以我最终得到了一个完整但滑动的矩形。
最后我除以每种颜色找到的点数。如果结果为负,我将其移动图像宽度的大小。
或者:
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
设 I 为来自 360° 视频流的 w x h
帧。
设 R 为该帧上的红色矩形。 R小于图片的宽度
要计算这个矩形的质心,我们需要区分两种情况:
- 案例 1,其中 R 在边缘
- 情况 2 R 完全在框架内
如您所见,在情况 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
但它没有按预期工作。问题出在哪里,有没有更快的解决方案?
这是一个基于转换点的解决方案,即当您从红色移动到非红色时,或者以其他方式。要捕获水平中心,我需要以下信息:
gridSize.x
: space 矩形可以放置的宽度。
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 设置为相应的位置。
由于我是在同一范围内计算边界框,所以我分两步进行。 我首先累积感兴趣像素的坐标。然后,当我检查重叠边界框时,我为图像右半部分的每个重叠颜色减去 with。所以我最终得到了一个完整但滑动的矩形。
最后我除以每种颜色找到的点数。如果结果为负,我将其移动图像宽度的大小。
或者:
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