ArUco----一个微型现实增强库的介绍及视觉应用(二)

2023-05-16

ArUco----一个微型现实增强库的介绍及视觉应用(二)

ArUco----一个微型现实增强库的介绍及视觉应用(二)

一、第一个ArUco的视觉应用

  首先介绍第一个视觉应用的Demo,这个应用场景比较简单,下面具体介绍:

1. 应用场景

  主线程:通过摄像头检测环境中的视觉标志,看到ID为100的标志后在图像中圈出标志,在标志上绘制坐标系,得到视觉标志相对于相机坐标系的位置和姿态参数;

  子线程:将得到的视觉标志进一步转换成需要的数据类型并发送给机器人。

2. 编程环境

  Ubuntu14.04(安装有OpenCV以及ArUco)

3. 编译工具

  Cmake

 4. 源码下载地址

  https://github.com/Zhanggx0102/Aruco_Blog_Demo.git

 5. 源码处理

  下载完成后重新编译即可。

  cd Aruco_Blog_Demo-master

  rm -r build/

  mkdir build

  cd build

  cmake ..

  make 

二、源码解读

 源码中已经做了比较详细的注释,这里主要讲解程序框架。

程序流程图如下所示:

 

程序流程图

执行后的效果如下图所示:

下面是源码截取的两个主要的函数。

/*******************************************************************************************************************
main function
********************************************************************************************************************/
int main(int argc,char **argv)
{

    int thread_return;
    pthread_t Message_Send_Thread_ID;
    //init thread lock
    pthread_mutex_init(&IK_Solver_Lock, NULL);
    //creat new thread 
    thread_return = pthread_create(&Message_Send_Thread_ID,NULL,Thread_Func_Message_Send,NULL);
    
    //import the camera param (CameraMatrix)
    float camera_matrix_array[9] = { 1.0078520005023535e+003, 0., 6.3950000000000000e+002, 
                                  0.0, 1.0078520005023535e+003, 3.5950000000000000e+002, 
                                  0.0, 0.0, 1.0 };
    cv::Mat Camera_Matrix(3,3,CV_32FC1);
    InitMat(Camera_Matrix,camera_matrix_array);
    cout << "Camera_Matrix = " << endl << "" << Camera_Matrix << endl ;
    //import the camera param (Distorsion)
    float Distorsion_array[5] = {-4.9694653328469340e-002, 2.3886698343464000e-001, 0., 0.,-2.1783942538569392e-001};
    cv::Mat Distorsion_M(1,5,CV_32FC1);
    InitMat(Distorsion_M,Distorsion_array);
    cout << "Distorsion_M = " << endl << "" << Distorsion_M << endl ;

    CameraParameters LogiC170Param;
    //LogiC170Param.readFromXMLFile("LogitchC170_Param.yml");
    LogiC170Param.CameraMatrix = Camera_Matrix.clone();
    LogiC170Param.Distorsion = Distorsion_M.clone();
    LogiC170Param.CamSize.width = 1280;
    LogiC170Param.CamSize.height = 720;

    float MarkerSize = 0.04;
    int Marker_ID;
    MarkerDetector MDetector;
    MDetector.setThresholdParams(7, 7);
    MDetector.setThresholdParamRange(2, 0);

    CvDrawingUtils MDraw;

    //read the input image
    VideoCapture cap(0); // open the default camera 
     if(!cap.isOpened())  // check if we succeeded  
        return -1; 
    cv::Mat frame;
    cv::Mat Rvec;//rotational vector
    CvMat Rvec_Matrix;//temp matrix
    CvMat R_Matrix;//rotational matrixs
    cv::Mat Tvec;//translation vector

    cap>>frame;//get first frame
    //LogiC170Param.resize(frame.size());

    printf("%f, %f\n",cap.get(CV_CAP_PROP_FRAME_WIDTH),cap.get(CV_CAP_PROP_FRAME_HEIGHT));  
    cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280);  
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 720);  
    //cap.set(CV_CAP_PROP_FPS, 10);  
    printf("%f, %f\n",cap.get(CV_CAP_PROP_FRAME_WIDTH),cap.get(CV_CAP_PROP_FRAME_HEIGHT));   

    while(1)
    {
        //get current frame
        cap>>frame;
        //Ok, let's detect
        vector< Marker >  Markers=MDetector.detect(frame, LogiC170Param, MarkerSize);
        //printf("marker count:%d \n",(int)(Markers.size()));

        //for each marker, estimate its ID and if it is  100 draw info and its boundaries in the image
        for (unsigned int j=0;j<Markers.size();j++)
        {
            //marker ID test
            Marker_ID = Markers[j].id;
            printf("Marker ID = %d \n",Marker_ID);

            if(Marker_ID == 100)
            {
                //cout<<Markers[j]<<endl;
                Markers[j].draw(frame,Scalar(0,0,255),2);

                Markers[j].calculateExtrinsics(MarkerSize, LogiC170Param, false);
                //calculate rotational vector
                Rvec = Markers[j].Rvec;
                cout << "Rvec = " << endl << "" << Rvec << endl ;
                //calculate transformation vector
                Tvec = Markers[j].Tvec;
                cout << "Tvec = " << endl << "" << Tvec << endl ;

                //lock to update global variables: Rotat_Vec_Arr[3]  Rotat_M[9]  Trans_M[3]
                pthread_mutex_lock(&IK_Solver_Lock);

                //save rotational vector to float array
                for (int r = 0; r < Rvec.rows; r++)  
                {  
                    for (int c = 0; c < Rvec.cols; c++)  
                    {     
                        //cout<< Rvec.at<float>(r,c)<<endl;  
                        Rotat_Vec_Arr[r] = Rvec.at<float>(r,c);
                    }     
                }
                printf("Rotat_Vec_Arr[3] = [%f, %f, %f] \n",Rotat_Vec_Arr[0],Rotat_Vec_Arr[1],Rotat_Vec_Arr[2]);

                //save array data to CvMat and convert rotational vector to rotational matrix
                cvInitMatHeader(&Rvec_Matrix,1,3,CV_32FC1,Rotat_Vec_Arr,CV_AUTOSTEP);//init Rvec_Matrix
                cvInitMatHeader(&R_Matrix,3,3,CV_32FC1,Rotat_M,CV_AUTOSTEP);//init R_Matrix and Rotat_M
                cvRodrigues2(&Rvec_Matrix, &R_Matrix,0);
                printf("Rotat_M = \n[%f, %f, %f, \n  %f, %f, %f, \n  %f, %f, %f] \n",Rotat_M[0],Rotat_M[1],Rotat_M[2],Rotat_M[3],Rotat_M[4],Rotat_M[5],Rotat_M[6],Rotat_M[7],Rotat_M[8]);
                
                //save transformation vector to float array
                for (int r = 0; r < Tvec.rows; r++)
                {  
                    for (int c = 0; c < Tvec.cols; c++)  
                    {
                        Trans_M[r] = Tvec.at<float>(r,c);
                    }
                }
                printf("Trans_M[3] = [%f, %f, %f] \n",Trans_M[0],Trans_M[1],Trans_M[2]);

                //unlock 
                pthread_mutex_unlock(&IK_Solver_Lock);

                // draw a 3d cube in each marker if there is 3d info
                if (LogiC170Param.isValid() && MarkerSize != -1)
                {
                    MDraw.draw3dAxis(frame,LogiC170Param,Rvec,Tvec,0.04);
                }
            }
        }
        //*/
        cv::waitKey(150);//wait for key to be pressed
        cv::imshow("Frame",frame);
    }
    //wait for the IK solver thread close and recover resources
    pthread_join(Message_Send_Thread_ID,NULL);

    pthread_mutex_destroy(&IK_Solver_Lock); //destroy the thread lock
    return 0
}
/**********************************************************
function: new thread to send messages 
input: void
return :null
***********************************************************/
void * Thread_Func_Message_Send(void *arg)
{
    printf("IK solver thread is running!\n");
    //original pose and position
    float P_original[4];
    float N_original[4];
    float O_original[4];
    float A_original[4];
    //final pose and position 
    float P[3];
    float N[3];
    float O[3];
    float A[3];

    P_original[3] = 1;
    N_original[3] = 0;
    O_original[3] = 0;
    A_original[3] = 0;

    while (1)
    {
        //get the spacial pose
        pthread_mutex_lock(&IK_Solver_Lock);
        //memcpy(P_original, Trans_M, sizeof(Trans_M));
        for(int i=0;i<3;i++)
        {
            P_original[i] = Trans_M[i];
            N_original[i] = Rotat_M[3*i];
            O_original[i] = Rotat_M[3*i+1];
            A_original[i] = Rotat_M[3*i+2];
        }
        pthread_mutex_unlock(&IK_Solver_Lock);
        //debug printf
        ///*
        printf("N_original[4] = [%f, %f, %f, %f]  \n",N_original[0],N_original[1],N_original[2],N_original[3]);
        printf("O_original[4] = [%f, %f, %f, %f]  \n",O_original[0],O_original[1],O_original[2],O_original[3]);
        printf("A_original[4] = [%f, %f, %f, %f]  \n",A_original[0],A_original[1],A_original[2],A_original[3]);
        printf("P_original[4] = [%f, %f, %f, %f]  \n",P_original[0],P_original[1],P_original[2],P_original[3]);
        //*/

        printf("I send the message to robot here! \n");
        /*
        add message send function here!
        */
//uodate every 5 s sleep(5); } //kill the message send thread pthread_exit(0); }

 

<-- 本篇完-->

 

欢迎留言、私信、邮箱、微信等任何形式的技术交流。

作者信息:

名称:Shawn

邮箱:zhanggx0102@163.com

微信二维码:↓

          

posted on 2017-12-15 17:27 Shawn0102 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/shawn0102/p/8039439.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ArUco----一个微型现实增强库的介绍及视觉应用(二) 的相关文章

  • SLAM学习——使用ARUCO_marker进行AR投影

    转载自 xff1a https blog csdn net Kalenee article details 90148599 SLAM学习 使用ARUCO marker进行AR投影 white Learner 2020 06 06 15 2
  • 基于opencv的ArUco的视觉定位之ArUco安装

    转载自 xff1a https blog csdn net weixin 43053387 article details 84952557 基于opencv的ArUco的视觉定位之ArUco安装 share space 2019 01 1
  • python下使用aruco标记进进行三维姿势估计(转载)

    转载自 xff1a https www it610 com article 1291934151255072768 htm python下使用aruco标记进进行三维姿势估计 视觉机器人 python3 aruco python openc
  • ArUco Marker检测原理

    标记检测过程包括两个主要步骤 xff1a 检测候选marker 在该步骤中 xff0c 分析图像以找到作为标记的候选的正方形形状 它首先进行自适应阈值处理以对标记进行分割 xff0c 然后从阈值图像中提取轮廓 xff0c 并丢弃那些非凸起或
  • 基于opencv的ArUco的视觉定位之ArUco安装

    小编之前在前面的文章里是通过安装opencv 43 contirb来实现使用aruco xff0c 但在进行aruco的源码学习时 xff0c 发现不少类contirb里库是没有的 xff0c 于是不得不再装一个独立的aruco的库 xff
  • 【OpenCV3.2】Detection of ArUco Markers

    姿态估计 xff08 Pose estimation xff09 在 计算机视觉 领域扮演着十分重要的角色 xff1a 机器人 导航 增强现实以及其它 这一过程的基础是找到现实世界和图像投影之间的对应点 这通常是很困难的一步 xff0c 因
  • 二维相机能得到三维信息?机器人感知部分之Aruco标定板的使用

    大家好 xff0c 我是小鱼 xff0c 今天来介绍一下Aruco并是结合ROS来进行识别 aruco其实是opencv中的一个库 xff0c 可以将特定的标记物转换成三维的坐标 xff0c 所以它是可以脱离ROS进行使用的 aruco介绍
  • ARUCO marker的解释

    markers for ARUCO 一种汉明 海明 码的格子图 如图 百度百科解释汉明码规则概要 使用奇偶校验 具有一位纠错能力 校验位在2的次幂位置1 2 4 8 16 32 具体参看 https baike baidu com item
  • opencv_contrib aruco源码

    https github com opencv opencv contrib tree master modules 最近使用了aruco模块 想看看aruco的源码是怎样实现的 在opencv源码中一直没找到aruco 原来 他隐藏在op
  • aruco marker 的使用

    安装aruco 教程 xff1a make make install
  • aruco安装 配合realsense 使用

    使用github安装 网址 xff1a http www uco es investiga grupos ava node 26 git clone到本地之后 xff0c catkin make即可开始使用 使用apt安装 span cla
  • Aruco检测

    来自 xff1a https blog dgut top 2020 07 15 python aruco 检测ID span class token keyword import span numpy span class token ke
  • 源码实现 Aruco检测

    以下为实现aruco检测并读取id的代码 xff0c 直接复制粘贴即可 相信看到这篇博客的伙伴应该知道aruco xff0c 我就不解释了 opencv3 0以上有实现aruco的库 一 cmake编译信息 Cmakelist txt cm
  • ArUco----一个微型现实增强库的介绍及视觉应用(一)

    ArUco 一个微型现实增强库的介绍及视觉应用 xff08 一 xff09 ArUco 一个微型现实增强库的介绍及视觉应用 xff08 一 xff09 一 ArUco简介 ArUco是一个开源的微型的现实增强库 xff0c 目前好像已经集成
  • Aruco的使用+opencv+opencv_contrib+cmake

    Aruco的使用 By GuangyeHu 1 下载 xff1a https sourceforge net projects aruco files 解压到相应的文件夹 2 安装Cmake 本次实现使用的是cmake 3 15 1 win
  • 结合OPENNI2,Aruco与OPENCV进行视觉定位

    前些时间写了篇文章把我在做这个项目中遇到的问题以及思路说了一下 传送门 http jcs130 iteye com blog 2185533 在上篇文章的思路下作了实现 已经达到了教授的要求 nbsp 首先第一步检测四个角的坐标 经试验 在
  • SLAM学习——使用ARUCO_marker进行AR投影

    一 简介 1 1 目标 增强现实技术 xff08 Augmented Reality xff0c 简称 AR xff09 xff0c 是一种实时地计算摄影机影像的位置及角度并加上相应图像 视频 3D模型的技术 xff0c 这种技术的目标是在
  • 【AR】使用OpenCV中的aruco模块实现增强现实

    1 ArUco marker ArUco marker是由S Garrido Jurado等人在2014年提出的 xff0c 全称是Augmented Reality University of Cordoba xff0c 详见他们的论文
  • Ros下Aruco模块的使用

    生成ARUCO ROS MARKER 链接 http chev me arucogen 首先启动ros roscore 打开相机节点 xff0c 在此提供usb相机与Realsense D435i的启动方法 xff1a roslaunch
  • 使用Realsense测试aruco_ros包

    01 准备工作 安装realsense ros安装aruco ros span class token builtin class name cd span ur ws src span class token function git s

随机推荐