Как применить 3D-модель к обнаруженному лицу с помощью Apple Vision NO AR

С камерой iPhoneX True-Depth можно получить 3D-координаты любого объекта и использовать эту информацию для позиционирования и масштабирования объекта, но со старыми iPhone у нас нет доступа к AR на передней камере, что я сделал до сих пор обнаруживал лицо с помощью рамки Apple Vison и рисовал 2D-контуры вокруг лица или ориентиров. Я создал SceneView и применил его в качестве переднего слоя Моего представления с чистым фоном, а под ним - AVCaptureVideoPreviewLayer, после обнаружения лица мой 3D-объект появляется на экране но для правильного позиционирования и масштабирования в соответствии с ограничивающим блоком лица потребовалось спроецирование и другие вещи, которые я там застрял, я также пытался преобразовать 2D BoundingBox в 3D с помощью CATransform3D, но мне это не удалось! Мне интересно, возможно ли то, чего я хочу достичь? Я помню, что SnapChat делал это до того, как ARKit был доступен на iPhone, если я не ошибаюсь!

Imgur

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(self.sceneView)

        self.sceneView.frame = self.view.bounds
        self.sceneView.backgroundColor = .clear
        self.node = self.scene.rootNode.childNode(withName: "face", 
        recursively: true)!

    }

    fileprivate func updateFaceView(for result: 
    VNFaceObservation, twoDFace: Face2D) {
        let box = convert(rect: result.boundingBox)
        defer {
            DispatchQueue.main.async {
                self.faceView.setNeedsDisplay()
            }
        }

        faceView.boundingBox = box
        self.sceneView.scene?.rootNode.addChildNode(self.node)

        let unprojectedBox = SCNVector3(box.origin.x, box.origin.y, 
        0.8)

        let worldPoint = sceneView.unprojectPoint(unprojectedBox)

         self.node.position = worldPoint 
        /* Here i have to to unprojecting 
         to convert the value from a 2D point to 3D point also 
         issue here. */
    }

person Shahriyar    schedule 23.05.2019    source источник


Ответы (2)


Единственный способ добиться этого - использовать SceneKit с ортографической камерой и использовать SCNGeometrySource, чтобы сопоставить ориентиры из Vision с вершинами меша. Во-первых, вам нужна сетка с таким же количеством вершин Vision (66–77 в зависимости от того, в какой версии Vision вы находитесь). Вы можете создать его, используя такой инструмент, как Blender.

Сетка в Blender

Затем в коде каждый раз, когда вы обрабатываете свои ориентиры, вы выполняете следующие шаги: 1- Получите вершины меша:

func getVertices() -> [SCNVector3]{
        var result = [SCNVector3]()
        let planeSources = shape!.geometry?.sources(for: SCNGeometrySource.Semantic.vertex)
        if let planeSource = planeSources?.first {
            let stride = planeSource.dataStride
            let offset = planeSource.dataOffset
            let componentsPerVector = planeSource.componentsPerVector
            let bytesPerVector = componentsPerVector * planeSource.bytesPerComponent
            let vectors = [SCNVector3](repeating: SCNVector3Zero, count: planeSource.vectorCount)
            //   [SCNVector3](count: planeSource.vectorCount, repeatedValue: SCNVector3Zero)
            let vertices = vectors.enumerated().map({
                (index: Int, element: SCNVector3) -> SCNVector3 in
                var vectorData = [Float](repeating: 0, count: componentsPerVector)
                let byteRange = NSMakeRange(index * stride + offset, bytesPerVector)

                let data = planeSource.data
                (data as NSData).getBytes(&vectorData, range: byteRange)
                return SCNVector3( x: vectorData[0], y: vectorData[1], z: vectorData[2])
            })

            result = vertices

        }

        return result
    }

2- Отмените проецирование каждого ориентира, захваченного Vision, и сохраните их в массиве SCNVector3:

let unprojectedLandmark = sceneView.unprojectPoint( SCNVector3(landmarks[i].x + (landmarks[i].x,landmarks[i].y,0))

3- Измените геометрию, используя новые вершины:

func reshapeGeometry (_ vertices: [SCNVector3]) {

let source = SCNGeometrySource(vertices: vertices)

var newSources = [SCNGeometrySource]()
newSources.append(source)

for source in shape!.geometry!.sources {
    if (source.semantic != SCNGeometrySource.Semantic.vertex) {
        newSources.append(source)
    }
}

let geometry = SCNGeometry(sources: newSources, elements: shape!.geometry?.elements)

let material = shape!.geometry?.firstMaterial
shape!.geometry = geometry
shape!.geometry?.firstMaterial = material

}

Я смог это сделать, и это был мой метод. Надеюсь это поможет!

person Diego Meire    schedule 05.12.2019
comment
Не могли бы вы поделиться более полной реализацией этого? Это кажется очень многообещающим, но не объясняет, как когда-либо использовались getVertices() или unprojectedLandmark. - person ZbadhabitZ; 15.02.2020

Я бы посоветовал взглянуть на продукты Google AR Core, которые поддерживают сцену Apple AR с задней или передней камерой ... но добавляют некоторые дополнительные функции помимо Apple, когда дело доходит до устройств с камерой глубины без Face.

Apple Core Vision почти аналогична структуре Googles Core Vision, которая возвращает 2D-точки, представляющие глаза / рот / нос и т. Д., И компонент наклона лица.

Однако, если вам нужен способ просто применить либо 2D-текстуры к отзывчивому 3D-лицу, либо, в качестве альтернативы, прикрепить 3D-модели к точкам на лице, взгляните на структуру Google Core Augmented Faces. У него отличный пример кода для iOS и Android.

person Jules Burt    schedule 30.10.2019
comment
comment
ARCore SDK великолепен, но ограничен по сравнению с Vision (например, похоже, что он не поддерживает обнаружение / отслеживание нескольких лиц и использует меньшее количество вершин, чем текущая версия Vision). Тем не менее, это отличный способ реализовать такую ​​технологию без чрезмерной сложности. - person ZbadhabitZ; 14.02.2020
comment
Конечно, но фреймворк Apple Vision не позволяет осуществлять реальное трехмерное отслеживание головы, а просто двухмерное отслеживание маркеров на лице. ARKIt от Apple будет выполнять реальное трехмерное отслеживание головы, но доступно только на устройствах iPhone10 и новее. - person Jules Burt; 19.02.2020