当前位置: 首页 > news >正文

广州网站建设定制设计建站平台哪个好

广州网站建设定制设计,建站平台哪个好,单页网站建站,北京做网站建设文章目录 前言一、OpenCV函数测试二、原因分析三、libcbdetect修改总结 前言 棋盘格角点检测在相机拼接、机械臂手眼标定中等应用很广泛,通常也要求尽量各种角度摆放从而保证标定精度。然后就自然想到了这个问题:如果棋盘格任意角度摆放怎么能对应上角点…

文章目录

  • 前言
  • 一、OpenCV函数测试
  • 二、原因分析
  • 三、libcbdetect修改
  • 总结


前言

棋盘格角点检测在相机拼接、机械臂手眼标定中等应用很广泛,通常也要求尽量各种角度摆放从而保证标定精度。然后就自然想到了这个问题:如果棋盘格任意角度摆放怎么能对应上角点的顺序?如图所示(原来是8x6的棋盘格,我划掉了一列,变成了7x6):在这里插入图片描述
在这里插入图片描述


一、OpenCV函数测试

为了解决这个困惑,先用OpenCV自带的棋盘格检测试试,打印一下角点序号:

void onChange(int angle, void* userdata)
{Mat img = *(Mat*)userdata;Mat img_rotate;cv::Point2f center(img.cols / 2.0, img.rows / 2.0);cv::Mat rot_mat = cv::getRotationMatrix2D(center, angle, 1.0);cv::warpAffine(img, img_rotate, rot_mat, img.size());vector<Point2f> points;findChessboardCorners(img_rotate, Size(7, 6), points);for(int i=0;i<points.size();i++){//circle(img_rotate, points[i], 5, Scalar(0, 0, 255), 2, 8, 0);putText(img_rotate, to_string(i), points[i], FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255), 1, 8, false);}imshow("img_rotate", img_rotate);waitKey(1);
}int main(int argc, char* argv[])
{Mat img;if(argc < 2)img = imread("20250305155453261.bmp");elseimg = imread(argv[1]);int angle = 180;namedWindow("img_rotate", WINDOW_AUTOSIZE);createTrackbar("angle", "img_rotate", &angle, 360,onChange,(void*)&img);   waitKey(0);return 0;
}

然后测试了7x6的棋盘格,发现随便怎么转序号都不变,就跟上面2张图一样。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、原因分析

原来8x6的棋盘格就会混淆序号,其实也好理解,行数和列数均为偶数时,棋盘格是对称的,旋转180度无法区分上下。当行数和列数一奇一偶时,有一边就是不对称的,起始点的格子颜色也不一样,例如7x6中,起始点格子为黑色,水平放置时判断一下左上角和右下角格子颜色,黑色就是起始块,当然也可以约定白色是起始块。

三、libcbdetect修改

libcbdetect是一个github大神根据论文开源的棋盘格角点检测算法,有时opencv检测不出来的它能检测,但是貌似是不支持这种角点顺序不变的功能。因此想着根据起始块颜色来区分一下,暂且就定义黑色为起始块,算法思路也比较简单:

  1. 根据检测到的角点将图片旋转至水平
  2. 角点也相应的旋转至水平,旋转前的角点记录下来
  3. 旋转后的角点按照从左到右,从上到下排序
  4. 抠出左上角和右下角4个角点组成的块,比较一下谁是黑块
  5. 若黑块在左上角,按排序后的角点顺序输出原图对应的角点;若黑块在右下角,将排序后的角点倒序输出原图对应的角点即可。
#include "libcbdetect/boards_from_corners.h"
#include "libcbdetect/config.h"
#include "libcbdetect/find_corners.h"
#include "libcbdetect/plot_boards.h"
#include "libcbdetect/plot_corners.h"
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;int get_cell_mean_value(Mat img, cv::Point2f p1, cv::Point2f p2, cv::Point2f p3, cv::Point2f p4)
{    vector<Point2f> pts;pts.push_back(p1);pts.push_back(p2);pts.push_back(p3);pts.push_back(p4);Rect rect = boundingRect(pts);rect.x += 2;rect.y += 2;rect.width -= 4;rect.height -= 4;return mean(img(rect)).val[0];
}bool findchessboard_libdetect(Mat img, std::vector<Point2f>& points, const int w, const int h)
{points.clear();cbdetect::Corner corners;std::vector<cbdetect::Board> boards;cbdetect::Params params;params.corner_type = cbdetect::SaddlePoint;//params.score_thr = 0.01;cbdetect::find_corners(img, corners, params);if (corners.p.size() == 0){//LOG_ERROR( "detect chessboard fail, empty corners");printf("detect chessboard fail, empty corners\n");return false;}cbdetect::boards_from_corners(img, corners, boards, params);//cbdetect::plot_boards(img, corners,boards, params);if (boards.size() == 0){//LOG_ERROR( "detect chessboard fail");printf("detect chessboard fail\n");return false;}if (boards.size() > 1){//LOG_ERROR( "detect too many chessboards");printf("detect too many chessboards\n");return false;}int bh = boards[0].idx.size() - 2;int bw = boards[0].idx[0].size() - 2;if ((h != bh || w != bw) && (h != bw || w != bh)){printf("board size faild: %d,%d\n", bw, bh);return false;}points.resize(bh * bw);int count = 0;auto& board = boards[0];for (int i = 1; i < board.idx.size() - 1; ++i) {if (board.idx[i].size() != bw + 2){//LOG_ERROR( "each line has different nums of corners");printf("each line has different nums of corners\n");return false;}for (int j = 1; j < board.idx[i].size() - 1; ++j) {if (board.idx[i][j] < 0) {continue;}if (h == bh){points[count] = (corners.p[board.idx[i][j]]);}else{points[(count % bw) * w + count / bw] = (corners.p[board.idx[i][j]]);}++count;}}//下面代码固定棋盘格角点输出顺序if(points.size()!= w *h) return false;    Mat gray_img;Mat rot_mat;Mat img_rotate;if(img.channels() == 3) cvtColor(img, gray_img, COLOR_BGR2GRAY);else gray_img = img;//将棋盘格旋转至水平float angle;if(points[0].x == points[bw-1].x){angle = 90;}else{angle = atan((points[bw-1].y - points[0].y) / (points[bw-1].x - points[0].x)) * 180 / M_PI;}cv::Point2f center(gray_img.cols / 2.0, gray_img.rows / 2.0);rot_mat = getRotationMatrix2D(center, angle, 1.0);warpAffine(gray_img, img_rotate,rot_mat, gray_img.size());cv::Rect bbox = cv::RotatedRect(center, gray_img.size(), angle).boundingRect();rot_mat.at<double>(0, 2) += bbox.width / 2.0 - center.x;  //x方向的偏移量Txrot_mat.at<double>(1, 2) += bbox.height / 2.0 - center.y; //y方向的偏移量Tyfloat m_dx = bbox.width / 2 - center.x;float m_dy = bbox.height / 2 - center.y;struct _point{Point2f pt;int index;};vector<_point> points_rotate;for (int i=0;i<points.size();++i){const Point2f& pt = points[i];Mat p = Mat::ones(3, 1, CV_64F);p.at<double>(0) = pt.x;p.at<double>(1) = pt.y;Mat pp = rot_mat * p;p.at<double>(0) = pp.at<double>(0) - m_dx;p.at<double>(1) = pp.at<double>(1) - m_dy;_point pt_rotate;pt_rotate.pt = Point2f(p.at<double>(0), p.at<double>(1));pt_rotate.index = i;points_rotate.push_back(pt_rotate);}sort(points_rotate.begin(), points_rotate.end(), [](_point a, _point b) {return a.pt.y < b.pt.y;});for(int i=0;i<h;++i){sort(points_rotate.begin() + i*w, points_rotate.begin() + (i+1)*w, [](_point a, _point b) {return a.pt.x < b.pt.x;});}//判断一下黑色格子在左上角还是右下角int tl_val = get_cell_mean_value(img_rotate, points_rotate[0].pt, points_rotate[1].pt, points_rotate[w].pt, points_rotate[w+1].pt);int br_val = get_cell_mean_value(img_rotate, points_rotate[w * (h -1) - 1].pt, points_rotate[w * (h -1) - 2].pt, points_rotate[w * h - 2].pt, points_rotate[w * h - 1].pt);cout<<tl_val<<" "<<br_val<<endl;for(int i=0;i<points_rotate.size();++i){putText(img_rotate, to_string(i), points_rotate[i].pt, FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255), 1, 8, false);circle(img_rotate, points_rotate[i].pt, 5, Scalar(255), 2, 8, 0);}vector<Point2f> points_sort;for(int i=0;i<points_rotate.size();++i){if(tl_val > br_val){points_sort.push_back(points[points_rotate[w * h - 1 -i].index]);}else{points_sort.push_back(points[points_rotate[i].index]);}}points = points_sort;return true;}

总结

  1. 做实验确认opencv棋盘格检测对于7x6这种一奇一偶的棋盘格检测出的角点顺序不会发生变化,8x6这种不行。
  2. 根据棋盘格起始格子颜色为libcbdetect打补丁,使其也能够固定角点检测顺序。
http://www.cadmedia.cn/news/3456.html

相关文章:

  • 建设企业网站的重要性软文写作范文
  • 关于建设 医院网站的请示seo推广软件下载
  • 纳雍网站建设公司站长之家的作用
  • 怎样设计一个公司网站在线培训网站
  • 建e网全景合成合肥优化排名推广
  • 王爷站住重生嫡女要强嫁免费阅读seo网站诊断文档案例
  • 专业网站建设商城价格网站seo技术
  • 装饰公司东莞网站建设军事网站大全军事网
  • 怎么登录企业网站网销怎么销售的
  • 江门网站建设维护seo服务公司
  • 手机房产网站模板推广宣传方式有哪些
  • 中央政府门口网站建设理念搜索引擎优化员简历
  • 网站空间申请网站怎么营销推广
  • 门户网站案例正规赚佣金的平台
  • 研发管理系统软件搜素引擎优化
  • 深圳找人做网站免费网络推广网站
  • 中小型网站建设与管理windows优化大师卸载
  • 珠海响应式网站制作如何自己开发网站
  • 5个网站建设百度seo报价方法
  • 西安做网站南通公司seo免费
  • 新乡网站建设求职简历网络seo是什么工作
  • 青岛房地产网站建设苏州关键词搜索排名
  • 时时彩网站开发代理代码网站制作
  • 企业网站建设需要准备什么项目营销推广方案
  • 东莞公司有哪些搜索引擎优化的英文缩写
  • 还能电子商务网站建设网站收录批量查询
  • 厦门集美网站建设北京计算机培训机构哪个最好
  • 新余网站网站建设搜索引擎优化的五个方面
  • 服装设计类网站百度seo排名优化软件分类
  • 佛山正规的免费建站百度问答库