使用cv :: goodFeaturesToTrack拟合线

时间:2017-10-17 09:45:29

标签: c++ opencv computer-vision

我有角点,我试图使用cv :: fitline来拟合这些线条 但是我得到了图片中显示的来自原点0,0的线条。

我还有投影矩阵和视图矩阵以及相机间的参数,如果这会有帮助

我试图计算图中方框的音量 enter image description here

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


  Mat src, src_copy, edges, dst;
  src = imread( "freezeFrame__1508152029892.png", 0 );

  src_copy = src.clone();

  GaussianBlur( src, edges, Size( 5, 5 ), 1.5, 1.5 );

  erode( edges, edges, Mat() );// these lines may need to be optimized 
  dilate( edges, edges, Mat() );
  dilate( edges, edges, Mat() );
  erode( edges, edges, Mat() );

  Canny( edges, dst, 1, 10, 3 ); // canny parameters may need to be optimized 
  imshow( "canny", dst );

  std::vector< cv::Point2f > corners;

  // maxCorners – The maximum number of corners to return. If there are more corners
  // than that will be found, the strongest of them will be returned
  int maxCorners = 10;

  // qualityLevel – Characterizes the minimal accepted quality of image corners;
  // the value of the parameter is multiplied by the by the best corner quality
  // measure (which is the min eigenvalue, see cornerMinEigenVal() ,
  // or the Harris function response, see cornerHarris() ).
  // The corners, which quality measure is less than the product, will be rejected.
  // For example, if the best corner has the quality measure = 1500,
  // and the qualityLevel=0.01 , then all the corners which quality measure is
  // less than 15 will be rejected.
  double qualityLevel = 0.01;

  // minDistance – The minimum possible Euclidean distance between the returned corners
  double minDistance = 20.;

  // mask – The optional region of interest. If the image is not empty (then it
  // needs to have the type CV_8UC1 and the same size as image ), it will specify
  // the region in which the corners are detected
  cv::Mat mask;

  // blockSize – Size of the averaging block for computing derivative covariation
  // matrix over each pixel neighborhood, see cornerEigenValsAndVecs()
  int blockSize = 3;

  // useHarrisDetector – Indicates, whether to use operator or cornerMinEigenVal()
  bool useHarrisDetector = false;

  // k – Free parameter of Harris detector
  double k = 0.04;

  cv::goodFeaturesToTrack( src, corners, maxCorners, qualityLevel, minDistance, mask, blockSize, useHarrisDetector, k );



  std::vector<Vec4f> lines;
  for ( int i = 0; i < corners.size(); i++ )
  {

    cv::Point2f pt = corners[i];
    for ( int j = i + 1; j < corners.size(); j++ )
    {

      cv::Point2f endpt = corners[j];

      std::vector<cv::Point2f> points;
      points.push_back( pt );
      points.push_back( endpt );


      Vec4f line;
      cv::fitLine( points, line, CV_DIST_L2, 0, 0.01, 0.01 );
      lines.push_back( line );
    }
  }

  for ( size_t i = 0; i < lines.size(); i++ )
  {

    cv::Vec4i v = lines[i];
    line( src, Point( v[0], v[1] ), Point( v[2], v[3] ), Scalar( 0, 0, 255 ), 3, 4 );
  }


  for ( size_t i = 0; i < corners.size(); i++ )
  {
    cv::circle( src, corners[i], 10, cv::Scalar( 255. ), -1 );
  }

  imshow( "line src", src );
  imshow("line dest", edges );
  cv::waitKey( 0 );


  return 0;
}

1 个答案:

答案 0 :(得分:2)

阅读文档:

  

line - 输出行参数。在2D拟合的情况下,它应该是4个元素的向量(如Vec4f) - (vx,vy,x0,y0),其中(vx,vy)是与线共线的归一化向量,(x0,y0)是就行了。在3D拟合的情况下,它应该是6个元素的向量(如Vec6f) - (vx,vy,vz,x0,y0,z0),其中(vx,vy,vz)是与线共线的归一化向量和(x0,y0,z0)是该行的一个点。

所以你必须通过以下方式划清界限:

Point2f linePoint = Point2f( v[2], v[3] );
Point2f lineDirection = Point2f( v[0], v[1]);
float factor = 50; // if lineDirection is already length 1, you could choose factor to be the desired line length
line( src, linePoint  , linePoint+ factor*lineDirection + , Scalar( 0, 0, 255 ), 3, 4 );`