Added naive blockmatching algorithm (just to get acquainted with the code base, this algo shouldn't be considered seriously).
Also, added boilerplate for pcaflow.pull/710/head
parent
46dd2631d6
commit
fc00397160
4 changed files with 300 additions and 1 deletions
@ -0,0 +1,143 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace optflow |
||||
{ |
||||
|
||||
class OpticalFlowBlockMatching : public DenseOpticalFlow |
||||
{ |
||||
protected: |
||||
int windowSize; |
||||
int blockSize; |
||||
|
||||
inline float submatrixAbsDiff( int x0, int y0, const Mat &I0, int x1, int y1, const Mat &I1 ) const; |
||||
|
||||
public: |
||||
OpticalFlowBlockMatching() : windowSize( 3 ), blockSize( 8 ){}; |
||||
|
||||
void calc( InputArray I0, InputArray I1, InputOutputArray flow ); |
||||
void collectGarbage(); |
||||
}; |
||||
|
||||
inline float OpticalFlowBlockMatching::submatrixAbsDiff( int x0, int y0, const Mat &I0, int x1, int y1, |
||||
const Mat &I1 ) const |
||||
{ |
||||
float error = 0; |
||||
const Size size = I0.size(); |
||||
for ( int i = -windowSize; i <= windowSize; ++i ) |
||||
{ |
||||
if ( i + y0 < 0 || i + y0 >= size.height || i + y1 < 0 || i + y1 >= size.height ) |
||||
{ |
||||
error += 1; |
||||
continue; |
||||
} |
||||
const Vec3f *I0X = I0.ptr<Vec3f>( i + y0 ); |
||||
const Vec3f *I1X = I1.ptr<Vec3f>( i + y1 ); |
||||
for ( int j = -windowSize; j <= windowSize; ++j ) |
||||
{ |
||||
if ( j + x0 < 0 || j + x0 >= size.width || j + x1 < 0 || j + x1 >= size.width ) |
||||
{ |
||||
error += 1; |
||||
continue; |
||||
} |
||||
const Vec3f diff = I0X[j + x0] - I1X[j + x1]; |
||||
error += abs( diff[0] ); |
||||
error += abs( diff[1] ); |
||||
error += abs( diff[2] ); |
||||
} |
||||
} |
||||
return error; |
||||
} |
||||
|
||||
void OpticalFlowBlockMatching::calc( InputArray I0, InputArray I1, InputOutputArray flow_out ) |
||||
{ |
||||
CV_Assert( I0.channels() == 3 ); |
||||
CV_Assert( I1.channels() == 3 ); |
||||
Size size = I0.size(); |
||||
CV_Assert( size == I1.size() ); |
||||
|
||||
flow_out.create( size, CV_32FC2 ); |
||||
Mat flow = flow_out.getMat(); |
||||
Mat from = I0.getMat(); |
||||
Mat to = I1.getMat(); |
||||
|
||||
from.convertTo( from, CV_32FC3, 1.0 / 255.0 ); |
||||
to.convertTo( to, CV_32FC3, 1.0 / 255.0 ); |
||||
|
||||
const float distNormalize = blockSize * sqrt( 2 ); |
||||
|
||||
for ( int y0 = 0; y0 < size.height; ++y0 ) |
||||
{ |
||||
Vec2f *flowX = flow.ptr<Vec2f>( y0 ); |
||||
const int yEnd = std::min( size.height - 1, y0 + blockSize ); |
||||
|
||||
for ( int x0 = 0; x0 < size.width; ++x0 ) |
||||
{ |
||||
float minDiff = 1e10; |
||||
Vec2f du( 0, 0 ); |
||||
const int xEnd = std::min( size.width - 1, x0 + blockSize ); |
||||
for ( int y1 = std::max( 0, y0 - blockSize ); y1 <= yEnd; ++y1 ) |
||||
for ( int x1 = std::max( 0, x0 - blockSize ); x1 <= xEnd; ++x1 ) |
||||
{ |
||||
const float distance = sqrt( ( x0 - x1 ) * ( x0 - x1 ) + ( y0 - y1 ) * ( y0 - y1 ) ) / distNormalize; |
||||
const float kernel = 1.0 + 0.5 * distance; |
||||
const float diff = kernel * submatrixAbsDiff( x0, y0, from, x1, y1, to ); |
||||
if ( diff < minDiff ) |
||||
{ |
||||
minDiff = diff; |
||||
du = Vec2f( ( x1 - x0 ), ( y1 - y0 ) ); |
||||
} |
||||
} |
||||
flowX[x0] = du; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void OpticalFlowBlockMatching::collectGarbage() {} |
||||
|
||||
Ptr<DenseOpticalFlow> createOptFlow_BlockMatching() { return makePtr<OpticalFlowBlockMatching>(); } |
||||
} |
||||
} |
@ -0,0 +1,148 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace optflow |
||||
{ |
||||
|
||||
class OpticalFlowPCAFlow : public DenseOpticalFlow |
||||
{ |
||||
protected: |
||||
float sparseRate; |
||||
|
||||
public: |
||||
OpticalFlowPCAFlow() : sparseRate( 0.02 ){}; |
||||
|
||||
void calc( InputArray I0, InputArray I1, InputOutputArray flow ); |
||||
void collectGarbage(); |
||||
|
||||
private: |
||||
void findSparseFeatures( Mat &from, Mat &to, std::vector<Point2f> &features, |
||||
std::vector<Point2f> &predictedFeatures ); |
||||
}; |
||||
|
||||
void OpticalFlowPCAFlow::findSparseFeatures( Mat &from, Mat &to, std::vector<Point2f> &features, |
||||
std::vector<Point2f> &predictedFeatures ) |
||||
{ |
||||
std::vector<uchar> predictedStatus; |
||||
std::vector<float> predictedError; |
||||
calcOpticalFlowPyrLK( from, to, features, predictedFeatures, predictedStatus, predictedError ); |
||||
|
||||
size_t j = 0; |
||||
for ( size_t i = 0; i < features.size(); ++i ) |
||||
{ |
||||
if ( predictedStatus[i] ) |
||||
{ |
||||
features[j] = features[i]; |
||||
predictedFeatures[j] = predictedFeatures[i]; |
||||
++j; |
||||
} |
||||
} |
||||
features.resize( j ); |
||||
predictedFeatures.resize( j ); |
||||
} |
||||
|
||||
void OpticalFlowPCAFlow::calc( InputArray I0, InputArray I1, InputOutputArray flow_out ) |
||||
{ |
||||
Size size = I0.size(); |
||||
CV_Assert( size == I1.size() ); |
||||
CV_Assert( sparseRate > 0 && sparseRate < 0.1 ); |
||||
|
||||
Mat from, to; |
||||
if ( I0.channels() == 3 ) |
||||
{ |
||||
cvtColor( I0, from, COLOR_BGR2GRAY ); |
||||
from.convertTo( from, CV_8U ); |
||||
} |
||||
else |
||||
{ |
||||
I0.getMat().convertTo( from, CV_8U ); |
||||
} |
||||
if ( I1.channels() == 3 ) |
||||
{ |
||||
cvtColor( I1, to, COLOR_BGR2GRAY ); |
||||
to.convertTo( to, CV_8U ); |
||||
} |
||||
else |
||||
{ |
||||
I1.getMat().convertTo( to, CV_8U ); |
||||
} |
||||
|
||||
CV_Assert( from.channels() == 1 ); |
||||
CV_Assert( to.channels() == 1 ); |
||||
|
||||
std::vector<Point2f> features, predictedFeatures; |
||||
const unsigned maxFeatures = size.area() * sparseRate; |
||||
goodFeaturesToTrack( from, features, maxFeatures, 0.005, 3 ); |
||||
|
||||
// Add points along the grid if not enough features
|
||||
{ |
||||
const unsigned missingPoints = maxFeatures - features.size(); |
||||
const unsigned blockSize = sqrt( (float)size.area() / missingPoints ); |
||||
for ( int x = blockSize / 2; x < size.width; x += blockSize ) |
||||
for ( int y = blockSize / 2; y < size.height; y += blockSize ) |
||||
features.push_back( Point2f( x, y ) ); |
||||
} |
||||
|
||||
findSparseFeatures( from, to, features, predictedFeatures ); |
||||
|
||||
// TODO: Remove occlusions
|
||||
|
||||
flow_out.create( size, CV_32FC2 ); |
||||
Mat flow = flow_out.getMat(); |
||||
for ( size_t i = 0; i < features.size(); ++i ) |
||||
{ |
||||
flow.at<Point2f>( features[i].y, features[i].x ) = predictedFeatures[i] - features[i]; |
||||
} |
||||
|
||||
from.convertTo( from, CV_32F ); |
||||
to.convertTo( to, CV_32F ); |
||||
} |
||||
|
||||
void OpticalFlowPCAFlow::collectGarbage() {} |
||||
|
||||
Ptr<DenseOpticalFlow> createOptFlow_PCAFlow() { return makePtr<OpticalFlowPCAFlow>(); } |
||||
} |
||||
} |
Loading…
Reference in new issue