diff --git a/demo.py b/demo.py index 30f09d4..b341954 100644 --- a/demo.py +++ b/demo.py @@ -8,6 +8,7 @@ from PIL import Image import time import argparse +import os import pyflow parser = argparse.ArgumentParser( @@ -17,31 +18,34 @@ help='Visualize (i.e. save) output of flow.') args = parser.parse_args() -im1 = np.array(Image.open('examples/car1.jpg')) -im2 = np.array(Image.open('examples/car2.jpg')) +examples_dir = "./examples" +im1 = np.array(Image.open(os.path.join(examples_dir, 'img1.jpg'))) +im2 = np.array(Image.open(os.path.join(examples_dir, 'img2.jpg'))) im1 = im1.astype(float) / 255. im2 = im2.astype(float) / 255. # Flow Options: -alpha = 0.012 -ratio = 0.75 -minWidth = 20 -nOuterFPIterations = 7 -nInnerFPIterations = 1 -nSORIterations = 30 +alpha = 0.012 # default 0.012 +ratio = 0.75 # default 0.75 +minWidth = 20 # default 20 +nOuterFPIterations = 7 # default 7 +nInnerFPIterations = 1 # default 1 +nSORIterations = 30 # default 30 colType = 0 # 0 or default:RGB, 1:GRAY (but pass gray image with shape (h,w,1)) +threshold = 0.000005 s = time.time() u, v, im2W = pyflow.coarse2fine_flow( im1, im2, alpha, ratio, minWidth, nOuterFPIterations, nInnerFPIterations, - nSORIterations, colType, verbose = True) + nSORIterations, colType, verbose = True, threshold = threshold) e = time.time() print('Time Taken: %.2f seconds for image of size (%d, %d, %d)' % ( e - s, im1.shape[0], im1.shape[1], im1.shape[2])) flow = np.concatenate((u[..., None], v[..., None]), axis=2) -np.save('examples/outFlow.npy', flow) +np.save(os.path.join(examples_dir, 'outFlow.npy'), flow) -if args.viz: +always_viz = True +if args.viz or always_viz: import cv2 hsv = np.zeros(im1.shape, dtype=np.uint8) hsv[:, :, 0] = 255 @@ -50,5 +54,5 @@ hsv[..., 0] = ang * 180 / np.pi / 2 hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX) rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) - cv2.imwrite('examples/outFlow_new.png', rgb) - cv2.imwrite('examples/car2Warped_new.jpg', im2W[:, :, ::-1] * 255) + cv2.imwrite(os.path.join(examples_dir, 'outFlow_new.png'), rgb) + cv2.imwrite(os.path.join(examples_dir, 'img2Warped_new.jpg'), im2W[:, :, ::-1] * 255) diff --git a/pyflow.pyx b/pyflow.pyx index a68037e..9dec734 100644 --- a/pyflow.pyx +++ b/pyflow.pyx @@ -15,14 +15,15 @@ cdef extern from "src/Coarse2FineFlowWrapper.h": double alpha, double ratio, int minWidth, int nOuterFPIterations, int nInnerFPIterations, int nSORIterations, int colType, - int h, int w, int c, bool verbose); + int h, int w, int c, bool verbose, double threshold); def coarse2fine_flow(np.ndarray[double, ndim=3, mode="c"] Im1 not None, np.ndarray[double, ndim=3, mode="c"] Im2 not None, double alpha=1, double ratio=0.5, int minWidth=40, int nOuterFPIterations=3, int nInnerFPIterations=1, int nSORIterations=20, int colType=0, - bool verbose = False): + bool verbose = False, + double threshold = 0.0): """ Input Format: double * vx, double * vy, double * warpI2, @@ -50,5 +51,6 @@ def coarse2fine_flow(np.ndarray[double, ndim=3, mode="c"] Im1 not None, alpha, ratio, minWidth, nOuterFPIterations, nInnerFPIterations, nSORIterations, colType, h, w, c, - verbose) + verbose, + threshold) return vx, vy, warpI2 diff --git a/src/Coarse2FineFlowWrapper.cpp b/src/Coarse2FineFlowWrapper.cpp index 7f64dfe..c255a9e 100644 --- a/src/Coarse2FineFlowWrapper.cpp +++ b/src/Coarse2FineFlowWrapper.cpp @@ -15,7 +15,7 @@ void Coarse2FineFlowWrapper(double * vx, double * vy, double * warpI2, int nOuterFPIterations, int nInnerFPIterations, int nSORIterations, int colType, int h, int w, int c, - bool verbose) { + bool verbose, double threshold) { DImage ImFormatted1, ImFormatted2; DImage vxFormatted, vyFormatted, warpI2Formatted; @@ -33,7 +33,7 @@ void Coarse2FineFlowWrapper(double * vx, double * vy, double * warpI2, alpha, ratio, minWidth, nOuterFPIterations, nInnerFPIterations, nSORIterations, - verbose); + verbose, threshold); // copy formatted output to a contiguous memory to be returned memcpy(vx, vxFormatted.pData, h * w * sizeof(double)); diff --git a/src/Coarse2FineFlowWrapper.h b/src/Coarse2FineFlowWrapper.h index 4932fd7..2b2703e 100644 --- a/src/Coarse2FineFlowWrapper.h +++ b/src/Coarse2FineFlowWrapper.h @@ -11,4 +11,4 @@ extern void Coarse2FineFlowWrapper(double * vx, double * vy, double * warpI2, int nOuterFPIterations, int nInnerFPIterations, int nSORIterations, int colType, int h, int w, int c, - bool verbose); + bool verbose, double threshold); diff --git a/src/OpticalFlow.cpp b/src/OpticalFlow.cpp index ed68a38..e00a969 100644 --- a/src/OpticalFlow.cpp +++ b/src/OpticalFlow.cpp @@ -5,6 +5,7 @@ #include "ImageProcessing.h" #include "GaussianPyramid.h" #include +#include #include using namespace std; @@ -195,7 +196,7 @@ void OpticalFlow::genInImageMask(DImage &mask, const DImage &flow,int interval) //-------------------------------------------------------------------------------------------------------- void OpticalFlow::SmoothFlowSOR(const DImage &Im1, const DImage &Im2, DImage &warpIm2, DImage &u, DImage &v, double alpha, int nOuterFPIterations, int nInnerFPIterations, int nSORIterations, - bool verbose) + bool verbose, double threshold) { DImage mask,imdx,imdy,imdt; int imWidth,imHeight,nChannels,nPixels; @@ -380,6 +381,8 @@ void OpticalFlow::SmoothFlowSOR(const DImage &Im1, const DImage &Im2, DImage &wa du.reset(); dv.reset(); + + bool use_converge_est = (threshold > 0.0); for(int k = 0; k& para, bool verbose = false); @@ -46,7 +46,7 @@ class OpticalFlow // function of coarse to fine optical flow static void Coarse2FineFlow(DImage& vx,DImage& vy,DImage &warpI2,const DImage& Im1,const DImage& Im2,double alpha,double ratio,int minWidth, - int nOuterFPIterations,int nInnerFPIterations,int nCGIterations, bool verbose); + int nOuterFPIterations,int nInnerFPIterations,int nCGIterations, bool verbose, double threshold = 0.0); static void Coarse2FineFlowLevel(DImage& vx,DImage& vy,DImage &warpI2,const DImage& Im1,const DImage& Im2,double alpha,double ratio,int nLevels, int nOuterFPIterations,int nInnerFPIterations,int nCGIterations, bool verbose);