opencv图像坐标点检测出来后,怎么进行点与点间实际距离与角度换算?

berlinpand 2017-09-14 10:41:18
进行了角点检测把图像上一条线上的角点检测出来了,但是输出的是像素坐标点,想问问如何进行点与点像素距离到实际距离的转换,和点与点连线间直线夹角的计算,算法是了解一些,可是实现不太懂,请大家赐教
...全文
1853 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
一只酸奶瓶 2019-11-16
  • 打赏
  • 举报
回复
有进展了咩?opecv下的坐标是从左上角开始的 这样如何求解点对的距离哇
李吉吉吉吉 2019-11-11
  • 打赏
  • 举报
回复
最近有啥进展吗?我最近也在弄坐标问题
berlinpand 2017-09-15
  • 打赏
  • 举报
回复
引用 2 楼 m0_37901643 的回复:
你说的实际坐标,实际距离是指现实中地理位置空间的坐标和距离还是相对于客户区现实界面的坐标距离啊?
其实我想知道的是单幅(图像中的距离和现实中比例是1:1的)图像上测出两个像素点的像素距离后如何换成cm等长度单位,不知道这样说您了解了吗。
沐阳2100 2017-09-15
  • 打赏
  • 举报
回复
你说的实际坐标,实际距离是指现实中地理位置空间的坐标和距离还是相对于客户区现实界面的坐标距离啊?
赵4老师 2017-09-14
  • 打赏
  • 举报
回复 1
仅供参考:
double angle( Point pt1, Point pt2, Point pt0 ) {// finds a cosine of angle between vectors from pt0->pt1 and from pt0->pt2
    double dx1 = pt1.x - pt0.x;
    double dy1 = pt1.y - pt0.y;
    double dx2 = pt2.x - pt0.x;
    double dy2 = pt2.y - pt0.y;
    double ratio;//边长平方的比
    ratio=(dx1*dx1+dy1*dy1)/(dx2*dx2+dy2*dy2);
    if (ratio<0.8 || 1.2<ratio) {//根据边长平方的比过小或过大提前淘汰这个四边形,如果淘汰过多,调整此比例数字
//      Log("ratio\n");
        return 1.0;//根据边长平方的比过小或过大提前淘汰这个四边形
    }
    return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}
void findSquares( const Mat& gray0, vector<vector<Point> >& squares ) {// returns sequence of squares detected on the gray0. the sequence is stored in the specified memory storage
    squares.clear();

    Mat pyr,gray1,timg;

    // down-scale and upscale the gray0 to filter out the noise
    pyrDown(gray0, pyr, Size(gray0.cols/2, gray0.rows/2));
    pyrUp(pyr, timg, gray0.size());
    vector<vector<Point> > contours;

    // try several threshold levels
    for (int l = 0; l < N; l++ ) {
        // hack: use Canny instead of zero threshold level.
        // Canny helps to catch squares with gradient shading
//      if (l == 0 ) {//可试试不对l==0做特殊处理是否能在不影响判断正方形的前提下加速判断过程
//          // apply Canny. Take the upper threshold from slider
//          // and set the lower to 0 (which forces edges merging)
//          Canny(timg, gray1, 0, thresh, 5);
//          // dilate canny output to remove potential
//          // holes between edge segments
//          dilate(gray1, gray1, Mat(), Point(-1,-1));
//      } else {
            // apply threshold if l!=0:
            //     tgray(x,y) = gray1(x,y) < (l+1)*255/N ? 255 : 0
            gray1 = timg >= (l+1)*255/N;
//      }

        // find contours and store them all as a list
        findContours(gray1, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

        vector<Point> approx;

        // test each contour
        for (size_t i = 0; i < contours.size(); i++ ) {
            // approximate contour with accuracy proportional
            // to the contour perimeter
            approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);//0.02为将毛边拉直的系数,如果对毛边正方形漏检,可试试调大

            // square contours should have 4 vertices after approximation
            // relatively large area (to filter out noisy contours)
            // and be convex.
            // Note: absolute value of an area is used because
            // area may be positive or negative - in accordance with the
            // contour orientation
            if (approx.size() == 4 && isContourConvex(Mat(approx))) {
                double area;
                area=fabs(contourArea(Mat(approx)));
                if (4000.0<area && area<30000.0) {//当正方形面积在此范围内……,如果有因面积过大或过小漏检正方形问题,调整此范围。
//                  printf("area=%lg\n",area);
                    double maxCosine = 0.0;

                    for (int j = 2; j < 5; j++ ) {
                        // find the maximum cosine of the angle between joint edges
                        double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
                        maxCosine = MAX(maxCosine, cosine);
                        if (maxCosine==1.0) break;// //边长比超过设定范围
                    }

                    // if cosines of all angles are small
                    // (all angles are ~90 degree) then write quandrange
                    // vertices to resultant sequence
                    if (maxCosine < 0.1 ) {//四个角和直角相比的最大误差,可根据实际情况略作调整,越小越严格
                        squares.push_back(approx);
                        return;//检测到一个合格的正方形就返回
//                  } else {
//                      Log("Cosine>=0.1\n");
                    }
                }
            }
        }
    }
}
一、主要内容:OpenCV能够实现强大丰富的图像处理,但是它缺少一个能够支持它运行的界面。Csharp经过多年的发展,得益于它的“所见及所得”能力,非常方便编写界面。这两者如果能够“双剑合璧”,将有效帮助实际工作产出。本课着重推荐GOCW采用“Csharp基于CLR直接调用Opencv编写的算法库”方法,能够将最新的OpenCV技术引入进来,同时保证生成程序的最小化。    为了进一步说明Csharp和OpenCV的结合使用,首先一个较为完整的基于winform实现答题卡识别的例子,相比较之前的实现,本次进一步贴近生产实际、内涵丰富,对算法也进行了进一步提炼。同时我们对WPF下对OpenCV函数的调用、OpenCV.js的调用进行相关教授。       二、课程结构1、 EmguCV、OpenCVSharp和GOCW之间进行比较(方便代码编写、能够融入最新的算法、速度有保障、方便调试找错、拒绝黑箱化);2、视频采集模块的构建,视频采集和图像处理之间的关系;3、视频采集专用的SDK和“陪练”系统的介绍;4、在视频增强类项目中和图像处理项目中,算法的选择;5、Csharp界面设计、图片的存储和其他构建设计;6、较为完整的答题卡识别例子,兼顾界面设计和算法分析;8、WPF基于GOCW也同样可以基于GOCW实现算法调用;webForm虽然也可以通过类似方法调用,但是OpenCV.JS的方法更现代高效。9、关于软件部署的相关要和窍门。       三、知识要:1、基本环境构建和程序框架;2、CLR基本原理和应用方法;3、接入、采集、模拟输入;4、图像处理,通过构建循环采集图片;5、增强和实时处理;6、基于投影等技术的答题卡识别算法;7、存储、转换;8、部署交付。        课程能够帮助你掌握Csharp调用Opencv的基本方法,获得相应框架代码和指导;从而进一步提升实现“基于图像处理”的解决方案能力。  

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧