Log in or register to post comments

Frame Marker getting the size of the marker

April 25, 2016 - 2:39am #1

Hello!

 

I am using the FrameMarkers sample for Android to develop my application. I would like to overlay data over the Marker that is detected. I managed to get the center of the marker using the method I found on these forums:

public Vec2F cameraPointToScreenPoint(Vec2F cameraPoint) {
        VideoMode videoMode = CameraDevice.getInstance ().getVideoMode(CameraDevice.MODE.MODE_DEFAULT);
        VideoBackgroundConfig config = Renderer.getInstance ().getVideoBackgroundConfig();

        WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();

        int screenWidth = display.getWidth();  // deprecated
        int screenHeight = display.getHeight();  // deprecated

        int xOffset = ((int) screenWidth - config.getSize().getData()[0]) / 2 + config.getPosition().getData()[0];
        int yOffset = ((int) screenHeight - config.getSize().getData()[1]) / 2 - config.getPosition().getData()[1];

        //if (isActivityInPortraitMode) {
        if(mActivity.getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
            // camera image is rotated 90 degrees
            int rotatedX = videoMode.getHeight() - (int)cameraPoint.getData()[1];
            int rotatedY = (int)cameraPoint.getData()[0];

            return new Vec2F(rotatedX * config.getSize().getData()[0] / (float) videoMode.getHeight() + xOffset,
                    rotatedY * config.getSize().getData()[1] / (float) videoMode.getWidth() + yOffset);
        } else {
            return new Vec2F(cameraPoint.getData()[0] * config.getSize().getData()[0] / (float) videoMode.getWidth() + xOffset,
                    cameraPoint.getData()[1] * config.getSize().getData()[1] / (float) videoMode.getHeight() + yOffset);
        }
    }

I use this method with the next code snippet:

 

Vec2F getMarkerCenter(TrackableResult trackableResult){
        CameraCalibration calib = CameraDevice.getInstance().getCameraCalibration();
        Vec2F cameraPoint = Tool.projectPoint(calib, trackableResult.getPose(), new Vec3F(0,0,0));
        return cameraPointToScreenPoint(cameraPoint);
    }

 

Overlaying the data with this position works and overlays text starting from the center of the marker. However I want to start overlaying the text from the upper left corner of the marker. I tried using the method Trackable.getSize(), but it always returns (50, 50) as the size and that is obviously not the current marker ize on the screen. How do I get the actual size of the marker on the current frame? 

Frame Marker getting the size of the marker

October 17, 2017 - 9:59am #5

Hello PSPiroz,

You can get the coordinates of an Image Target by accessing the Transform of the Image Target game object.

Thanks,

-Vuforia Support

Frame Marker getting the size of the marker

October 17, 2017 - 8:47am #4

Has anybody any idea how to do all the above stuff (either get the coordinates of the frame of augmentation / image target on video feedback, or its center point) in Unity ?

Frame Marker getting the size of the marker

April 26, 2016 - 7:04am #3

Thank you, I figured it out in the meantime. My markers are the standard A4 marker so 50 should be good. If anyone is interested here is the code that I used to get the screen coordinates of the edges of the marker:

 

Vec2F getMarkerCenter(TrackableResult trackableResult){
        CameraCalibration calib = CameraDevice.getInstance().getCameraCalibration();
        Vec2F cameraPoint = Tool.projectPoint(calib, trackableResult.getPose(), new Vec3F(0,0,0));
        return cameraPointToScreenPoint(cameraPoint);
    }

    Vec2F getMarkerUpperLeftCorner(TrackableResult trackableResult){
        final Marker marker = (Marker) trackableResult.getTrackable();
        CameraCalibration calib = CameraDevice.getInstance().getCameraCalibration();
        Vec2F cameraPoint = Tool.projectPoint(calib, trackableResult.getPose(),
                new Vec3F(- (marker.getSize().getData()[0] / 2.0f),marker.getSize().getData()[1] / 2.0f, 0));
        return cameraPointToScreenPoint(cameraPoint);
    }

    Vec2F getMarkerLowerLeftCorner(TrackableResult trackableResult){
        final Marker marker = (Marker) trackableResult.getTrackable();
        CameraCalibration calib = CameraDevice.getInstance().getCameraCalibration();
        Vec2F cameraPoint = Tool.projectPoint(calib, trackableResult.getPose(),
                new Vec3F(- (marker.getSize().getData()[0] / 2.0f),- (marker.getSize().getData()[1] / 2.0f), 0));
        return cameraPointToScreenPoint(cameraPoint);
    }

    Vec2F getMarkerUpperRightCorner(TrackableResult trackableResult){
        final Marker marker = (Marker) trackableResult.getTrackable();
        CameraCalibration calib = CameraDevice.getInstance().getCameraCalibration();
        Vec2F cameraPoint = Tool.projectPoint(calib, trackableResult.getPose(),
                new Vec3F(marker.getSize().getData()[0] / 2.0f,marker.getSize().getData()[1] / 2.0f, 0));
        return cameraPointToScreenPoint(cameraPoint);
    }

    Vec2F getMarkerLowerRightCorner(TrackableResult trackableResult){
        final Marker marker = (Marker) trackableResult.getTrackable();
        CameraCalibration calib = CameraDevice.getInstance().getCameraCalibration();
        Vec2F cameraPoint = Tool.projectPoint(calib, trackableResult.getPose(),
                new Vec3F(marker.getSize().getData()[0] / 2.0f,- (marker.getSize().getData()[1] / 2.0f), 0));
        return cameraPointToScreenPoint(cameraPoint);
    }

    Vec2F getMarkerSize(TrackableResult result){
        Vec2F markerUpperLeftCorner = getMarkerUpperLeftCorner(result);
        Vec2F markerUpperRightCorner = getMarkerUpperRightCorner(result);
        Vec2F markerLowerRightCorner = getMarkerLowerRightCorner(result);
        return new Vec2F(distanceVec2F(markerUpperLeftCorner, markerUpperRightCorner),
                distanceVec2F(markerUpperRightCorner, markerLowerRightCorner));
    }

    float getMarkerAngle(TrackableResult result){
        Vec2F markerLowerLeftCorner = getMarkerLowerLeftCorner(result);
        Vec2F markerLowerRightCorner = getMarkerLowerRightCorner(result);
        return angleVec2FinDegrees(markerLowerLeftCorner, markerLowerRightCorner);
    }

    float distanceVec2F(Vec2F a, Vec2F b){
        float xa = a.getData()[0];
        float ya = a.getData()[1];
        float xb = b.getData()[0];
        float yb = b.getData()[1];
        return (float)Math.hypot(xa - xb, ya - yb);
    }

    float angleVec2FinDegrees(Vec2F a, Vec2F b) {
        float xa = a.getData()[0];
        float ya = a.getData()[1];
        float xb = b.getData()[0];
        float yb = b.getData()[1];
        float dy = yb - ya;
        float dx = xb - xa;
        float theta = (float)Math.atan2(dy, dx); // range (-PI, PI]
        theta *= 180 / Math.PI; // rads to degs, range (-180, 180]
        //if (theta < 0) theta = 360 + theta; // range [0, 360)
        return theta;
    }

 

I also added a code function which calculates the marker angle on the screen and its current screen size.

Frame Marker getting the size of the marker

April 26, 2016 - 6:57am #2

The size of a Frame Marker can be specified programmatically when you create the Marker; if the GetSize method returns a size of (50,50), this means the Marker was created with that size;

you should first establish what will be the expected size of your Markers when printed, and then use that value (according to your unit of choice, e.g. meters, inches, millimeters, ...) and enter that value in the Marker creation.

This will then give you the correct size, based on which you can compute the 3D point corresponding to each corner of the marker and pass that argument to the Tool.projectPoint() method .

See also:

https://developer.vuforia.com/library/articles/Solution/How-To-Create-Frame-Markers-at-Runtime

 

Log in or register to post comments