zoukankan      html  css  js  c++  java
  • OpenCV学习(34) 点到轮廓的距离

          在OpenCV中,可以很方便的计算一个像素点到轮廓的距离,计算距离的函数为:

    double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)

    Parameters:

    • contour – 输入参数轮廓。
    • pt – 测试的点。
    • measureDist – 如果为false的话,则函数计算符号,在轮廓外部在为-1,在轮廓内为1,在轮廓上,则为0。如果为ture,则计算实际的像素符号距离,在轮廓外的点像素距离为负值,在内的点,像素距离为正值。

    下面的是计算一副图像中各个像素到轮廓距离的代码:

    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    using namespace cv;
    using namespace std;

    using namespace cv;
    using namespace std;

    int main( int argc, char** argv )
    {
    //创建一副图像
    const int r = 100;
    Mat src = Mat::zeros( Size( 4*r, 4*r ), CV_8UC1 );

    //创建一个轮廓序列
    vector<Point2f> vert(6);

    vert[0] = Point( 1.5*r, 1.34*r );
    vert[1] = Point( 1*r, 2*r );
    vert[2] = Point( 1.5*r, 2.866*r );
    vert[3] = Point( 2.5*r, 2.866*r );
    vert[4] = Point( 3*r, 2*r );
    vert[5] = Point( 2.5*r, 1.34*r );

    //画轮廓
    for( int j = 0; j < 6; j++ )
    { line( src, vert[j], vert[(j+1)%6], Scalar( 255 ), 3, 8 ); }

    //得到轮廓
    vector<vector<Point> > contours; vector<Vec4i> hierarchy;
    Mat src_copy = src.clone();

    findContours( src_copy, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);

    //计算顶点到轮廓的距离
    Mat raw_dist( src.size(), CV_32FC1 );

    for( int j = 0; j < src.rows; j++ )
    {
    for( int i = 0; i < src.cols; i++ )
    {
    raw_dist.at<float>(j,i) = pointPolygonTest( contours[0], Point2f(i,j), true ); }
    }

    double minVal; double maxVal;
    minMaxLoc( raw_dist, &minVal, &maxVal, 0, 0, Mat() );
    minVal = abs(minVal); maxVal = abs(maxVal);

    //用户型化的方式显示距离
    Mat drawing = Mat::zeros( src.size(), CV_8UC3 );

    for( int j = 0; j < src.rows; j++ )
    { for( int i = 0; i < src.cols; i++ )
    {
    //在外部
    if( raw_dist.at<float>(j,i) < 0 )
    { drawing.at<Vec3b>(j,i)[0] = 255 - (int) abs(raw_dist.at<float>(j,i))*255/minVal; }
    //在内部
    else if( raw_dist.at<float>(j,i) > 0 )
    { drawing.at<Vec3b>(j,i)[2] = 255 - (int) raw_dist.at<float>(j,i)*255/maxVal; }
    else
    // 在边上
    { drawing.at<Vec3b>(j,i)[0] = 255; drawing.at<Vec3b>(j,i)[1] = 255; drawing.at<Vec3b>(j,i)[2] = 255; }
    }
    }

    namedWindow( "image", CV_WINDOW_AUTOSIZE );
    imshow( "image", src );
    namedWindow( "Distance", CV_WINDOW_AUTOSIZE );
    imshow( "Distance", drawing );

    waitKey(0);
    return(0);
    }

    对于轮廓外的点,越是蓝色,则距离轮廓越近,轮廓内的点,越是红色距离轮廓越近,轮廓上点距离为0,用白色表示。

    程序执行后效果:

    imageimage

    程序代码:工程FirstOpenCV30

  • 相关阅读:
    Extjs知识点汇总
    div设置滚动条内容任然显示不全
    win7 系统安装 docker
    docker常用命令
    cargo实现自动化部署远程jetty容器(非安全模式)
    win7 失去焦点解决方案
    jeecms 评论相关
    jeecms v8 网站访问量配置
    python——进程池
    python多进程编程常用到的方法
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/3427598.html
Copyright © 2011-2022 走看看