AR多标签识别程序1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef __APPLE__
#  ifdef _WIN32
#    include <windows.h>
#  endif
#  include <GL/glut.h>
#else
#  include <GLUT/glut.h>
#endif
#include <AR/ar.h>
#include <AR/gsub.h>
#include <AR/video.h>
#include <AR/arMulti.h>
#include "GLFont.h"
#include "BasicInfo.h"
//#define                 CPARA_NAME       "Data/camera_para.dat"
//#define                 CONFIG_NAME      "Data/multi/marker.dat"

#define CPARA_NAME "E:/MyGitProject/vsProjectCollection/ARDrawWord/ARToolKitTest/Data/camera_para.dat"
#define CONFIG_NAME "E:/MyGitProject/vsProjectCollection/ARDrawWord/ARToolKitTest/Data/testM/barcode.dat" //marker.dat"

ARHandle               *arHandle;
AR3DHandle             *ar3DHandle;
ARGViewportHandle      *vp;
ARMultiMarkerInfoT     *config;
int                     robustFlag = 0;
int                     count;
ARParamLT              *gCparamLT1 = NULL;

static void             init(int argc, char *argv[]);
static void             cleanup(void);
static void             mainLoop(void);
static void             draw(ARdouble trans1[3][4], ARdouble trans2[3][4], int mode);
static void             keyEvent(unsigned char key, int x, int y);
void DrawCube_multi(LPCTSTR disContent);
void DrawCube1(void);
int main(int argc, char *argv[])
{
    //初始化openGL环境
    glutInit(&argc, argv);//
    init(argc, argv);
    //设置显示函数
    argSetDispFunc(mainLoop, 1);
    //设置键盘输入事件函数
    argSetKeyFunc(keyEvent);
    count = 0;
    arVideoCapStart();//开始捕获视频源
    arUtilTimerReset();//重置定时器
    argMainLoop();//glut主循环
    return (0);
}

static void   keyEvent(unsigned char key, int x, int y)
{
    int     debug;
    int     thresh;

    /* quit if the ESC key is pressed */
    if (key == 0x1b) {
        ARLOG("*** %f (frame/sec)\n", (double)count / arUtilTimer());
        cleanup();
        exit(0);
    }

    if (key == 'd') {
        arGetDebugMode(arHandle, &debug);
        debug = 1 - debug;
        arSetDebugMode(arHandle, debug);
    }

    if (key == '1') {
        arGetDebugMode(arHandle, &debug);
        if (debug) {
            arGetLabelingThresh(arHandle, &thresh);
            thresh -= 5;
            if (thresh < 0) thresh = 0;
            arSetLabelingThresh(arHandle, thresh);
            ARLOG("thresh = %d\n", thresh);
        }
    }
    if (key == '2') {
        arGetDebugMode(arHandle, &debug);
        if (debug) {
            arGetLabelingThresh(arHandle, &thresh);
            thresh += 5;
            if (thresh > 255) thresh = 255;
            arSetLabelingThresh(arHandle, thresh);
            ARLOG("thresh = %d\n", thresh);
        }
    }

    if (key == ' ') {
        robustFlag = 1 - robustFlag;
        if (robustFlag) ARLOG("Robust estimation mode.\n");
        else             ARLOG("Normal estimation mode.\n");
    }
}

/* main loop */
static void mainLoop(void)
{
    ARUint8         *dataPtr;//捕获视频数据的数据指针 unsigned char 类型
    ARMarkerInfo    *marker_info;//描述一个被检测到梯形区域相关信息
    int             marker_num;
    int             imageProcMode; //图像处理模式
    int             debugMode;
    double          err;
    int             i;

    /* grab a video frame */
    if ((dataPtr = (ARUint8 *)arVideoGetImage()) == NULL) {
        arUtilSleep(2); //休眠2毫秒
        return;//arVideoGetImage 返回被捕获视频图像的buffer,从左上角第一行开始读取数据,逐行读取
    }

    //获取一帧图片
    if (count == 100) {
        ARLOG("*** %f (frame/sec)\n", (double)count / arUtilTimer());
        arUtilTimerReset(); //获取到100张图片后对定时器进行重置
        count = 0;
    }
    count++;

    /* detect the markers in the video frame */
    if (arDetectMarker(arHandle, dataPtr) < 0) {
        cleanup();
        exit(0);
    }
    marker_num = arGetMarkerNum(arHandle);  //获取从 video frame中检测到的marker数目
    marker_info = arGetMarker(arHandle);    //获取检测到的marker_info信息


    for (int cnt = 0; cnt < marker_num; cnt++){
        if (marker_info[cnt].id >= 0){
            //若为单独一个模型检测,则可以直接打印其置信度等相关信息
            printf("检测到第%d个标记与配置文件中的标识%d之间的相似度为:%f\n", cnt, marker_info[cnt].id, marker_info[cnt].cf);
        }
        else if (marker_info[cnt].idPatt >= 0){
            //若为多个模型,且模型为自定义模板,则将打印其相似度信息如下
            printf("检测到第%d个标记与配置文件中的标识%d之间的相似度为:%f\n", cnt, marker_info[cnt].idPatt, marker_info[cnt].cfPatt);
        }
        else if (marker_info[cnt].idMatrix >= 0){
            //若为多个模型,且模型为二维条形码,则将打印其相似度信息如下
            printf("检测到第%d个标记与配置文件中的标识%d之间的相似度为:%f\n", cnt, marker_info[cnt].idMatrix, marker_info[cnt].cfMatrix);
        }

    }

    argDrawMode2D(vp); //Update curent camera parameters (internal and external) for rendering 2D or 3D objects in the view plane (like text or 2D shape).
    arGetDebugMode(arHandle, &debugMode); //Find out whether ARToolKit's debug mode is enabled.
    if (debugMode == 0) {
        argDrawImage(dataPtr);
    }
    else {
        arGetImageProcMode(arHandle, &imageProcMode);  //Get the image processing mode.
        if (imageProcMode == AR_IMAGE_PROC_FRAME_IMAGE) {
            argDrawImage(arHandle->labelInfo.bwImage);
        }
        else {
            argDrawImageHalf(arHandle->labelInfo.bwImage);
        }
        glColor3f(1.0f, 0.0f, 0.0f);
        glLineWidth(2.0f);
        for (i = 0; i < marker_num; i++) {
            argDrawSquareByIdealPos(marker_info[i].vertex);
        }
        glLineWidth(1.0f);
    }

    if (robustFlag) {
        err = arGetTransMatMultiSquareRobust(ar3DHandle, marker_info, marker_num, config);
    }
    else {
        err = arGetTransMatMultiSquare(ar3DHandle, marker_info, marker_num, config);
    }
    if (config->prevF == 0) {
        argSwapBuffers();
        return;
    }
    //ARLOGd("err = %f\n", err);

    argDrawMode3D(vp);
    glClearDepth(1.0);
    glClear(GL_DEPTH_BUFFER_BIT);
    for (i = 0; i < config->marker_num; i++) {
        if (config->marker[i].visible >= 0) draw(config->trans, config->marker[i].trans, 0, i);
        /*else                                draw(config->trans, config->marker[i].trans, 1, i);*/
    }

    argSwapBuffers();
}

static void   init(int argc, char *argv[])
{
    ARParam         cparam;
    ARGViewport     viewport;
    ARPattHandle   *arPattHandle;
    char            vconf[512];
    char            configName[512];
    int             xsize, ysize;
    AR_PIXEL_FORMAT pixFormat;
    int             i;

    configName[0] = '\0';
    vconf[0] = '\0';
    for (i = 1; i < argc; i++) {
        if (strncmp(argv[i], "-config=", 8) == 0) {
            strcpy(configName, &argv[i][8]);
        }
        else {
            if (vconf[0] != '\0') strcat(vconf, " ");
            strcat(vconf, argv[i]);
        }
    }
    if (configName[0] == '\0') strcpy(configName, CONFIG_NAME);

    /* open the video path */
    if (arVideoOpen(vconf) < 0) exit(0);
    /* find the size of the window */
    if (arVideoGetSize(&xsize, &ysize) < 0) exit(0);
    ARLOGi("Image size (x,y) = (%d,%d)\n", xsize, ysize);
    if ((pixFormat = arVideoGetPixelFormat()) < 0) exit(0);

    /* set the initial camera parameters */
    if (arParamLoad(CPARA_NAME, 1, &cparam) < 0) {
        ARLOGe("Camera parameter load error !!\n");
        exit(0);
    }
    arParamChangeSize(&cparam, xsize, ysize, &cparam);
    ARLOG("*** Camera Parameter ***\n");
    arParamDisp(&cparam);
    if ((gCparamLT1 = arParamLTCreate(&cparam, AR_PARAM_LT_DEFAULT_OFFSET)) == NULL) {
        ARLOGe("Error: arParamLTCreate.\n");
        exit(-1);
    }

    if ((arHandle = arCreateHandle(gCparamLT1)) == NULL) {
        ARLOGe("Error: arCreateHandle.\n");
        exit(0);
    }
    if (arSetPixelFormat(arHandle, pixFormat) < 0) {
        ARLOGe("Error: arSetPixelFormat.\n");
        exit(0);
    }

    if ((ar3DHandle = ar3DCreateHandle(&cparam)) == NULL) {
        ARLOGe("Error: ar3DCreateHandle.\n");
        exit(0);
    }

    if ((arPattHandle = arPattCreateHandle()) == NULL) {
        ARLOGe("Error: arPattCreateHandle.\n");
        exit(0);
    }
    arPattAttach(arHandle, arPattHandle);

    if ((config = arMultiReadConfigFile(configName, arPattHandle)) == NULL) {
        ARLOGe("config data load error !!\n");
        exit(0);
    }
    //提高每个图像检测之间的相似度截止频率,默认值为0.5,这样提高检测的准确度
    config->cfMatrixCutoff = 0.6;
    config->cfPattCutoff = 0.6;
    

    if (config->patt_type == AR_MULTI_PATTERN_DETECTION_MODE_TEMPLATE) {
        arSetPatternDetectionMode(arHandle, AR_TEMPLATE_MATCHING_COLOR);
    }
    else if (config->patt_type == AR_MULTI_PATTERN_DETECTION_MODE_MATRIX) {
        arSetPatternDetectionMode(arHandle, AR_MATRIX_CODE_DETECTION);
        arSetMatrixCodeType(arHandle, AR_MATRIX_CODE_4x4);
    }
    else { // AR_MULTI_PATTERN_DETECTION_MODE_TEMPLATE_AND_MATRIX
        arSetPatternDetectionMode(arHandle, AR_TEMPLATE_MATCHING_COLOR_AND_MATRIX);
        arSetMatrixCodeType(arHandle, AR_MATRIX_CODE_4x4);
    }

    /* open the graphics window */
    viewport.sx = 0;
    viewport.sy = 0;
    viewport.xsize = xsize;
    viewport.ysize = ysize;
    if ((vp = argCreateViewport(&viewport)) == NULL) exit(0);
    argViewportSetCparam(vp, &cparam);
    argViewportSetPixFormat(vp, pixFormat);
}

/* cleanup function called when program exits */
static void cleanup(void)
{
    arParamLTFree(&gCparamLT1);
    arVideoCapStop();
    arVideoClose();
    argCleanup();
}

static void draw(ARdouble trans1[3][4], ARdouble trans2[3][4], int mode, int patt_num)
{
    ARdouble  gl_para[16];
    GLfloat   light_position[] = { 100.0f, -200.0f, 200.0f, 0.0f };
    GLfloat   light_ambi[] = { 0.1f, 0.1f, 0.1f, 0.0f };
    GLfloat   light_color[] = { 1.0f, 1.0f, 1.0f, 0.0f };
    GLfloat   mat_flash[] = { 1.0f, 1.0f, 1.0f, 0.0f };
    GLfloat   mat_flash_shiny[] = { 50.0f };
    GLfloat   mat_diffuse[] = { 0.0f, 0.0f, 1.0f, 1.0f };
    GLfloat   mat_diffuse1[] = { 1.0f, 0.0f, 0.0f, 1.0f };
    int       debugMode;

    //glEnable(GL_DEPTH_TEST);
    glDisable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    /* load the camera transformation matrix */
    glMatrixMode(GL_MODELVIEW);
    argConvGlpara(trans1, gl_para);
#ifdef ARDOUBLE_IS_FLOAT
    glLoadMatrixf(gl_para);
#else
    glLoadMatrixd(gl_para);
#endif
    argConvGlpara(trans2, gl_para);
#ifdef ARDOUBLE_IS_FLOAT
    glMultMatrixf(gl_para);
#else
    glMultMatrixd(gl_para);
#endif

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambi);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_color);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);
    if (mode == 0) {
        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
        glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse);
    }
    else {
        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse1);
        glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse1);
    }
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    //glTranslatef(0.0f, 0.0f, 20.0f);
    glTranslatef(0.0f, 0.0f, 0.0f);
    arGetDebugMode(arHandle, &debugMode);
    if (debugMode == 0){
        switch (patt_num){
        case 0:    {
                    char *dispContent = getAirInfo();                    
                    DrawCube_multi(dispContent);
                    free(dispContent);
                    dispContent = NULL;
                    break;
        }
        case 1:{
                   char *dispContent = getHotChannelInfo();
                   DrawCube_multi(dispContent);
                   free(dispContent);
                   dispContent = NULL;                
                   break;
        }
        case 2: {
                    char *dispContent = getColdChannelInfo();
                    DrawCube_multi(dispContent);
                    free(dispContent);
                    dispContent = NULL;                
                    break;
        }
        case 3:{
                   char *dispContent = getCabinetInfo();
                   DrawCube_multi(dispContent);
                   free(dispContent);
                   dispContent = NULL;                  
                   break;
        }
        case 4:{
                  char *dispContent = getPDUInfo();
                   DrawCube_multi(dispContent);
                   free(dispContent);
                   dispContent = NULL;                
                   break;
        }            
        case 5:{
                   char *dispContent = getShortColdChannelInfo();
                   DrawCube_multi(dispContent);
                   free(dispContent);
                   dispContent = NULL;
                   break;
        }
        default:            
            DrawCube_multi("没有相对应的设备信息");
        }
    }
    else {
        DrawCube_multi("没有相对应的设备信息");
    }
    glPopMatrix();

    glDisable(GL_LIGHT0);
    glDisable(GL_LIGHTING);
    //glDisable(GL_DEPTH_TEST);
}

void DrawCube_multi(char *disContent)
{
    // Colour cube data.
    int i;
    float fSize = 40.0f;
    //平面大小 2.4*2.4
    const GLfloat cube_vertices[8][3] = {
        /* +z */{ 1.2f, 1.2f, 0.5f }, { 1.2f, -1.2f, 0.5f }, { -1.2f, -1.2f, 0.5f }, { -1.2f, 1.2f, 0.5f },
        /* -z */{ 1.2f, 1.2f, 0.5f }, { 1.2f, -1.2f, 0.5f }, { -1.2f, -1.2f, 0.5f }, { -1.2f, 1.2f, 0.5f } };
    //绿色,全透明
    const GLubyte cube_vertex_colors[8][4] = {
        { 0, 255, 0, 255 }, { 0, 255, 0, 255 }, { 0, 255, 0, 255 }, { 0, 255, 0, 255},
        { 0, 255, 0, 255 }, { 0, 255, 0, 255}, { 0, 255, 0, 255}, { 0, 255, 0, 255} };

    const GLubyte cube_faces[6][4] = { /* ccw-winding  counter - clockwise winding 逆时针方向缠绕*/
        /* +z */{ 3, 2, 1, 0 }, /* -x */{ 2, 3, 7, 6 }, /* +x */{ 0, 1, 5, 4 },
        /* -y */{ 3, 0, 4, 7 }, /* +y */{ 1, 2, 6, 5 }, /* -z */{ 4, 5, 6, 7 } };

    glPushMatrix(); // Save world coordinate system.    
    glScalef(fSize, fSize, fSize);
    glTranslatef(-0.3f, 0.05f, 0.0f); // Place base of cube on marker surface. 覆盖整个标签,z轴不变,x,y
    glDisable(GL_LIGHTING);
    glDisable(GL_TEXTURE_2D);//纹理
    //glDisable(GL_BLEND);    
    glEnable(GL_BLEND);    
    glDepthMask(GL_FALSE);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, cube_vertex_colors);//指定含有顶点颜色的数组
    glVertexPointer(3, GL_FLOAT, 0, cube_vertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    for (i = 0; i < 6; i++) {
        //glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE, &(cube_faces[i][0]));
        glDrawElements(GL_LINE, 4, GL_UNSIGNED_BYTE, &(cube_faces[i][0]));
    }
    glDisableClientState(GL_COLOR_ARRAY);
    glColor4ub(0, 0, 0, 255);
    for (i = 0; i < 6; i++) {
        glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_BYTE, &(cube_faces[i][0]));
    }
    //glBlendFunc(GL_ONE, GL_ONE);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //glBlendFunc(GL_SRC_ALPHA, GL_ONE);    
    glDepthMask(GL_TRUE);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisable(GL_BLEND);
    /*CreateFont的参数
           cHeight 字体的逻辑高度
           cWidth  字体的逻辑宽度
           cEscapement 指定移位向量相对x轴的偏转角度
           cOrientation 指定字符基线相对x轴的偏转角度
           cWeight 设置字符粗细程度
           bItalic 是否启用斜体
           bUnderline 是否启用下划线
           bStrikeOut 是否启用删除线
           iCharset  指定字符集
           iOutPrecision 输出精度
           iClipPrecision 剪裁精度
           iQuality 输出质量
           iPitchAndFamily 字体族
           pszFaceName 字体名
    */
    HFONT hFont = CreateFont(0, 0, 0, 0, 100, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, FF_MODERN, TEXT("宋体"));
    /*根据字符串里面是否包含\n对字符串进行行分割并进行多行显示*/
    char delims[] = "\n";
    char *lineStr=NULL;
    //将字符串常量转为字符串变量
    char *dispContentStr = (char *)malloc(sizeof(char)*(strlen(disContent) + 1));
    int yOffsetUnitCnt = 0;
    float originY = 0.7f;
    float actualY = originY;
    float moveYdistance = 0.2f;
    if (dispContentStr != NULL){
        strcpy(dispContentStr, disContent);
        lineStr = strtok(dispContentStr, delims); //strtok中的char *Str为非常量指针,而非常量指针可以隐式转换为常量指针,由于strtok会对指针指向值进行修改,
        while (lineStr != NULL){        //所以当Str为常量指针时,编译时没有问题,但运行时会报错
            actualY = originY - yOffsetUnitCnt*moveYdistance;
            draw3dtextWithCloseLight(lineStr, hFont, 0.2f, -1.1f, actualY, 0.7f, 0.2f, 0.2f, 0.2f, 0.0f, 0.0f, 0.0f);
            printf("result is \"%s\"\n", lineStr);
            lineStr = strtok(NULL, delims);
            yOffsetUnitCnt++;
        }
    }
    else{
        printf("mallocerror\n");
        exit(-1);
    }    
    free(dispContentStr);
    dispContentStr = NULL;

    /*
      str 一行需要显示的字体
      hFont 一种具有特殊性的逻辑字体,在后面可以被任何设备选择
      cDepth 字体的深度
      dXoffset,Yoffset,Zoffset 偏移原点位置
    */
    //draw3dtextWithCloseLight(disContent, hFont, 0.0f, -0.5f, -0.5f, 0.6f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f);
    //draw3dtextWithCloseLight(disContent, hFont, 0.0f, -0.5f, 0.0f, 0.6f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f);
    //draw3dtextWithCloseLight(disContent, hFont, 0.0f, -0.5f, 0.5f, 0.6f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f);
    glPopMatrix();    // Restore world coordinate system.    

}


参考链接:

http://www.artoolworks.com/support/applications/marker/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值