//-------------------------------------------------------------------------
void InitializeArrays()
//-------------------------------------------------------------------------
{
    int i, j, pos;
    double Normalize = 0.0;
    Window = 2*halfWindow + 1; Window2 = Window*Window;
    H         = new double[3*NxNy];
    kernelGxx = new double[Window2];
    kernelGyy = new double[Window2];
    kernelGxy = new double[Window2];
    for(i = -halfWindow; i <= halfWindow; i++){
        for(j = -halfWindow; j <= halfWindow; j++){
            pos = i+halfWindow + (j+halfWindow)*Window;
            kernelGxx[pos] = Gxx((double)i*hx,(double)j*hy);
            kernelGyy[pos] = Gyy((double)i*hx,(double)j*hy);
            kernelGxy[pos] = Gxy((double)i*hx,(double)j*hy);
            Normalize += kernelGxx[pos];
        }
    }
    //---------------------------------------------------------------------
	if(Normalize != 0){
        for(i = -halfWindow; i <= halfWindow; i++){
            for(j = -halfWindow; j <= halfWindow; j++){
                pos = i+halfWindow + (j+halfWindow)*Window;
                kernelGxx[pos] -= (Normalize/(double)Window2);
                kernelGyy[pos] -= (Normalize/(double)Window2);
            }
        }
    }
};
/*static*/ void ImageFilter::computeDerivativesOfImage(const cv::Mat& img, const std::size_t apertureSize, const double sigma, cv::Mat& Fx, cv::Mat& Fy, cv::Mat& Fxx, cv::Mat& Fyy, cv::Mat& Fxy)
{
	// Compute derivatives wrt xy-coordinate system.
	cv::Mat Gx(apertureSize, apertureSize, CV_64F), Gy(apertureSize, apertureSize, CV_64F);
	cv::Mat Gxx(apertureSize, apertureSize, CV_64F), Gyy(apertureSize, apertureSize, CV_64F), Gxy(apertureSize, apertureSize, CV_64F);
	DerivativesOfGaussian::getFirstOrderDerivatives(apertureSize, sigma, Gx, Gy);
	DerivativesOfGaussian::getSecondOrderDerivatives(apertureSize, sigma, Gxx, Gyy, Gxy);

	// Make sure that the sum (or average) of all elements of the kernel has to be zero (similar to the Laplace kernel) so that the convolution result of a homogeneous regions is always zero.
	//	REF [site] >> http://fourier.eng.hmc.edu/e161/lectures/gradient/node8.html
	const double kernelArea = (double)apertureSize * (double)apertureSize;
	Gx -= cv::sum(Gx) / kernelArea;
	Gy -= cv::sum(Gy) / kernelArea;
	Gxx -= cv::sum(Gxx) / kernelArea;
	Gyy -= cv::sum(Gyy) / kernelArea;
	Gxy -= cv::sum(Gxy) / kernelArea;

	// Compute Fx, Fy, Fxx, Fyy, Fxy.
	cv::filter2D(img, Fx, CV_64F, Gx, cv::Point(-1, -1), 0, cv::BORDER_DEFAULT);
	cv::filter2D(img, Fy, CV_64F, Gy, cv::Point(-1, -1), 0, cv::BORDER_DEFAULT);
	cv::filter2D(img, Fxx, CV_64F, Gxx, cv::Point(-1, -1), 0, cv::BORDER_DEFAULT);
	cv::filter2D(img, Fyy, CV_64F, Gyy, cv::Point(-1, -1), 0, cv::BORDER_DEFAULT);
	cv::filter2D(img, Fxy, CV_64F, Gxy, cv::Point(-1, -1), 0, cv::BORDER_DEFAULT);
}