Нарисуйте подогнанную линию (OpenCV) - PullRequest
10 голосов
/ 01 мая 2010

Я использую OpenCV, чтобы уместить линию из набора точек, используя cvFitLine()

cvFitLine() возвращает нормализованный вектор, который является линейным по отношению к линии и точке на линии. Подробнее здесь

Используя эту информацию, как я могу получить уравнение прямой, чтобы я мог нарисовать линию?

Ответы [ 5 ]

9 голосов
/ 04 мая 2010

Просто нарисуйте большую линию вместо решения для границ. например:

cv.Line(img, (x0-m*vx[0], y0-m*vy[0]), (x0+m*vx[0], y0+m*vy[0]), (0,0,0))

сделает это например .. для м достаточно большой:)

9 голосов
/ 02 мая 2010

Если cvFitLine() возвращает нормализованный вектор (vx,vy) и точку (x0,y0), то уравнение линии будет

(x, y) = (x0, y0) + t * (vx, vy)

, где t начинается с & минус; & infin; до + & бесконечность.

Это то, что вы просили, но, вероятно, не сразу поможет нарисовать линию. Вы хотели бы обрезать это или к границам экрана, или возможно ограничивающему прямоугольнику оригинального набора точек. Чтобы обрезать линию в прямоугольнике, просто найдите значения t, где линия пересекает границу прямоугольника.

4 голосов
/ 24 марта 2012

Я использовал там стратегию, похожую на Karpathy, но использовал дополнительную функцию. Как видите, я использую cvClipLine, чтобы обрезать линию до размера изображения, что не является необходимым, но добавляет немного привлекательности.

Также здесь указан множитель как theMult = max (img-> height, img-> width), поэтому мы не получаем числа, которые могут однажды переполниться или что-то в этом роде.

void drawLine(IplImage * img, float line[4], int thickness,CvScalar color)
{
    double theMult = max(img->height,img->width);
    // calculate start point
    CvPoint startPoint;
    startPoint.x = line[2]- theMult*line[0];// x0
    startPoint.y = line[3] - theMult*line[1];// y0
    // calculate end point
    CvPoint endPoint;
    endPoint.x = line[2]+ theMult*line[0];//x[1]
    endPoint.y = line[3] + theMult*line[1];//y[1]

    // draw overlay of bottom lines on image
    cvClipLine(cvGetSize(img), &startPoint, &endPoint);
    cvLine(img, startPoint, endPoint, color, thickness, 8, 0);
}
1 голос
/ 01 июля 2018

Добавление к @brainjam ответу:

Чтобы закрепить ограничивающий прямоугольник исходного набора точек:

// std::vector<Point2i> points = ...

//lineParams: [vx,vy, x0,y0]: (normalized vector, point on our contour)
Vec4f lineParams; fitLine(points, lineParams, CV_DIST_L2, 0, 0.01, 0.01);

// derive the bounding xs of points
decltype(points)::iterator minXP, maxXP;
std::tie(minXP, maxXP) = std::minmax_element(points.begin(), points.end(), [](const Point2i& p1, const Point2i& p2){ return p1.x < p2.x; });

// derive y coords of fitted line
float m = lineParams[1] / lineParams[0];
int y1 = ((minXP->x - lineParams[2]) * m) + lineParams[3];
int y2 = ((maxXP->x - lineParams[2]) * m) + lineParams[3];
line(clearTarget, Point(minXP->x, y1), Point(maxXP->x, y2), Scalar(255, 255, 255), 2);

Чтобы обрезать границы изображения целиком, замените minXP->x на 0 и maxXP->x на image.cols - 1, на которые изначально был дан ответ https://stackoverflow.com/a/14192660/2380455

0 голосов
/ 24 февраля 2014

мы используем "Vec4f fitedLine;" для встроенной линии в fitLine у ​​нас есть 4 параметра если мы рассмотрим линейное отношение az ниже: Y - Y0 = M (X - X0)

у нас есть Y0 = FitedLine [3]; X0 = FitedLine [2]; m = FitedLine [1] / FitedLine [0];

поэтому у нас есть уравнение Линии, на котором мы можем найти другие точки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...