Параллельный расчет точки пересечения векторов оптического потока - PullRequest
0 голосов
/ 19 декабря 2018

Я сталкиваюсь с какой-то легкой и не такой легкой проблемой, в зависимости от того, как на это смотреть.Чтобы избежать недоразумений, вызванных моим плохим английским языком, я быстро нарисовал, чтобы объяснить ситуацию:

проблема визуализирована

Меня интересует пунктирвекторы на изображениях, которые имеют потенциальную точку пересечения, отмеченную зеленым цветом на рисунке, ЕСЛИ движение продолжается в этом направлении.Интересная область iv помечена синим между двумя кружками в нижней части экрана, поэтому меня интересуют все векторы, точки пересечения которых попадают между двумя синими точками внизу.Любой другой вектор, который имеет пересечение с другой областью границы на экране, мне не интересен, поэтому я не рассчитываю время вычисления для них.У меня есть работающий код, который работает, но ужасно медленный, и поэтому его нельзя использовать.Короче говоря, я просто получаю 2 точки из плотного оптического потока, вычисляю наклон линии, который определяется этими двумя точками, затем я устанавливаю уравнение линии (y = m * x + b) равным нулю и решаю после точки пересеченияб.Это происходит внутри функции

Вот мой пример кода, который я пытаюсь оптимизировать.

cv::Ptr<cv::DenseOpticalFlow> STD_OF = cv::optflow::createOptFlow_SparseToDense();

void processDOF (bool & blnFirstFrame, // флаг bool, который является ложным со 2-го кадра в видеоподаче cv :: Mat & mask, // маска, которая имеет тот же размер, что и изображения в градациях серого //, которыеимеет эфир 0 или 255 для пометки моего окна интереса в изображении int iThreshold, // 255 фильтров cv :: Mat & mPreviousGrayscaleImageForOpticalFlow, // предыдущее изображение в градациях серого cv :: Mat & mGrayscaleImageForOpticalFlow, // текущее изображение в градациях серого cv :: Mat & mDenseOpticalFlowImage //изображение, в котором хранятся данные оптического потока) {cv :: Mat cflowmap;// рисуем изображение, на котором отображается оптический поток cv :: UMat umDenseOpticalFlowImage;// изображение, в котором хранятся данные оптического потока cv :: Point pIntersection;// точка пересечения в синей области int step = 5;// оптический поток просматривается в каждой 5-й точке по оси x и по оси y изображения

//calculate dense optical flow
if  (
        ( blnFirstFrame == false ) &&
        ( mPreviousGrayscaleImageForOpticalFlow.empty() == false ) &&
        ( mGrayscaleImageForOpticalFlow.empty() == false )              //current grayscale image
){

    STD_OF->calc    (
                        mPreviousGrayscaleImageForOpticalFlow,
                        mGrayscaleImageForOpticalFlow,
                        umDenseOpticalFlowImage
                    );
    umDenseOpticalFlowImage.copyTo(mDenseOpticalFlowImage);
    mGrayscaleImageForOpticalFlow.copyTo(cflowmap);

    //calculate intersections
    for(int y = 0; y < cflowmap.rows; y += step)
            for(int x = 0; x < cflowmap.cols; x += step)
            {
                if (mask.at<int>(y, x) >= iThreshold){          //check if the observed poit is within the mask

                    const cv::Point2f& offset = mDenseOpticalFlowImage.at<cv::Point2f>(y, x);   //offset where the point of the,
                                                                                                //optical flow vector is pointing to
                    //calculate intersection point
                    pIntersection = calculate_intersection  (
                                                cv::Point(x,y),                     //start point of observed optical flow vector
                                                cv::Point(cvRound(x+offset.x), cvRound(y+offset.y)),    //endpoint of observed optical flow vector
                                                getBorderPointLeft(),               //blue boder point left in the drawing
                                                getBorderPointright()               //blue boder point right in the drawing
                                            );
                    evaluationIntersectionPoint(pIntersection);     //put the point within a std::vector<cv::Point> for further evaluation
                    //draw the interesting vectors
                    cv::line(cflowmap, cv::Point(x,y), cv::Point(cvRound(x+offset.x), cvRound(y+offset.y)),
                         cv::Scalar(0,255,00));
                    cv::circle(cflowmap, cv::Point(x,y), 2, cv::Scalar(0,255,0), -1);
                }
            }
}

Моя проблема в том, что я не могу обернуть голову вокруг того, как я мог бы параллельны части внутривложенные в циклы :(. Результаты очень плохие, я получаю 1FPS, цель 8-10FPS0

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