vuforia 之 Target space 和 screen space 之間的轉換方法

最近在研究 【高通 AR 】技術,通過其Examples來學習相關SDK。

在研究 ImageTagets 的時候,想獲取:

1、目標空間對應的3D point 對應的 屏幕上2D point ; 

2、屏幕上觸碰一點 對應的 空間座標。

雖然其開發文檔https://developer.vuforia.com/resources/dev-guide/screen-coordinates 對這2個需求進行了實現方式闡述,但是都不是很具體。所以花了不少時間去實現(尤其是需求1)。現將 空間座標 轉換成 屏幕座標的方法總結如下:


Target space to screen space

//xq
- (CGPoint)getScreenPointByPose:(QCAR::Matrix34F)pose
{
    // need to account for the orientation on view size
    CGFloat viewWidth = self.frame.size.height; // Portrait
    CGFloat viewHeight = self.frame.size.width; // Portrait
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if (UIInterfaceOrientationIsLandscape(orientation))
    {
        viewWidth = self.frame.size.width;
        viewHeight = self.frame.size.height;
    }
    
    // calculate any mismatch of screen to video size
    QCAR::CameraDevice& cameraDevice = QCAR::CameraDevice::getInstance();
    const QCAR::CameraCalibration& cameraCalibration = cameraDevice.getCameraCalibration();
    QCAR::VideoMode videoMode = cameraDevice.getVideoMode(QCAR::CameraDevice::MODE_DEFAULT);
    
    CGFloat scale = viewWidth/videoMode.mWidth;
    if (videoMode.mHeight * scale < viewHeight)
        scale = viewHeight/videoMode.mHeight;
    CGFloat scaledWidth = videoMode.mWidth * scale;
    CGFloat scaledHeight = videoMode.mHeight * scale;
    
    CGPoint margin = {(scaledWidth - viewWidth)/2, (scaledHeight - viewHeight)/2};
    CGPoint center =[self projectCoord:CGPointMake(0,0) inView:cameraCalibration andPose:pose withOffset:margin andScale:scale];
    NSLog(@"center = %@",[NSValue valueWithCGPoint:center]);
    
    CGPoint centerNew = center;
    centerNew.x = viewHeight - center.y;
    centerNew.y = center.x;
    NSLog(@"centerNew = %@",[NSValue valueWithCGPoint:centerNew]);
   
    return  centerNew;
    
}

- (CGPoint) projectCoord:(CGPoint)coord inView:(const QCAR::CameraCalibration&)cameraCalibration andPose:(QCAR::Matrix34F)pose withOffset:(CGPoint)offset andScale:(CGFloat)scale
{
    CGPoint converted;
    
    QCAR::Vec3F vec(coord.x,coord.y,0);
    QCAR::Vec2F sc = QCAR::Tool::projectPoint(cameraCalibration, pose, vec);
    converted.x = sc.data[0]*scale - offset.x;
    converted.y = sc.data[1]*scale - offset.y;
    
    return converted;
}

其中:方法一中傳入參數 pose  - (void)renderFrameQCAR 方法獲取,即被跟蹤到目標的 3*4姿態矩陣。(詳見https://developer.vuforia.com/resources/dev-guide/pose-matrix-explained,返回值 centerNew 即爲 屏幕上對應的座標。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章