parent
2d1fc7a6cd
commit
e4137ce8c1
3 changed files with 501 additions and 0 deletions
@ -0,0 +1,85 @@ |
|||||||
|
/*
|
||||||
|
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 |
||||||
|
(3-clause BSD License) |
||||||
|
|
||||||
|
Copyright (C) 2000-2015, Intel Corporation, all rights reserved. |
||||||
|
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. |
||||||
|
Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved. |
||||||
|
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. |
||||||
|
Copyright (C) 2015, OpenCV Foundation, all rights reserved. |
||||||
|
Copyright (C) 2015, Itseez 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: |
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, |
||||||
|
this list of conditions and the following disclaimer. |
||||||
|
|
||||||
|
* Redistributions 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. |
||||||
|
|
||||||
|
* Neither the names of the copyright holders nor the names of the contributors |
||||||
|
may 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 copyright holders 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. |
||||||
|
|
||||||
|
Algorithmic details of this algorithm can be found at: |
||||||
|
* O. Green, Y. Birk, "A Computationally Efficient Algorithm for the 2D Covariance Method", ACM/IEEE International Conference on High Performance Computing, Networking, Storage and Analysis, Denver, Colorado, 2013 |
||||||
|
A previous and less efficient version of the algorithm can be found: |
||||||
|
* O. Green, L. David, A. Galperin, Y. Birk, "Efficient parallel computation of the estimated covariance matrix", arXiv, 2013 |
||||||
|
|
||||||
|
|
||||||
|
*/ |
||||||
|
#ifndef __OPENCV_ESTIMATECOVARIANCE_HPP__ |
||||||
|
#define __OPENCV_ESTIMATECOVARIANCE_HPP__ |
||||||
|
#ifdef __cplusplus |
||||||
|
|
||||||
|
#include <opencv2/core.hpp> |
||||||
|
|
||||||
|
namespace cv |
||||||
|
{ |
||||||
|
namespace ximgproc |
||||||
|
{ |
||||||
|
|
||||||
|
/** @brief Computes the estimated covariance matrix of an image using the sliding
|
||||||
|
window forumlation. |
||||||
|
|
||||||
|
@param src The source image. Input image must be of a complex type. |
||||||
|
@param windowRows The number of rows in the window. |
||||||
|
@param windowCols The number of cols in the window. |
||||||
|
The window size parameters control the accuracy of the estimation.
|
||||||
|
The sliding window moves over the entire image from the top-left corner
|
||||||
|
to the bottom right corner. Each location of the window represents a sample. |
||||||
|
If the window is the size of the image, then this gives the exact covariance matrix. |
||||||
|
For all other cases, the sizes of the window will impact the number of samples
|
||||||
|
and the number of elements in the estimated covariance matrix.
|
||||||
|
*/ |
||||||
|
|
||||||
|
CV_EXPORTS_W void covarianceEstimation(InputArray src, OutputArray dst,
|
||||||
|
int windowRows, int windowCols); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
#endif |
||||||
|
#endif |
@ -0,0 +1,415 @@ |
|||||||
|
/*
|
||||||
|
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 |
||||||
|
(3-clause BSD License) |
||||||
|
|
||||||
|
Copyright (C) 2000-2015, Intel Corporation, all rights reserved. |
||||||
|
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. |
||||||
|
Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved. |
||||||
|
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. |
||||||
|
Copyright (C) 2015, OpenCV Foundation, all rights reserved. |
||||||
|
Copyright (C) 2015, Itseez 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: |
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, |
||||||
|
this list of conditions and the following disclaimer. |
||||||
|
|
||||||
|
* Redistributions 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. |
||||||
|
|
||||||
|
* Neither the names of the copyright holders nor the names of the contributors |
||||||
|
may 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 copyright holders 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. |
||||||
|
|
||||||
|
Algorithmic details of this algorithm can be found at: |
||||||
|
* O. Green, Y. Birk, "A Computationally Efficient Algorithm for the 2D Covariance Method", ACM/IEEE International Conference on High Performance Computing, Networking, Storage and Analysis, Denver, Colorado, 2013 |
||||||
|
A previous and less efficient version of the algorithm can be found: |
||||||
|
* O. Green, L. David, A. Galperin, Y. Birk, "Efficient parallel computation of the estimated covariance matrix", arXiv, 2013 |
||||||
|
|
||||||
|
|
||||||
|
*/ |
||||||
|
|
||||||
|
#include "precomp.hpp" |
||||||
|
//#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENMP |
||||||
|
#include <omp.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
using namespace cv; |
||||||
|
using namespace std; |
||||||
|
|
||||||
|
|
||||||
|
namespace cv{ |
||||||
|
namespace ximgproc{ |
||||||
|
|
||||||
|
class EstimateCovariance{ |
||||||
|
|
||||||
|
public: |
||||||
|
EstimateCovariance(int pr_, int pc_); |
||||||
|
~EstimateCovariance(); |
||||||
|
|
||||||
|
void computeEstimateCovariance(Mat inputData,Mat outputData); |
||||||
|
int combinationCount(); |
||||||
|
|
||||||
|
private: |
||||||
|
typedef struct { |
||||||
|
int mult1r; |
||||||
|
int mult1c; |
||||||
|
int mult2r; |
||||||
|
int mult2c; |
||||||
|
int type2; // 0 - for the first P*P. 1 - for the next (P-1)(P-1)
|
||||||
|
int id; |
||||||
|
} Combination; |
||||||
|
|
||||||
|
void initInternalDataStructures(); |
||||||
|
void buildCombinationsTable(); |
||||||
|
|
||||||
|
void iterateCombinations(Mat inputData,Mat outputData); |
||||||
|
void computeOneCombination(int comb_id, Mat inputData , Mat outputData, |
||||||
|
Mat outputVector,int* finalMatPosR, int* finalMatPosC); |
||||||
|
|
||||||
|
inline void complexSubtract(std::complex<float>& src, std::complex<float>& dst){dst-=src;} |
||||||
|
inline void complexAdd(std::complex<float>& src, std::complex<float>& dst){dst+=src;} |
||||||
|
inline void complexConjMulAndAdd(std::complex<float>& a, std::complex<float>& b, |
||||||
|
std::complex<float>& dst){dst += a*b;} |
||||||
|
inline void complexConjMul(std::complex<float>& a, std::complex<float>& b, |
||||||
|
std::complex<float>& dst){dst = a*b;} |
||||||
|
|
||||||
|
private: |
||||||
|
int nr; |
||||||
|
int nc; |
||||||
|
int pr; |
||||||
|
int pc; |
||||||
|
int threads; |
||||||
|
|
||||||
|
Combination* combinationsTable; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
EstimateCovariance::EstimateCovariance(int pr_, int pc_){ |
||||||
|
pr=pr_; pc=pc_; |
||||||
|
|
||||||
|
#ifdef HAVE_OPENMP |
||||||
|
threads=omp_get_num_procs(); |
||||||
|
omp_set_num_threads(threads); |
||||||
|
#else |
||||||
|
threads=1; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
EstimateCovariance::~EstimateCovariance(){ |
||||||
|
delete[] combinationsTable; |
||||||
|
} |
||||||
|
|
||||||
|
void EstimateCovariance::initInternalDataStructures(){ |
||||||
|
int combCount = combinationCount(); |
||||||
|
combinationsTable = new Combination[combCount]; |
||||||
|
buildCombinationsTable(); |
||||||
|
} |
||||||
|
|
||||||
|
int EstimateCovariance::combinationCount(){ |
||||||
|
return (pr*pc+(pr-1)*(pc-1)); |
||||||
|
} |
||||||
|
|
||||||
|
void EstimateCovariance::buildCombinationsTable() |
||||||
|
{ |
||||||
|
int idx_row,idx_col; |
||||||
|
int comb_idx = 0; |
||||||
|
Combination comb; |
||||||
|
|
||||||
|
// The first element of the product is [0,0] and the second is to down and to the right of it.
|
||||||
|
for (idx_col=0; idx_col<pc; ++idx_col) { |
||||||
|
for (idx_row=0; idx_row<pr; ++idx_row) { |
||||||
|
comb.mult1r=0; |
||||||
|
comb.mult1c=0; |
||||||
|
comb.mult2r=idx_row; |
||||||
|
comb.mult2c=idx_col; |
||||||
|
comb.type2 = 0; |
||||||
|
comb.id = comb_idx; |
||||||
|
memcpy(&combinationsTable[comb_idx++], &comb, sizeof(Combination)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// The first element is on the top right, and the second element is to the left and down of it.
|
||||||
|
for (idx_row=1; idx_row<pr; ++idx_row) { |
||||||
|
for (idx_col=1; idx_col<pc; ++idx_col) { |
||||||
|
comb.mult1r=idx_row; |
||||||
|
comb.mult1c=0; |
||||||
|
comb.mult2r=0; |
||||||
|
comb.mult2c=idx_col; |
||||||
|
|
||||||
|
comb.type2 = 1; |
||||||
|
comb.id = comb_idx; |
||||||
|
memcpy(&combinationsTable[comb_idx++], &comb, sizeof(Combination)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void EstimateCovariance::computeEstimateCovariance(Mat inputData,Mat outputData){ |
||||||
|
initInternalDataStructures(); |
||||||
|
nr=inputData.rows; |
||||||
|
nc=inputData.cols; |
||||||
|
|
||||||
|
iterateCombinations(inputData,outputData); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
void EstimateCovariance::iterateCombinations(Mat inputData,Mat outputData) |
||||||
|
{ |
||||||
|
int combsPerCPU = combinationCount()/threads; |
||||||
|
int remainder = combinationCount()%threads; |
||||||
|
if(remainder>0) |
||||||
|
combsPerCPU++; |
||||||
|
|
||||||
|
#ifdef HAVE_OPENMP |
||||||
|
#pragma omp parallel |
||||||
|
#endif |
||||||
|
{ |
||||||
|
int idx; |
||||||
|
int combs; |
||||||
|
#ifdef HAVE_OPENMP |
||||||
|
int thread_id= omp_get_thread_num(); |
||||||
|
#else |
||||||
|
int thread_id=0; |
||||||
|
#endif |
||||||
|
int startComb; |
||||||
|
if (remainder > thread_id){ |
||||||
|
combs=combsPerCPU; |
||||||
|
startComb=(thread_id)*combsPerCPU; |
||||||
|
} |
||||||
|
else{ |
||||||
|
combs=combsPerCPU-1; |
||||||
|
startComb=remainder*combsPerCPU+(thread_id-remainder)*(combsPerCPU-1); |
||||||
|
} |
||||||
|
// stopComb=startComb+combs;
|
||||||
|
Mat outputVector(pr*pc,1, DataType<std::complex<float> >::type); |
||||||
|
|
||||||
|
int* finalMatPosR = new int[pr*pc]; |
||||||
|
int* finalMatPosC = new int[pr*pc]; |
||||||
|
|
||||||
|
for (idx=0; idx<combs; idx++){ |
||||||
|
outputVector.setTo(Scalar(0,0)); |
||||||
|
memset(finalMatPosR,0,pr*pc*sizeof(int)); |
||||||
|
memset(finalMatPosC,0,pr*pc*sizeof(int)); |
||||||
|
computeOneCombination(startComb++, inputData, outputData, |
||||||
|
outputVector,finalMatPosR, finalMatPosC); |
||||||
|
} |
||||||
|
delete[] finalMatPosR;
|
||||||
|
delete[] finalMatPosC; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void EstimateCovariance::computeOneCombination(int comb_id,Mat inputData, Mat outputData, |
||||||
|
Mat outputVector,int* finalMatPosR, int* finalMatPosC) |
||||||
|
{ |
||||||
|
Combination* comb = &combinationsTable[comb_id]; |
||||||
|
int type2 = comb->type2; |
||||||
|
int deltaR = (int)abs((int)(comb->mult1r-comb->mult2r)); |
||||||
|
int deltaC = (int)abs((int)(comb->mult1c-comb->mult2c)); |
||||||
|
int numElementsInBlock = pr-abs(deltaR); |
||||||
|
int numBlocks = pc-deltaC; |
||||||
|
const int DR= nr-pr; |
||||||
|
const int DC= nc-pc; |
||||||
|
|
||||||
|
int elementC=0; |
||||||
|
std::complex<float> temp_res = std::complex<float>(0,0); |
||||||
|
int i,j,r,c; |
||||||
|
|
||||||
|
if (!type2) { |
||||||
|
// Computing the first index of the combination.
|
||||||
|
// This index is made up
|
||||||
|
for(i=0; i<=( DR); i++) { |
||||||
|
int iPdr=i+deltaR; |
||||||
|
for(j=0; j<= (DC); j++) { |
||||||
|
int jPdc = j+deltaC; |
||||||
|
complexConjMulAndAdd(inputData.at<std::complex<float> >(i,j), inputData.at<std::complex<float> >(iPdr,jPdc), temp_res); |
||||||
|
} |
||||||
|
} |
||||||
|
}else{ |
||||||
|
// Computing the first index of the combination.
|
||||||
|
for(i=0; i<=( DR); i++) { |
||||||
|
int iPdr=i+deltaR; |
||||||
|
for(j=0; j<= (DC); j++) { |
||||||
|
int jPdc = j+deltaC; |
||||||
|
complexConjMulAndAdd(inputData.at<std::complex<float> >(iPdr,j), inputData.at<std::complex<float> >(i,jPdc), temp_res); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
outputVector.at<std::complex<float> >(0,0) = temp_res; |
||||||
|
|
||||||
|
// Checking if the first element belongs to the first set of combinatons.
|
||||||
|
// The combination that the first element is above the second.
|
||||||
|
if (!type2) { |
||||||
|
finalMatPosR[0]=0; |
||||||
|
finalMatPosC[0]=pr*deltaC+deltaR; |
||||||
|
elementC++; |
||||||
|
}else{ |
||||||
|
finalMatPosR[0]=deltaR; |
||||||
|
finalMatPosC[0]=pr*deltaC; |
||||||
|
elementC++; |
||||||
|
} |
||||||
|
|
||||||
|
for(r=1;r<(pr-deltaR);r++){ |
||||||
|
std::complex<float> newRowSum = std::complex<float>(0,0),oldRowSum = std::complex<float>(0,0); |
||||||
|
std::complex<float> addRows = std::complex<float>(0,0); |
||||||
|
|
||||||
|
int rM1 = r-1; |
||||||
|
int k = DR+1 + rM1; |
||||||
|
int kPdr = k+deltaR; |
||||||
|
int rM1Pdr = rM1 + deltaR; |
||||||
|
int cPdc; |
||||||
|
|
||||||
|
if (!type2) { |
||||||
|
for(c=0;c<=(DC); c++){ |
||||||
|
cPdc = c+deltaC; |
||||||
|
complexConjMulAndAdd(inputData.at<std::complex<float> >(k,c),inputData.at<std::complex<float> >(kPdr,cPdc),newRowSum); |
||||||
|
complexConjMulAndAdd(inputData.at<std::complex<float> >(rM1,c),inputData.at<std::complex<float> >(rM1Pdr,cPdc),oldRowSum); |
||||||
|
} |
||||||
|
}else{ |
||||||
|
for(c=0;c<=(DC); c++){ |
||||||
|
cPdc = c+deltaC; |
||||||
|
complexConjMulAndAdd(inputData.at<std::complex<float> >(kPdr,c),inputData.at<std::complex<float> >(k,cPdc),newRowSum); |
||||||
|
complexConjMulAndAdd(inputData.at<std::complex<float> >(rM1Pdr,c),inputData.at<std::complex<float> >(rM1,cPdc),oldRowSum); |
||||||
|
} |
||||||
|
} |
||||||
|
complexAdd(newRowSum,addRows); |
||||||
|
complexSubtract(oldRowSum,addRows); |
||||||
|
complexAdd(outputVector.at<std::complex<float> >(rM1,0),outputVector.at<std::complex<float> >(r,0)); |
||||||
|
complexAdd(addRows,outputVector.at<std::complex<float> >(r,0)); |
||||||
|
|
||||||
|
finalMatPosR[elementC]=finalMatPosR[elementC-1]+1;; |
||||||
|
finalMatPosC[elementC]=finalMatPosC[elementC-1]+1; |
||||||
|
elementC++; |
||||||
|
} |
||||||
|
|
||||||
|
for(c=1; c<numBlocks; c++) { |
||||||
|
std::complex<float> newColSum = std::complex<float>(0,0),oldColSum = std::complex<float>(0,0); |
||||||
|
std::complex<float> addCols = std::complex<float>(0,0); |
||||||
|
|
||||||
|
// Index arithmetic
|
||||||
|
int cM1 = c-1; |
||||||
|
int dcPc = DC+c; |
||||||
|
int q = DC+1 + cM1; |
||||||
|
int cM1PdeltaC = cM1 + deltaC; |
||||||
|
int dcPcPdeltaC = dcPc+deltaC; |
||||||
|
|
||||||
|
if (!type2) { |
||||||
|
for(r=0;r<=(DR); r++){ |
||||||
|
int rPdr = r+deltaR; |
||||||
|
complexConjMulAndAdd(inputData.at<std::complex<float> >(r,q),inputData.at<std::complex<float> >(rPdr,q+deltaC),newColSum); |
||||||
|
complexConjMulAndAdd(inputData.at<std::complex<float> >(r,cM1),inputData.at<std::complex<float> >(rPdr,cM1+deltaC),oldColSum); |
||||||
|
} |
||||||
|
}else{ |
||||||
|
for(r=0;r<=(DR); r++){ |
||||||
|
int rPdr = r+deltaR; |
||||||
|
complexConjMulAndAdd(inputData.at<std::complex<float> >(rPdr,q),inputData.at<std::complex<float> >(r,q+deltaC),newColSum); |
||||||
|
complexConjMulAndAdd(inputData.at<std::complex<float> >(rPdr,cM1),inputData.at<std::complex<float> >(r,cM1+deltaC),oldColSum); |
||||||
|
} |
||||||
|
} |
||||||
|
complexAdd(newColSum,addCols); |
||||||
|
complexSubtract(oldColSum,addCols); |
||||||
|
complexAdd(outputVector.at<std::complex<float> >((c-1)*numElementsInBlock,0),outputVector.at<std::complex<float> >(c*numElementsInBlock,0)); |
||||||
|
complexAdd(addCols,outputVector.at<std::complex<float> >(c*numElementsInBlock,0)); |
||||||
|
|
||||||
|
finalMatPosR[elementC]=finalMatPosR[elementC-numElementsInBlock]+pr; |
||||||
|
finalMatPosC[elementC]=finalMatPosC[elementC-numElementsInBlock]+pr; |
||||||
|
elementC++; |
||||||
|
|
||||||
|
for(r=1; r<numElementsInBlock; r++) { |
||||||
|
std::complex<float> w = std::complex<float>(0,0),x = std::complex<float>(0,0), |
||||||
|
y = std::complex<float>(0,0),z = std::complex<float>(0,0),deltaRowSum = std::complex<float>(0,0); |
||||||
|
std::complex<float> tempRes = std::complex<float>(0,0); |
||||||
|
// Index arithmetic
|
||||||
|
int rM1 = r-1; |
||||||
|
int drPr = DR+r; |
||||||
|
int rM1PdeltaR = rM1 + deltaR; |
||||||
|
int drPrPdeltaR = drPr+deltaR; |
||||||
|
|
||||||
|
if (!type2) { |
||||||
|
complexConjMul(inputData.at<std::complex<float> >(rM1,cM1),inputData.at<std::complex<float> >(rM1PdeltaR,cM1PdeltaC),w); |
||||||
|
complexConjMul(inputData.at<std::complex<float> >(rM1,dcPc),inputData.at<std::complex<float> >(rM1PdeltaR,dcPcPdeltaC),x); |
||||||
|
complexConjMul(inputData.at<std::complex<float> >(drPr,cM1),inputData.at<std::complex<float> >(drPrPdeltaR,cM1PdeltaC),y); |
||||||
|
complexConjMul(inputData.at<std::complex<float> >(drPr,dcPc),inputData.at<std::complex<float> >(drPrPdeltaR,dcPcPdeltaC),z); |
||||||
|
}else{ |
||||||
|
complexConjMul(inputData.at<std::complex<float> >(rM1PdeltaR,cM1),inputData.at<std::complex<float> >(rM1,cM1PdeltaC),w); |
||||||
|
complexConjMul(inputData.at<std::complex<float> >(rM1PdeltaR,dcPc),inputData.at<std::complex<float> >(rM1,dcPcPdeltaC),x); |
||||||
|
complexConjMul(inputData.at<std::complex<float> >(drPrPdeltaR,cM1),inputData.at<std::complex<float> >(drPr,cM1PdeltaC),y); |
||||||
|
complexConjMul(inputData.at<std::complex<float> >(drPrPdeltaR,dcPc),inputData.at<std::complex<float> >(drPr,dcPcPdeltaC),z); |
||||||
|
} |
||||||
|
complexAdd(w,tempRes); |
||||||
|
complexSubtract(x,tempRes); |
||||||
|
complexSubtract(y,tempRes); |
||||||
|
complexAdd(z,tempRes); |
||||||
|
|
||||||
|
complexAdd(outputVector.at<std::complex<float> >((c-1)*numElementsInBlock + r,0),deltaRowSum); |
||||||
|
complexSubtract(outputVector.at<std::complex<float> >((c-1)*numElementsInBlock+ rM1,0),deltaRowSum); |
||||||
|
|
||||||
|
complexAdd(deltaRowSum,tempRes); |
||||||
|
complexAdd(outputVector.at<std::complex<float> >(c*numElementsInBlock+rM1,0),tempRes); |
||||||
|
complexAdd(tempRes,outputVector.at<std::complex<float> >(c*numElementsInBlock+r,0)); |
||||||
|
|
||||||
|
finalMatPosR[elementC]=finalMatPosR[elementC-1]+1; |
||||||
|
finalMatPosC[elementC]=finalMatPosC[elementC-1]+1; |
||||||
|
elementC++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for(i=0; i<numElementsInBlock*numBlocks; i++){ |
||||||
|
outputData.at<std::complex<float> >(finalMatPosR[i],finalMatPosC[i])=outputVector.at<std::complex<float> >(i,0); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void covarianceEstimation(InputArray input_, OutputArray output_,int windowRows, int windowCols){ |
||||||
|
|
||||||
|
CV_Assert( input_.channels() <= 2); // Does not take color images.
|
||||||
|
|
||||||
|
Mat input; |
||||||
|
|
||||||
|
Mat temp=input_.getMat(); |
||||||
|
if(temp.channels() == 1){ |
||||||
|
temp.convertTo(temp,CV_32FC2);
|
||||||
|
Mat zmat = Mat::zeros(temp.size(), CV_32F);
|
||||||
|
Mat twoChannelsbefore[] = {temp,zmat}; |
||||||
|
cv::merge(twoChannelsbefore,2,input); |
||||||
|
}else{ |
||||||
|
temp.convertTo(input, CV_32FC2); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
EstimateCovariance estCov(windowRows,windowCols); |
||||||
|
|
||||||
|
//input_.getMat().convertTo(input, CV_32FC2);
|
||||||
|
|
||||||
|
output_.create(windowRows*windowCols,windowRows*windowCols, DataType<std::complex<float> >::type); |
||||||
|
|
||||||
|
Mat output = output_.getMat(); |
||||||
|
|
||||||
|
estCov.computeEstimateCovariance(input,output); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace ximgproc
|
||||||
|
} // namespace cv
|
Loading…
Reference in new issue