Log in or register to post comments

Error projecting point on the screen.

June 15, 2011 - 7:57am #12

Hi,

I'm trying to project marker coordinates and to export them to java. I think there's something on camera calibration and pose matrix I don't understand.

When i try to project the frame vertices of the marker with this code, there's always a variable offset: it seems like I'm not using correct camera calibration, perhaps.

Only when the device is normal to the frame i get the marker correctly framed.

const QCAR::Tracker& tracker = QCAR::Tracker::getInstance();
        const QCAR::CameraCalibration& cameraCalibration = tracker.getCameraCalibration();
QCAR::Vec2F mrkrsize = marker->getSize();
        float mposx = mrkrsize.data[0];
        float mposy= mrkrsize.data[1];
        QCAR::Vec2F screenPoint1 = QCAR::Tool::projectPoint(cameraCalibration, trackable->getPose(), QCAR::Vec3F(0, +mposy/2, 0));
        QCAR::Vec2F screenPoint2 = QCAR::Tool::projectPoint(cameraCalibration, trackable->getPose(), QCAR::Vec3F(0, -mposy/2, 0));
        QCAR::Vec2F screenPoint3 = QCAR::Tool::projectPoint(cameraCalibration, trackable->getPose(), QCAR::Vec3F(mposx, posy/2, 0));
        QCAR::Vec2F screenPoint4 = QCAR::Tool::projectPoint(cameraCalibration, trackable->getPose(), QCAR::Vec3F(mposx, -mposy/2, 0));

Re: Error projecting point on the screen.

June 16, 2011 - 12:32pm #11

It looks like the projectPoint method doesn't work as advertised. It projects a point to camera space, not screen space. You should have all the information you need to take this point from camera to screen space, however. Here's a method that should work for landscape mode, let us know if you need help adapting it to portrait.

QCAR::Vec2F cameraPointToScreenPoint(QCAR::Vec2F cameraPoint)
{
    QCAR::VideoMode videoMode = QCAR::CameraDevice::getInstance().getVideoMode(QCAR::CameraDevice::MODE_DEFAULT);
    QCAR::VideoBackgroundConfig config = QCAR::Renderer::getInstance().getVideoBackgroundConfig();
    
    int xOffset = ((int) screenWidth - config.mSize.data[0]) / 2.0f + config.mPosition.data[0];
    int yOffset = ((int) screenHeight - config.mSize.data[1]) / 2.0f - config.mPosition.data[1];
    
    return QCAR::Vec2F(cameraPoint.data[0] * config.mSize.data[0] / (float) videoMode.mWidth + xOffset,
                       cameraPoint.data[1] * config.mSize.data[1] / (float) videoMode.mHeight + yOffset);
}

- Kim

Re: Error projecting point on the screen.

June 17, 2011 - 7:58am #10

Thank you, it works.

Re: Error projecting point on the screen.

November 22, 2011 - 1:49am #9
ksiva wrote:

...Here's a method that should work for landscape mode, let us know if you need help adapting it to portrait...
- Kim

I am interested in the portrait mode version, ty :)

Re: Error projecting point on the screen.

November 28, 2011 - 9:17pm #8

Sorry for the delay, here's a version that works in either orientation:

QCAR::Vec2F cameraPointToScreenPoint(QCAR::Vec2F cameraPoint)
{
    QCAR::VideoMode videoMode = QCAR::CameraDevice::getInstance().getVideoMode(QCAR::CameraDevice::MODE_DEFAULT);
    QCAR::VideoBackgroundConfig config = QCAR::Renderer::getInstance().getVideoBackgroundConfig();
    
    int xOffset = ((int) screenWidth - config.mSize.data[0]) / 2.0f + config.mPosition.data[0];
    int yOffset = ((int) screenHeight - config.mSize.data[1]) / 2.0f - config.mPosition.data[1];
    
    if (isActivityInPortraitMode)
    {
        // camera image is rotated 90 degrees
        int rotatedX = videoMode.mHeight - cameraPoint.data[1];
        int rotatedY = cameraPoint.data[0];
        
        return QCAR::Vec2F(rotatedX * config.mSize.data[0] / (float) videoMode.mHeight + xOffset,
                           rotatedY * config.mSize.data[1] / (float) videoMode.mWidth + yOffset);
    }
    else
    {
        return QCAR::Vec2F(cameraPoint.data[0] * config.mSize.data[0] / (float) videoMode.mWidth + xOffset,
                           cameraPoint.data[1] * config.mSize.data[1] / (float) videoMode.mHeight + yOffset);
    }
}

- Kim

Error projecting point on the screen.

September 19, 2012 - 4:31pm #7

Hi,

I'm using this code to get the center point of the trackable and I'm having trouble with the landscape mode.

It's always moved a little to the bottom left :-(

I'm testing this on an iPad 2 BTW

Error projecting point on the screen.

September 19, 2012 - 5:44pm #6

To get the center point of the trackable in screen space?

Error projecting point on the screen.

September 19, 2012 - 5:57pm #5

Exactly

UPDATE: Actually I was looking for the AR overlay frame but the tracker would work too :-)

Error projecting point on the screen.

September 19, 2012 - 6:59pm #4

Here's another approach you can try that's specific to iOS.

- (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;
}

- (void) calcScreenCoordsOf:(CGSize)target inView:(CGFloat *)matrix inPose:(QCAR::Matrix34F)pose
{
// 0,0 is at centre of target so extremities are at w/2,h/2
CGFloat w = target.width/2;
CGFloat h = target.height/2;

// 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};

// now project the 4 corners of the target
ImageTargetsAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
delegate.s0 = [self projectCoord:CGPointMake(-w,h) inView:cameraCalibration andPose:pose withOffset:margin andScale:scale];
delegate.s1 = [self projectCoord:CGPointMake(-w,-h) inView:cameraCalibration andPose:pose withOffset:margin andScale:scale];
delegate.s2 = [self projectCoord:CGPointMake(w,-h) inView:cameraCalibration andPose:pose withOffset:margin andScale:scale];
delegate.s3 = [self projectCoord:CGPointMake(w,h) inView:cameraCalibration andPose:pose withOffset:margin andScale:scale];
}

Error projecting point on the screen.

September 20, 2012 - 5:49am #3

Thank you, that's great.

What should I put in inView:(CGFloat *)matrix parameter?

Error projecting point on the screen.

April 10, 2013 - 7:36am #2

Hi,

I am working on the project, where is need to display some overlay image at certain point of trackable image, like "attaching" i.e. when trackable changes position overlay image also should change position accordingly.

I used the code mentioned below. I recieve projected point, but it can have negative x or y value.  How should I match this value to screen?

Thanks

Error projecting point on the screen.

October 2, 2013 - 6:41am #1

Hi, I'm also working on it. First , forgive my pool English. I want to get the 4 corners of the image target with the funcation calcScreenCoordsOf and projectCoord, but the 4 coordinate I get is rotated 90 degrees counterclockwise when I display them on the screen. Could anyone give me some advice?

Log in or register to post comments