如何在 OpenCV 中使用 OpenPose 获取各个身体部位的尺寸?

Sah*_*hil 2 python opencv openpose

我正在开发一个虚拟着装平台。我想从图像中获取一个人的尺寸。我已经实现了 OpenPose 并且能够获得一个人的骨骼,但是我不知道如何获得各个身体部位的测量值?

这是使用 OpenPose、OpenCV 获取 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) 
Run Code Online (Sandbox Code Playgroud)

这是输出

谁能告诉我如何前进?

t2s*_*lve 7

事实上,你的问题并不简单。

\n

一般来说,您将有多种选择来做到这一点,我将仅向您描述抽象步骤,以及如何实现这一目标。有些方法工作量较大,有些则不太精确。到目前为止我成功地使用了变体A。

\n

变体 A)

\n

设置:

\n

您使用 1x 相机,并且您的人位于平坦的 2D 表面的正前方。您的相机与二维表面(背景)应始终保持相同的固定距离和角度。我们必须假设人是平的并使用针孔相机概念。您可以执行以下处理步骤

\n

加工:

\n

步骤 A1) 通过打印的 2D 图案(棋盘或其他图案)进行相机校准\n重要的是您的图案在背景上始终尽可能平坦。在背景的不同点上生成多个图像,并尝试覆盖完整的可见空间。\n使用camera_calibration的opencv示例进行姿势估计(估计到相机的位置和距离)和镜头校正\n链接到代码示例 \您应该事先编辑配置 xml 文件,定义您使用的图案以及您使用的正方形尺寸(以毫米或厘米为单位)。

\n

StepA2) 给自己拍一张照片,进行镜头校正

\n

StepA3) 通过 Open-Pose-Framework 计算“身体点”

\n

步骤A4)使用逆单应性将点从\xe2\x80\x9c像素空间\xe2\x80\x9d投影到“真实世界”空间,使用步骤A1中的相机校准数据)\n现在计算欧几里得距离mm / 或 cm(在校准 xml 文件中定义)。\n此步骤假设我们将点投影在 100% 平坦的 2D 表面上,因为我们的 z 维度在这里设置为零,否则计算要复杂得多,但可能也可以这样做。\n我在我的 github 帐户中添加了一个小代码示例作为示例

\n

变体B:

\n

使用易于检测图片中已知几何图形的 \xe2\x80\x9cobject\xe2\x80\x9d 来确定某种比较器的大小。您还必须了解一些相机参数,例如焦距。我在这里找到了一个很好的分步教程,其中还包括一些数学背景。

\n

变体C:

\n

设置:

\n

使用 2 个或更多相机和 3D 重建。这可能会带来更高的准确性。而且这个人现在可以站在你的相机视野中的任何地方。

\n

脚步:

\n

步骤C1)在此处查看良好的校准步骤

\n

StepC2) 使用3D重建进行距离计算。这是\n详细的想法和一些代码

\n

变体D:

\n

使用 3D 扫描仪或 Kinect 系统(一篇展示 kinect 方式的论文\n)

\n