【ARToolkit】How to make a logo card patt

First of all, let me tell you, why our camera can recognize the identification card and show the virtual objects we need on the identification card?

The principle is this, in fact, there are a total of steps. Step 1: First, we use the knowledge of OpenGL to draw a virtual object, and the code used to draw this virtual object should be placed in OpenGL to implement. Step 2 : Make a new template, that is, make a logo card of your own. To create a new template, first print a blank template (first image below). It's just a black square with an empty white square in the middle. Then create a black and white or color image of the desired template that fits the square in the center and print it out. A good template should be one that is asymmetrical and doesn't have very fine details. Figure 2 shows a sample template. Glue the finished new template in the black square 


                   

Step 3: This is the step we will focus on. First we need to name the new template. We will explain to you the simpletest in the previous article as an example.

In the example of simpletest mentioned in the previous article, we need to put

char *patt_name = "Data/patt.hiro"; the code is changed to char *patt_name = "Data/yourpatt.hiro";

Among them, the only difference between the two lines of code is patt and yourpatt, which is the identification card that identifies the simpletest and the identification card we will make. Of course, you can also replace yourpatt with another English name.

I will paste the code for making the identification card below

#if defined(__sgi)
char            *vconf = "-size=FULL";
#elif defined(__linux)
#  if defined(AR_INPUT_GSTREAMER)
char *vconf = "videotestsrc";
#  elif defined(AR_INPUT_V4L)
char            *vconf = "-width=640 -height=480";
#  elif defined(AR_INPUT_1394CAM)
char            *vconf = "-mode=640x480_YUV411";
#  elif defined(AR_INPUT_DV)
char            *vconf = "";
#  endif
#elif defined(_WIN32)
char *vconf = "Data\\WDM_camera_flipV.xml";
#elif defined(__APPLE__)
char *vconf = "-width=640 -height=480";
#else
char *vconf = "";
#endif


// Image acquisition.
static ARUint8 *gARTImage = NULL;
static ARUint8 *gARTsaveImage = NULL;


// Marker detection.
static int gARTThreshhold = 100;
static ARMarkerInfo* gTarget  = NULL;




// Drawing.
static ARParam gARTCparam;
static ARGL_CONTEXT_SETTINGS_REF gArglSettings = NULL;


void lineSeg(double x1, double y1, double x2, double y2, ARGL_CONTEXT_SETTINGS_REF contextSettings, ARParam cparam, double zoom)
{
int enable;
    float   ox, oy;
    double  xx1, yy1, xx2, yy2;if (!contextSettings) return;arglDistortionCompensationGet(contextSettings, &enable);



    if (arglDrawModeGet(contextSettings) == AR_DRAW_BY_TEXTURE_MAPPING && enable) {
        xx1 = x1;  yy1 = y1;
        xx2 = x2;  yy2 = y2;
    } else {
        arParamIdeal2Observ(cparam.dist_factor, x1, y1, &xx1, &yy1);
        arParamIdeal2Observ(cparam.dist_factor, x2, y2, &xx2, &yy2);
    }    xx1 *= zoom; yy1 *= zoom;    xx2 *= zoom; yy2 *= zoom;ox = 0;oy = cparam.ysize - 1;glBegin(GL_LINES);glVertex2f(ox + xx1, oy - yy1);glVertex2f(ox + xx2, oy - yy2);glEnd();    glFlush();}static int setupCamera(ARParam *cparam){    ARParam  wparam;    char     name1[256], name2[256];


















int xsize, ysize;


    printf("Enter camera parameter filename");
    printf("(Data/camera_para.dat): ");
    if (fgets(name1, 256, stdin) == NULL) exit(0);
    if (sscanf(name1, "%s", name2) != 1) {
        strcpy(name2, "Data/camera_para.dat");
    }


// Load the camera parameters.
if (arParamLoad(name2, 1, &wparam) < 0 ) {
        printf("Parameter load error !!\n");
        return (FALSE);
    }    // Open the video path.    if (arVideoOpen(vconf) < 0) {fprintf(stderr, "setupCamera(): Unable to open connection to camera.\n");return (FALSE);}    // Find the size of the window.



   
   



    if (arVideoInqSize(&xsize, &ysize) < 0) return (FALSE);
    fprintf(stdout, "Camera image size (x,y) = (%d,%d)\n", xsize, ysize);// Resize for the window and init.    arParamChangeSize(&wparam, xsize, ysize, cparam);    fprintf(stdout, "*** Camera Parameter ***\n");    arParamDisp(cparam);    arInitCparam(cparam);if (arVideoCapStart() != 0) {fprintf(stderr, "setupCamera(): Unable to begin camera data capture.\n");return (FALSE);}return (TRUE);}static void Quit(void){free(gARTsaveImage); gARTsaveImage = NULL;arglCleanup(gArglSettings);arVideoCapStop();arVideoClose();exit(0);}









   

















static void Keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 0x1B: // Quit.
case 'Q':
case 'q':
Quit();
break;
case 'T':
case 't':
printf("Enter new threshold value (default = 100): ");
scanf("%d", &gARTThreshhold); while (getchar()!='\n');
printf("\n");
break;
case '?':
case '/':
printf("Keys:\n");
printf(" q or [esc]    Quit demo.\n");
printf(" t             Enter new binarization threshold value.\n");
printf(" ? or /        Show this help.\n");
printf("\nAdditionally,the ARVideo library supplied the following help text:\n");
arVideoDispOption();
break;
default:
break;
    }
}


static void Mouse(int button, int state, int x, int y)
{
    char   name1[256], name2[256];if (state == GLUT_DOWN) {if (button == GLUT_RIGHT_BUTTON) {Quit();} else if (button == GLUT_MIDDLE_BUTTON) {printf("Enter new threshold value (default = 100): ");scanf("%d", &gARTThreshhold); while (getchar() != '\n');printf("\n");} else if (button == GLUT_LEFT_BUTTON && gARTsaveImage && gTarget) {printf("Enter filename: ");if (fgets(name1, 256, stdin) == NULL) return;if (sscanf(name1, "%s", name2) != 1 ) return;if (arSavePatt(gARTsaveImage, gTarget, name2) < 0) {













printf("ERROR!!\n");
} else {
printf("  Saved\n");
}
}
}
}


static void Idle(void)
{
static int ms_prev;
int ms;
float s_elapsed;
ARUint8 *image;
    int             areamax;
ARMarkerInfo    *marker_info; // Pointer to array holding the details of detected markers.
    int             marker_num; // Count of number of markers detected.
    int             i;// Find out how long since Idle() last ran.ms = glutGet(GLUT_ELAPSED_TIME);s_elapsed = (float)(ms - ms_prev) * 0.001;if (s_elapsed < 0.01f) return; // Don't update more often than 100 Hz.ms_prev = ms;







// Grab a video frame.
if ((image = arVideoGetImage()) != NULL) {
gARTImage = image;if (arDetectMarker(gARTImage, gARTThreshhold, &marker_info, &marker_num) < 0) {Quit();}areamax = 0;gTarget = NULL;for (i = 0; i < marker_num; i++) {if (marker_info[i].area > areamax) {areamax = marker_info[i].area;gTarget = &(marker_info[i]);}}memcpy(gARTsaveImage, gARTImage,  gARTCparam.xsize * gARTCparam.ysize * AR_PIX_SIZE_DEFAULT);// Tell GLUT the display has changed.glutPostRedisplay();}}////This function is called on events when the visibility of the//























GLUT window changes (including when it first becomes visible).
//
static void Visibility(int visible)
{
if (visible == GLUT_VISIBLE) {
glutIdleFunc(Idle);
} else {
glutIdleFunc(NULL);
}
}


//
// This function is called when the
// GLUT window is resized.
//
static void Reshape(int w, int h)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode(GL_PROJECTION);glLoadIdentity();glMatrixMode(GL_MODELVIEW);glLoadIdentity();// Call through to anyone else who needs to know about window sizing here.







}


static void beginOrtho2D(int xsize, int ysize) {
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, xsize, 0.0, ysize);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();}static void endOrtho2D(void) {glMatrixMode(GL_PROJECTION);glPopMatrix();glMatrixMode(GL_MODELVIEW);glPopMatrix();}//// This function is called when the window needs redrawing.//static void Display(void){// Select correct buffer for this context.glDrawBuffer(GL_BACK);glClear(GL_COLOR_BUFFER_BIT); // Clear the buffers for new frame.




















arglDispImage(gARTImage, &gARTCparam, 1.0, gArglSettings); // zoom = 1.0.
arVideoCapNext();
gARTImage = NULL; // Image data is no longer valid after calling arVideoCapNext().


if (gTarget != NULL) {
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
beginOrtho2D(gARTCparam.xsize, gARTCparam.ysize);
        glLineWidth(2.0f);
        glColor3d(0.0, 1.0, 0.0);
        lineSeg(gTarget->vertex[0][0], gTarget->vertex[0][1],
gTarget->vertex[1][0], gTarget->vertex[1][1], gArglSettings, gARTCparam, 1.0);
        lineSeg(gTarget->vertex[3][0], gTarget->vertex[3][1],
gTarget->vertex[0][0], gTarget->vertex[0][1], gArglSettings, gARTCparam, 1.0);
        glColor3d(1.0, 0.0, 0.0);
        lineSeg(gTarget->vertex[1][0], gTarget->vertex[1][1],
gTarget->vertex[2][0], gTarget->vertex[2][1], gArglSettings, gARTCparam, 1.0);
        lineSeg(gTarget->vertex[2][0], gTarget->vertex[2][1],
gTarget->vertex[3][0], gTarget->vertex[3][1], gArglSettings, gARTCparam, 1.0);
endOrtho2D();
    }


glutSwapBuffers();
}


int main(int argc, char *argv[])
{
// ----------------------------------------------------------------------------
// Library inits.
//glutInit(&argc, argv);// ----------------------------------------------------------------------------// Hardware setup.//







if (!setupCamera(&gARTCparam)) {
fprintf(stderr, "main(): Unable to set up AR camera.\n");
exit(-1);
}// ----------------------------------------------------------------------------// Library setup.//// Set up GL context(s) for OpenGL to draw into.    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);glutInitWindowSize(gARTCparam.xsize, gARTCparam.ysize);glutCreateWindow(argv[0]);// Setup argl library for current context.if ((gArglSettings = arglSetupForCurrentContext()) == NULL) {fprintf(stderr, "main(): arglSetupForCurrentContext() returned error.\n");exit(-1);}
















arMalloc(gARTsaveImage, ARUint8, gARTCparam.xsize * gARTCparam.ysize * AR_PIX_SIZE_DEFAULT);// Register GLUT event-handling callbacks.// NB: Idle() is registered by Visibility.glutDisplayFunc(Display);glutReshapeFunc(Reshape);glutVisibilityFunc(Visibility);glutKeyboardFunc(Keyboard);    glutMouseFunc(Mouse);glutMainLoop();return (0);}













After running the program, the system will prompt you to enter a camera parameter folder name, to enter: Data/camera_para.dat.

Then the virtual image that appears is like this , and the content of the logo card is a new logo made by myself.


as shown in the picture. Once the image is found and oriented correctly, click the left mouse button. You will then be prompted to enter a template file name. For example, enter patt.yourpatt. Once the filename is entered, the system generates a bitmap image of the template, and the bitmap image is copied to the file named after the filename. Next this will be used in ARToolKit's template matching. In order to use this new template, the data must be copied to the file directory bin/Data. After recompiling simpletest, you can now use your own templates. The Data, wrl, and lib folders are the same as the first ARToolkit test program, and must be added to the .c file directory


In the above code, the production of various virtual images and identification cards can be completed as long as the code for drawing the virtual graphics is changed to the code of the virtual image that you want to appear.

Virtual images can produce a variety of images, and logo cards are also available


















Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325616386&siteId=291194637