Как отобразить поле оптического потока (float) в пиксельные данные (char) для деформации изображения? - PullRequest
3 голосов
/ 16 июня 2011

Я играл с функциями оптического потока в OpenCV и застрял.Я успешно сгенерировал поля и карты оптического потока X и Y, используя метод Farneback, но я не знаю, как применить это к координатам входного изображения, чтобы деформировать изображения.Результирующие поля X и Y имеют 32-битный тип с плавающей запятой (0-1,0), но как это соотносится с координатами входного и выходного изображений?Например, 1.0 чего?Ширина изображения?Разница между ними?

Плюс, я не уверен, как будет выглядеть мой цикл для применения трансформации / деформации.Я сделал много циклов, чтобы изменить цвет, но пиксели всегда остаются в одном и том же месте.Перемещение пикселей вокруг - это новая территория для меня!

Обновление: я получил это на работу, но получающееся изображение грязное:

//make a float copy of 8 bit grayscale source image
IplImage *src_img = cvCreateImage(img_sz, IPL_DEPTH_32F, 1);
cvConvertScale(input_img,src_img,1/255.0); //convert 8 bit to float

//create destination image
IplImage *dst_img = cvCreateImage(img_sz, IPL_DEPTH_32F, 1);

for(y = 0; y < flow->height; y++){

    //grab flow maps for X and Y
    float* vx = (float*)(velx->imageData + velx->widthStep*y);
    float* vy = (float*)(vely->imageData + vely->widthStep*y);

    //coords for source and dest image
    const float *srcpx = (const float*)(src_img->imageData+(src_img->widthStep*y));
    float *dstpx = (float*)(dst_img->imageData+(dst_img->widthStep*y));

    for(x=0; x < flow->width; x++)
    {
        int newx = x+(vx[x]);
        int newy = (int)(vy[x])*flow->width;
        dstpx[newx+newy] = srcpx[x];
    }
}

Я не мог заставить это работатьНа выходе был просто искаженный шум:

cvRemap(src_img,dst_img,velx,vely,CV_INTER_CUBIC,cvScalarAll(0));

Ответы [ 2 ]

5 голосов
/ 16 июня 2011

Векторы потока являются значениями скорости.Если пиксель на изображении 1 в позиции (x, y) имеет вектор потока (vx, vy), он оценивается как находящийся в позиции (x+vx, y+vy) (поэтому значения на самом деле не находятся в диапазоне [0, 1] - они могут быть больше иотрицательный тоже).Самый простой способ сделать деформацию - создать изображения с плавающей запятой с этими значениями (x+vx для направления x, аналогичного для y), а затем использовать cv::remap.

1 голос
/ 24 марта 2017

Использование OpenCV

https://github.com/opencv/opencv/blob/master/samples/python/opt_flow.py

def warp_flow(img, flow):
    h, w = flow.shape[:2]
    flow = -flow
    flow[:,:,0] += np.arange(w)
    flow[:,:,1] += np.arange(h)[:,np.newaxis]
    res = cv2.remap(img, flow, None, cv2.INTER_LINEAR)
    return res

Sample Result

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