如何在 OpenCV 中使用 OpenPose 获取单个 body 部分的大小?
How to get the size of individual body parts using OpenPose in OpenCV?
我正在开发虚拟着装平台。我想从图像中获取一个人的尺寸。我已经实现了 OpenPose 并且能够获得一个人的骨架但是我不知道如何获得单个 body 部分的测量值?
下面是使用OpenPose、OpenCV获取Skeleton的代码
get_skeleton_op.py
import cv2
import time
import numpy as np
protoFile = "pose/coco/pose_deploy_linevec.prototxt"
weightsFile = "pose/coco/pose_iter_440000.caffemodel"
nPoints = 18
POSE_PAIRS = [[1, 0], [1, 2], [1, 5], [2, 3], [3, 4], [5, 6], [6, 7],
[1, 8], [8, 9], [9, 10], [1, 11], [11, 12], [12, 13],
[0, 14], [0, 15], [14, 16], [15, 17]]
frame = cv2.imread("./fatguy.jpg")
frameCopy = np.copy(frame)
frameWidth = frame.shape[1]
frameHeight = frame.shape[0]
threshold = 0.1
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
t = time.time()
# input image dimensions for the network
inWidth = 368
inHeight = 368
inpBlob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight),
(0, 0, 0), swapRB=False, crop=False)
net.setInput(inpBlob)
output = net.forward()
print(output)
print("time taken by network : {:.3f}".format(time.time() - t))
H = output.shape[2]
W = output.shape[3]
# Empty list to store the detected keypoints
points = []
for i in range(nPoints):
# confidence map of corresponding body's part.
probMap = output[0, i, :, :]
# Find global maxima of the probMap.
minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)
# Scale the point to fit on the original image
x = (frameWidth * point[0]) / W
y = (frameHeight * point[1]) / H
if prob > threshold:
cv2.circle(frameCopy, (int(x), int(y)), 8, (0, 255, 255),
thickness=-1,
lineType=cv2.FILLED)
cv2.putText(frameCopy, "{}".format(i), (int(x), int(y)),
cv2.FONT_HERSHEY_SIMPLEX,
1, (0, 0, 255), 2,
lineType=cv2.LINE_AA)
# Add the point to the list if the probability
# is greater than the threshold
points.append((int(x), int(y)))
else:
points.append(None)
# Draw Skeleton
for pair in POSE_PAIRS:
partA = pair[0]
partB = pair[1]
if points[partA] and points[partB]:
cv2.line(frame, points[partA], points[partB], (0, 255, 255), 2)
cv2.circle(frame, points[partA], 8, (0, 0, 255),
thickness=-1,
lineType=cv2.FILLED)
# cv2.imshow('Output-Keypoints', frameCopy)
cv2.imshow('Output-Skeleton', frame)
cv2.imwrite('Output-Keypoints.jpg', frameCopy)
cv2.imwrite('Output-Skeleton.jpg', frame)
print("Total time taken : {:.3f}".format(time.time() - t))
cv2.waitKey(0)
谁能告诉我如何前进?
其实你的问题不简单。
一般来说,您会有多种选择,我将只向您描述抽象步骤,您如何实现这一点。有些方法的工作量更大,有些则不太精确。到目前为止,我已成功使用变体 A。
变体 A)
设置:
你使用 1x 相机,你的人直接在平面 2D 表面前面。您的相机与 2d 表面(背景)的距离和角度应始终相同。我们必须假设人是平的,并使用针孔相机的概念。您可以进行以下处理步骤
处理中:
步骤 A1) 通过打印的 2D 图案(棋盘或其他..)做一个 camera calibration
重要的是你的图案在你的背景上总是尽可能平坦。在背景的不同点上生成多个图像,并尝试覆盖完整的可见区域 space。
使用 camera_calibration 的 opencv 示例进行姿势估计(估计到相机的位置和距离)和镜头校正
link to code example。
您应该事先编辑配置 xml 文件,定义您使用的图案以及您使用的平方尺寸(以毫米或厘米为单位)。
StepA2) 拍摄人物照片,进行镜头校正
StepA3) 通过Open-Pose-Framework
计算“body-points”
StepA4) 使用 inverse homography 将你的点从“像素 space” 投影到“真实世界” space 使用你的 camera-calibration 步骤中的数据A1)
现在以 mm / 或 cm 为单位计算欧氏距离(在校准 xml 文件中定义)。
此步骤假设我们将点投影到 100% 的平面二维表面上,因为我们的 z-dimension 在这里设置为零,否则计算要复杂得多,但也可以这样做。
我添加了一个small code example to my github account as example
变体 B:
在你的图片中使用一个易于检测的已知几何形状的“对象”,它决定了某种比较器的大小。您还必须知道一些相机参数,例如焦距。我找到了一个 good step-by-step tutorial here,其中还包括一些数学背景。
变体 C:
设置:
使用 2 个或更多相机和 3D 重建。这可能会导致更高的准确性。而且这个人现在可以站在你相机领域的任何地方。
步骤:
StepC1) 看校准好walk-troughhere
StepC2) 使用3D重建进行距离计算。 这是
详细的想法和一些代码
变体 D:
使用 3D 扫描仪或 Kinect-System(a paper which shows the kinect way way
)
我正在开发虚拟着装平台。我想从图像中获取一个人的尺寸。我已经实现了 OpenPose 并且能够获得一个人的骨架但是我不知道如何获得单个 body 部分的测量值?
下面是使用OpenPose、OpenCV获取Skeleton的代码
get_skeleton_op.py
import cv2
import time
import numpy as np
protoFile = "pose/coco/pose_deploy_linevec.prototxt"
weightsFile = "pose/coco/pose_iter_440000.caffemodel"
nPoints = 18
POSE_PAIRS = [[1, 0], [1, 2], [1, 5], [2, 3], [3, 4], [5, 6], [6, 7],
[1, 8], [8, 9], [9, 10], [1, 11], [11, 12], [12, 13],
[0, 14], [0, 15], [14, 16], [15, 17]]
frame = cv2.imread("./fatguy.jpg")
frameCopy = np.copy(frame)
frameWidth = frame.shape[1]
frameHeight = frame.shape[0]
threshold = 0.1
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
t = time.time()
# input image dimensions for the network
inWidth = 368
inHeight = 368
inpBlob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight),
(0, 0, 0), swapRB=False, crop=False)
net.setInput(inpBlob)
output = net.forward()
print(output)
print("time taken by network : {:.3f}".format(time.time() - t))
H = output.shape[2]
W = output.shape[3]
# Empty list to store the detected keypoints
points = []
for i in range(nPoints):
# confidence map of corresponding body's part.
probMap = output[0, i, :, :]
# Find global maxima of the probMap.
minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)
# Scale the point to fit on the original image
x = (frameWidth * point[0]) / W
y = (frameHeight * point[1]) / H
if prob > threshold:
cv2.circle(frameCopy, (int(x), int(y)), 8, (0, 255, 255),
thickness=-1,
lineType=cv2.FILLED)
cv2.putText(frameCopy, "{}".format(i), (int(x), int(y)),
cv2.FONT_HERSHEY_SIMPLEX,
1, (0, 0, 255), 2,
lineType=cv2.LINE_AA)
# Add the point to the list if the probability
# is greater than the threshold
points.append((int(x), int(y)))
else:
points.append(None)
# Draw Skeleton
for pair in POSE_PAIRS:
partA = pair[0]
partB = pair[1]
if points[partA] and points[partB]:
cv2.line(frame, points[partA], points[partB], (0, 255, 255), 2)
cv2.circle(frame, points[partA], 8, (0, 0, 255),
thickness=-1,
lineType=cv2.FILLED)
# cv2.imshow('Output-Keypoints', frameCopy)
cv2.imshow('Output-Skeleton', frame)
cv2.imwrite('Output-Keypoints.jpg', frameCopy)
cv2.imwrite('Output-Skeleton.jpg', frame)
print("Total time taken : {:.3f}".format(time.time() - t))
cv2.waitKey(0)
谁能告诉我如何前进?
其实你的问题不简单。
一般来说,您会有多种选择,我将只向您描述抽象步骤,您如何实现这一点。有些方法的工作量更大,有些则不太精确。到目前为止,我已成功使用变体 A。
变体 A)
设置:
你使用 1x 相机,你的人直接在平面 2D 表面前面。您的相机与 2d 表面(背景)的距离和角度应始终相同。我们必须假设人是平的,并使用针孔相机的概念。您可以进行以下处理步骤
处理中:
步骤 A1) 通过打印的 2D 图案(棋盘或其他..)做一个 camera calibration 重要的是你的图案在你的背景上总是尽可能平坦。在背景的不同点上生成多个图像,并尝试覆盖完整的可见区域 space。 使用 camera_calibration 的 opencv 示例进行姿势估计(估计到相机的位置和距离)和镜头校正 link to code example。 您应该事先编辑配置 xml 文件,定义您使用的图案以及您使用的平方尺寸(以毫米或厘米为单位)。
StepA2) 拍摄人物照片,进行镜头校正
StepA3) 通过Open-Pose-Framework
计算“body-points”StepA4) 使用 inverse homography 将你的点从“像素 space” 投影到“真实世界” space 使用你的 camera-calibration 步骤中的数据A1) 现在以 mm / 或 cm 为单位计算欧氏距离(在校准 xml 文件中定义)。 此步骤假设我们将点投影到 100% 的平面二维表面上,因为我们的 z-dimension 在这里设置为零,否则计算要复杂得多,但也可以这样做。 我添加了一个small code example to my github account as example
变体 B:
在你的图片中使用一个易于检测的已知几何形状的“对象”,它决定了某种比较器的大小。您还必须知道一些相机参数,例如焦距。我找到了一个 good step-by-step tutorial here,其中还包括一些数学背景。
变体 C:
设置:
使用 2 个或更多相机和 3D 重建。这可能会导致更高的准确性。而且这个人现在可以站在你相机领域的任何地方。
步骤:
StepC1) 看校准好walk-troughhere
StepC2) 使用3D重建进行距离计算。 这是 详细的想法和一些代码
变体 D:
使用 3D 扫描仪或 Kinect-System(a paper which shows the kinect way way )