Hackaton项目是一个开源的Swift项目,它展示了如何使用第三方Core ML模型PoseNet来从摄像头捕获的图像帧中检测人体姿态。PoseNet模型能够检测17个不同的身体部位或关节,包括眼睛、耳朵、鼻子、肩膀、臀部、肘部、膝盖、手腕和脚踝。这些关节共同构成了一个人的姿态。
captureSession.beginConfiguration()
captureSession.sessionPreset = .vga640x480
try setCaptureSessionInput()
try setCaptureSessionOutput()
captureSession.commitConfiguration()
guard CVPixelBufferLockBaseAddress(pixelBuffer, .readOnly) == kCVReturnSuccess else {
return
}
var image: CGImage?
VTCreateCGImageFromCVPixelBuffer(pixelBuffer, options: nil, imageOut: &image)
CVPixelBufferUnlockBaseAddress(pixelBuffer, .readOnly)
DispatchQueue.main.sync {
delegate.videoCapture(self, didCaptureFrame: image)
}
let input = PoseNetInput(image: image, size: self.modelInputSize)
guard let prediction = try? self.poseNetMLModel.prediction(from: input) else {
return
}
let poseNetOutput = PoseNetOutput(prediction: prediction, modelInputSize: self.modelInputSize, modelOutputStride: self.outputStride)
DispatchQueue.main.async {
self.delegate?.poseNet(self, didPredict: poseNetOutput)
}
var pose = Pose()
pose.joints.values.forEach { joint in
configure(joint: joint)
}
pose.confidence = pose.joints.values.map { $0.confidence }.reduce(0, +) / Double(Joint.numberOfJoints)
pose.joints.values.forEach { joint in
joint.position = joint.position.applying(modelToInputTransformation)
}
let dstImageSize = CGSize(width: frame.width, height: frame.height)
let dstImageFormat = UIGraphicsImageRendererFormat()
dstImageFormat.scale = 1
let renderer = UIGraphicsImageRenderer(size: dstImageSize, format: dstImageFormat)
let dstImage = renderer.image { rendererContext in
draw(image: frame, in: rendererContext.cgContext)
for pose in poses {
for segment in PoseImageView.jointSegments {
let jointA = pose[segment.jointA]
let jointB = pose[segment.jointB]
guard jointA.isValid, jointB.isValid else {
continue
}
drawLine(from: jointA, to: jointB, in: rendererContext.cgContext)
}
for joint in pose.joints.values.filter({ $0.isValid }) {
draw(circle: joint, in: rendererContext.cgContext)
}
}
}