91

阿木币

0

精华

32 小时

在线时间

老司机

Rank: 2

发表于 2020-1-10 18:11:55 33536 浏览 18 回复

[飞控嵌入式] 基于Aruco二维码检测定位

基于Aruco二维码检测给出两种方案,一种是使用一个二维码进行检测定位,第二种是使用9个二维码拼成一张图进行求平均进行定位,通过实验有一疑问在这里进行求教。
疑问一:两种方案输出结果稳定性不好,尤其是第二方案,在实际应用中是不是加滤波器进行提高数据稳定性,有没有成熟的方案,求指点
疑问二:在第二种方案中,switch中求平均,偏移的加减不是特别明白,个人感觉程序中加减搞反了。
疑问三:在自主着陆中使用视觉进行定位比较好的方案是什么?
由于我刚开始学习视觉相关知识,上边提的问题有不合适的请见谅,谢谢!



扫一扫浏览分享
回复

使用道具 举报

35

阿木币

0

精华

4 小时

在线时间

应届白菜

Rank: 1

发表于 2020-1-11 15:23:47
关于疑问一,视觉这块的输出可以加一些滤波算法,如果是离群点噪声,加一个窗口平滑即可。对于二维码,我觉得主要的噪声是运动模糊,所以相机的选择特别重要,应该尽可能选择高帧率,低曝光时间的工业相机。

关于疑问二,这个我们会仔细检查代码,之后再回复您。
关于疑问三,如果对精度要求比较高,二维码是比较合适的,主要是选择高清、高帧率的相机。其他方案,比如基于椭圆检测的标志识别,可以抗一定的运动模糊,对相机要求相对较低。
回复 点赞

使用道具 举报

91

阿木币

0

精华

32 小时

在线时间

老司机

Rank: 2

 楼主| 发表于 2020-1-12 10:03:39
jario 发表于 2020-1-11 15:23
关于疑问一,视觉这块的输出可以加一些滤波算法,如果是离群点噪声,加一个窗口平滑即可。对于二维码,我觉 ...

首先感谢回帖!
高帧率的相机有具体推荐的型号吗?求推荐一款使用不错的相机。
还有一个问题想请教,最近有一个想法,但是不知道思路对不对,所以在此请教。我想自己设计一个降落标志,然后使用SIFT算法进行特征匹配找出匹配的区域,然后求出中心点,在进行坐标转换然后进行输出,壁纸刀这个方案是不是可行,求指点。
回复 点赞

使用道具 举报

255

阿木币

1

精华

55 小时

在线时间

老司机

Rank: 2

发表于 2020-1-12 10:54:09
hwang 发表于 2020-1-12 10:03
首先感谢回帖!
高帧率的相机有具体推荐的型号吗?求推荐一款使用不错的相机。
还有一个问题想请教,最近 ...

好友难度的问题。。。jario大神啊~~
回复 点赞

使用道具 举报

35

阿木币

0

精华

4 小时

在线时间

应届白菜

Rank: 1

发表于 2020-1-13 01:25:21
hwang 发表于 2020-1-12 10:03
首先感谢回帖!
高帧率的相机有具体推荐的型号吗?求推荐一款使用不错的相机。
还有一个问题想请教,最近 ...

搞帧率的相机,我们之前用过PointGray的,还不错。
https://www.flir.com/iis/machine-vision

SIFT匹配的话,如果背景比较复杂会有很多噪声,怎么去除噪声我觉得还是一个检测问题。如果标志有先验信息最好能利用,这样更有利于检测,如矩形 椭圆这样的。
回复 点赞

使用道具 举报

35

阿木币

0

精华

4 小时

在线时间

应届白菜

Rank: 1

发表于 2020-1-13 01:27:51
blueboats 发表于 2020-1-12 10:54
好友难度的问题。。。jario大神啊~~

过奖过奖,谢谢支持{:4_119:}
回复 点赞

使用道具 举报

91

阿木币

0

精华

32 小时

在线时间

老司机

Rank: 2

 楼主| 发表于 2020-1-13 08:03:07
jario 发表于 2020-1-13 01:25
搞帧率的相机,我们之前用过PointGray的,还不错。
https://www.flir.com/iis/machine-vision

好的,谢谢大神耐心回复,我先搞一下,后续有问题再来求教!
回复 点赞

使用道具 举报

91

阿木币

0

精华

32 小时

在线时间

老司机

Rank: 2

 楼主| 发表于 2020-1-13 08:30:39
jario 发表于 2020-1-13 01:25
搞帧率的相机,我们之前用过PointGray的,还不错。
https://www.flir.com/iis/machine-vision

我们自己设计的标志就是圆圈里加上公司的标志,你对这种有没有推荐的检测识别方法呢?
回复 点赞

使用道具 举报

91

阿木币

0

精华

32 小时

在线时间

老司机

Rank: 2

 楼主| 发表于 2020-1-19 16:02:12
本帖最后由 hwang 于 2020-1-19 16:42 编辑
jario 发表于 2020-1-13 01:25
搞帧率的相机,我们之前用过PointGray的,还不错。
https://www.flir.com/iis/machine-vision

我这边使用二维码检测定位在gazebo进行了仿真实验,输出的数据抖动太厉害无人机下降过程一直在乱晃,无法实现着落,我把代码贴到下边,麻烦大佬看一下是哪里有问题,能不能给点优化思路,拜托。

//-----------------利用Euler角进行三次旋转得到无人机相对目标的位置------------------
void CodeRotateByZ(double x, double y, double thetaz, double &outx, double &outy)
{
  double x1 = x; //将变量拷贝一次,保证&x == &outx这种情况下也能计算正确
  double y1 = y;
  double rz = thetaz * CV_PI / 180;
  outx = cos(rz) * x1 - sin(rz) * y1;
  outy = sin(rz) * x1 + cos(rz) * y1;
}
void CodeRotateByY(double x, double z, double thetay, double &outx, double &outz)
{
  double x1 = x;
  double z1 = z;
  double ry = thetay * CV_PI / 180;
  outx = cos(ry) * x1 + sin(ry) * z1;
  outz = cos(ry) * z1 - sin(ry) * x1;
}
void CodeRotateByX(double y, double z, double thetax, double &outy, double &outz)
{
  double y1 = y; //将变量拷贝一次,保证&y == &y这种情况下也能计算正确
  double z1 = z;
  double rx = thetax * CV_PI / 180;
  outy = cos(rx) * y1 - sin(rx) * z1;
  outz = cos(rx) * z1 + sin(rx) * y1;
}

int main(int argc, char **argv)
{
  //Initiate ROS
  ros::init(argc, argv, "pose_estimate_one");
  ros::NodeHandle nh_;
  ros::Rate loop_rate(30);

  precision_landing = nh_.advertise<urtrans::PrecisionLanding>("/precision_landing", 10);

  cv::Mat camera_matrix;
  cv::Mat distortion_coefficients;

  //相机内参
  camera_matrix = cv::Mat(3, 3, CV_64FC1, cv::Scalar::all(0)); //初始化矩阵的头,设置元素初始值
  camera_matrix.ptr<double>(0)[0] = 582.611780;
  camera_matrix.ptr<double>(0)[2] = 355.598968;
  camera_matrix.ptr<double>(1)[1] = 582.283970;
  camera_matrix.ptr<double>(1)[2] = 259.508932;
  camera_matrix.ptr<double>(2)[2] = 1.0f;
  //相机畸变参数
  distortion_coefficients = cv::Mat(5, 1, CV_64FC1, cv::Scalar::all(0));
  distortion_coefficients.ptr<double>(0)[0] = -0.409105;
  distortion_coefficients.ptr<double>(1)[0] = 0.200162;
  distortion_coefficients.ptr<double>(2)[0] = 0.003778;
  distortion_coefficients.ptr<double>(3)[0] = 0.000588;
  distortion_coefficients.ptr<double>(4)[0] = 0.0;

  //ArUco Marker字典选择以及旋转向量和平移向量初始化
  Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(7); //创建字典对象
  vector<double> rv(3), tv(3);
  cv::Mat rvec(rv), tvec(tv);
  VehicleState::SmartSensor smart_sensor_;
  VehicleStateSet::SetpointPosition set_position_;
  cv::Mat image;
  sensor_msgs::ImagePtr msg_ellipse;
  sensor_msgs::Image msg;
  urtrans::PrecisionLanding pre_land;
  while (ros::ok())
  {
    msg = smart_sensor_.get_down_cam_img();
    if (msg.width == 0)
    {
      ROS_INFO_STREAM("get_fro_cam_img() is null");
    }
    else
    {
      cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
    image = cv_ptr->image;
    std::vector<int> markerids;
    vector<vector<Point2f>> markerCorners, rejectedCandidate;
    Ptr<cv::aruco::DetectorParameters> parameters = cv::aruco::DetectorParameters::create();
    cv::aruco::detectMarkers(image, dictionary, markerCorners, markerids, parameters, rejectedCandidate); //检测函数,返回检测出的markers
                                                                                                          //待检测图像,字典对象,检测出的图像的角的列表,检测出的所有marker的id列表,检测阶段的所有参数,返回所有marker候选。

    if (markerids.size() > 0) //如果检测到marker,下一步多marker位置进行求解
    {
      cv::Mat RoteM, TransM;
      cv::Point3f Theta_C2W;
      cv::Point3f Theta_W2C;
      cv::Point3f Position_OcInW;

      cv::aruco::estimatePoseSingleMarkers(markerCorners, 1, camera_matrix, distortion_coefficients, rvec, tvec); //检测所有探测到的marker的pose
      //marke的角向量,二维码的大小(m)相机内参,相机畸变参数,marker的旋转量,平移量

      double rm[9];
      RoteM = cv::Mat(3, 3, CV_64FC1, rm);
      Rodrigues(rvec, RoteM); //罗德里旋转得到旋转矩阵
      double r11 = RoteM.ptr<double>(0)[0];
      double r12 = RoteM.ptr<double>(0)[1];
      double r13 = RoteM.ptr<double>(0)[2];
      double r21 = RoteM.ptr<double>(1)[0];
      double r22 = RoteM.ptr<double>(1)[1];
      double r23 = RoteM.ptr<double>(1)[2];
      double r31 = RoteM.ptr<double>(2)[0];
      double r32 = RoteM.ptr<double>(2)[1];
      double r33 = RoteM.ptr<double>(2)[2];
      TransM = tvec; //平移向量

      double thetaz = atan2(r21, r11) / CV_PI * 180;
      double thetay = atan2(-1 * r31, sqrt(r32 * r32 + r33 * r33)) / CV_PI * 180;
      double thetax = atan2(r32, r33) / CV_PI * 180;

      Theta_C2W.z = thetaz;
      Theta_C2W.y = thetay;
      Theta_C2W.x = thetax;

      Theta_W2C.x = -1 * thetax;
      Theta_W2C.y = -1 * thetay;
      Theta_W2C.z = -1 * thetaz;

      double tx = tvec.ptr<double>(0)[0];
      double ty = tvec.ptr<double>(0)[1];
      double tz = tvec.ptr<double>(0)[2];
      double x = tx, y = ty, z = tz;
      //ZYX axis rotate
      CodeRotateByZ(x, y, -1 * thetaz, x, y);
      CodeRotateByY(x, z, -1 * thetay, x, z);
      CodeRotateByX(y, z, -1 * thetax, y, z);

      Position_OcInW.x = x * -1;
      Position_OcInW.y = y * -1;
      Position_OcInW.z = z * -1;

      //计算偏航角之差
      Eigen::Matrix3d rotateMatrix;
      rotateMatrix << r11, r12, r13, r21, r22, r23, r31, r32, r33;
      Eigen::Vector3d eulerVec;
      eulerVec(0) = (Theta_C2W.z + 90) / 180 * CV_PI;

      //设置是否检测到标志的flage
      distinguish_flag = true;
      pre_land.is_located = distinguish_flag;

      // pre_land.des_dx_body = Position_OcInW.x;
      // pre_land.des_dy_body = Position_OcInW.y;
      // pre_land.des_dz_body = Position_OcInW.z;

      pre_land.des_dx = Position_OcInW.x;
      pre_land.des_dy = Position_OcInW.y;
      pre_land.des_dz = Position_OcInW.z;

      pre_land.locate_precision = 1;
      //set_position_.set_position(Position_OcInW.x, Position_OcInW.y, Position_OcInW.z, eulerVec(0));

      cout << "pos_target: [X Y Z] : "
           << " " << Position_OcInW.x << " [m] " << Position_OcInW.y << " [m] " << Position_OcInW.z << " [m] " << endl;
    }
    else
    {
      distinguish_flag = false;
      pre_land.is_located = distinguish_flag;

      // pre_land.des_dx_body = 0;
      // pre_land.des_dy_body = 0;
      // pre_land.des_dz_body = 0;

      pre_land.des_dx = 0;
      pre_land.des_dy = 0;
      pre_land.des_dz = 0;

      pre_land.locate_precision = 0;

      //set_position_.set_position(0, 0, 0, 0);
      // cout << "can not detected qrcode!" << endl;
    }
    precision_landing.publish(pre_land);
    Mat img_copy;
    image.copyTo(img_copy);
    cv::aruco::drawDetectedMarkers(img_copy, markerCorners, markerids); //绘制检测出来的图像
    //cv::aruco::drawAxis(img_copy, camera_matrix, distortion_coefficients, rvec, tvec, 0.1);
    cv::imshow("pose_estimate_one", img_copy);
    cv::waitKey(1);
    }
    ros::spinOnce();
    loop_rate.sleep();
  }
}
precision_land.png
land_data.png
aruco.jpg
回复 点赞

使用道具 举报

52

阿木币

1

精华

2400 小时

在线时间

管理员

Rank: 9Rank: 9Rank: 9

发表于 2020-1-19 16:38:06
视频如下: WeChat_20200119162849.mp4 (1.02 MB, 下载次数: 4)
回复 点赞

使用道具 举报

下一页 »
12下一页
返回列表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表