我有角点,我试图使用cv :: fitline来拟合这些线条 但是我得到了图片中显示的来自原点0,0的线条。
我还有投影矩阵和视图矩阵以及相机间的参数,如果这会有帮助
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;
}
答案 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 );`