double AutoCorr::getMinimalPattern(unsigned int &sX, unsigned int &sY, unsigned int &sizeX, unsigned int &sizeY)
{
    const float epsilon = 0.00005;

    float *rho_x = 0;
    float *rho_y = 0;
    getACX(m_autocorr, rho_x);
    getACY(m_autocorr, rho_y);
    float stdDevX = 0;
    float stdDevY = 0;
    int* xPeaks = new int[m_autocorr.cols];
    int* yPeaks = new int[m_autocorr.rows];
    int peaksX = countPeaks(rho_x, stdDevX, m_autocorr.cols, xPeaks);
    int peaksY = countPeaks(rho_y, stdDevY, m_autocorr.rows, yPeaks);

    std::vector<int> high_xPeaks;
    float meanPeakHeight = 0;
    for (int i = 0; i < peaksX; i++)
    {
        meanPeakHeight += calcPeakHeight(xPeaks[i], rho_x, m_autocorr.cols);
    }
    meanPeakHeight /= peaksX;
    for (int i = 0; i < peaksX; i++)
    {
        if (calcPeakHeight(xPeaks[i], rho_x, m_autocorr.cols) > meanPeakHeight)
        {
            high_xPeaks.push_back(xPeaks[i]);
        }
    }
    std::vector<int> high_yPeaks;
    meanPeakHeight = 0;
    for (int i = 0; i < peaksY; i++)
    {
        meanPeakHeight += calcPeakHeight(yPeaks[i], rho_y, m_autocorr.rows);
    }
    meanPeakHeight /= peaksY;
    for (int i = 0; i < peaksY; i++)
    {
        if (calcPeakHeight(yPeaks[i], rho_y, m_autocorr.rows) > meanPeakHeight)
        {
            high_yPeaks.push_back(yPeaks[i]);
        }
    }

    //x direction
    float x_highest_correlation = -FLT_MAX;
    for (int x = 0; x < high_xPeaks.size() / 2; x++)
    {
        for (int x2 = x + 1; x2 < high_xPeaks.size(); x2++)
        {
            //choose size for subrect
            int width  = high_xPeaks[x2] - high_xPeaks[x] + 1;
            int height = m_image.rows;

            //choose center for the subrect
            int cx = high_xPeaks[x] + width / 2;
            int cy = height / 2;

            //extract the subrect
            cv::Mat dst;
            cv::getRectSubPix(m_image, cv::Size(width, height), cv::Point2f(cx, cy), dst);

            //calculate cross correlation between dst and m_image
            CrossCorr* cc = new CrossCorr(m_image, dst);
            float correlation = 0;
            for (int i = 0; i < m_image.cols / width; i++)
            {
                correlation += fabs(cc->at((high_xPeaks[x] + i * width) % m_image.cols, 0));
            }
            if (correlation > x_highest_correlation)
            {
                x_highest_correlation = correlation;
                sizeX 	= width;
                sX	= high_xPeaks[x];
            }
        }
    }
    //Could not find enough peaks
    if (x_highest_correlation == -FLT_MAX)
    {
        sizeX 	= m_image.cols;
        sX	= 0;
    }

    //y direction
    float y_highest_correlation = -FLT_MAX;
    for (int y = 0; y < high_yPeaks.size(); y++)
    {
        for (int y2 = y + 1; y2 < high_yPeaks.size(); y2++)
        {
            //choose size for subrect
            int width = sizeX;
            int height  = high_yPeaks[y2] - high_yPeaks[y] + 1;

            //choose center for the subrect
            int cx = sX;
            int cy = high_yPeaks[y] + width / 2;

            //extract the subrect
            cv::Mat dst;
            cv::getRectSubPix(m_image, cv::Size(width, height), cv::Point2f(cx, cy), dst);

            //calculate cross correlation between dst and m_image
            CrossCorr* cc = new CrossCorr(m_image, dst);
            float correlation = 0;
            for (int i = 0; i < m_image.rows / height; i++)
            {
                for (int j = 0; j < m_image.cols / width; j++)
                {
                    correlation += fabs(cc->at((sX + j * width) % m_image.cols, (high_yPeaks[y] + i * height) % m_image.rows));
                }
            }
            if (correlation > y_highest_correlation)
            {
                y_highest_correlation = correlation;
                sizeY 	= height;
                sY	= high_yPeaks[y];
            }
        }
    }
    //Could not find enough peaks
    if (y_highest_correlation == -FLT_MAX)
    {
        sizeY 	= m_image.rows;
        sY	= 0;
    }

    if (y_highest_correlation == -FLT_MAX == x_highest_correlation || stdDevX < 0.00001 && stdDevY < 0.00001 || peaksX < 0.00001 || peaksY < 0.00001)
    {
        //Texture is aperiodic
        return 0;
    }
    else
    {
        return	1.0f / std::min(stdDevX/(m_autocorr.cols / peaksX), stdDevY/(m_autocorr.rows / peaksY));
    }
}
Esempio n. 2
0
double AutoCorr::getMinimalPattern(unsigned int &sX, unsigned int &sY, unsigned int &sizeX, unsigned int &sizeY, const int minimalPatternSize = 10)
{
	const float epsilon = 0.00005;

	float *rho_x = 0;
	float *rho_y = 0;	
	getACX(m_autocorr, rho_x);
	getACY(m_autocorr, rho_y);
	float stdDevX = 0;
	float stdDevY = 0;
	int* xPeaks = new int[m_autocorr.cols];
	int* yPeaks = new int[m_autocorr.rows];
	int peaksX = countPeaks(rho_x, stdDevX, m_autocorr.cols, xPeaks);
	int peaksY = countPeaks(rho_y, stdDevY, m_autocorr.rows, yPeaks);
//	std::cout<<"Peaks x:"<<peaksX<<"\t\t StdDev rho_x: "<<stdDevX/(m_autocorr.cols / peaksX)<<std::endl;
//	std::cout<<"Peaks y:"<<peaksY<<"\t\t StdDev rho_y: "<<stdDevY/(m_autocorr.rows / peaksY)<<std::endl;
	for (int i = 0; i < m_autocorr.cols; i++)
	{
		std::cerr<<i<<" "<<rho_x[i]<<std::endl;
	}
//	for (int i = 0; i < peaksX; i++)
//	{
//		std::cout<<xPeaks[i]<<" "<<0<<std::endl;
//	}

	std::vector<int> high_xPeaks;
	for (int i = 0; i < peaksX; i++)
	{
		if (/*calcPeakHeight(xPeaks[i], rho_x, m_autocorr.cols) > minimalPatternSize &&*/ rho_x[xPeaks[i]] > 0)
		{
			high_xPeaks.push_back(xPeaks[i]);
//			std::cout<<high_xPeaks.back()<<" "<<0<<std::endl;
		}
	}
	std::vector<int> high_yPeaks;
	for (int i = 0; i < peaksY; i++)
	{
		if (/*calcPeakHeight(yPeaks[i], rho_y, m_autocorr.rows) > minimalPatternSize &&*/ rho_y[yPeaks[i]] > 0)
		{
			high_yPeaks.push_back(yPeaks[i]);
		}
	}

	std::priority_queue<patternDim, std::vector<patternDim>, patternDim> x_patterns;
	//x direction
	for (int x = 0; x < high_xPeaks.size() / 2; x++)
	{
		for (int x2 = x + 1; x2 < high_xPeaks.size() / 2; x2++)
		{
			patternDim p;	
			float dist = fabs(calcPeakHeight(high_xPeaks[x], rho_x, m_autocorr.cols) - calcPeakHeight(high_xPeaks[x2], rho_x, m_autocorr.cols));
			float d1   = fabs(fabs(rho_x[high_xPeaks[x]] - rho_x[high_xPeaks[x] - 1]) - fabs(rho_x[high_xPeaks[x2]] - rho_x[high_xPeaks[x2] - 1]));
			float d2   = fabs(fabs(rho_x[high_xPeaks[x]] - rho_x[high_xPeaks[x] + 1]) - fabs(rho_x[high_xPeaks[x2]] - rho_x[high_xPeaks[x2] + 1]));
			p.size 	= high_xPeaks[x2] - high_xPeaks[x];
			p.s	= high_xPeaks[x];
			p.fit = dist + d1 + d2;
			x_patterns.push(p);
		}
	}
	
	if (x_patterns.empty())
	{
		sizeX = m_image.cols;
		sX = 0;
	}
	else
	{
		//Test the first elements of the priority queuer by cross correlation
		float x_highest_correlation = -FLT_MAX;
		for (int x = 0; x < std::min((size_t)10, x_patterns.size()); x++)
		{
			//choose size for subrect
			int width  = x_patterns.top().size;
			int height = m_image.rows;

			//choose center for the subrect
			int cx = x_patterns.top().s + width / 2;
			int cy = height / 2;

			//extract the subrect
			cv::Mat dst;
			cv::getRectSubPix(m_image, cv::Size(width, height), cv::Point2f(cx, cy), dst);
		
			//calculate cross correlation between dst and m_image
			CrossCorr* cc = new CrossCorr(m_image, dst);
			float correlation = 0;	
			for (int i = 0; i < m_image.cols / width; i++)
			{
				correlation += cc->at((x_patterns.top().s + i * width) % m_image.cols, 0);
			}	
//			std::cout<<"x: "<<x<<" "<<correlation<<std::endl;
			if (correlation > x_highest_correlation)
			{
				x_highest_correlation = correlation;
				sizeX 	= width;
				sX	= x_patterns.top().s;
			}
			x_patterns.pop();
		}
	}

	//y direction
	std::priority_queue<patternDim, std::vector<patternDim>, patternDim> y_patterns;
	for (int y = 0; y < high_yPeaks.size() / 2; y++)
	{
		for (int y2 = y + 1; y2 < high_yPeaks.size() / 2; y2++)
		{
			patternDim p;	
			float dist = fabs(calcPeakHeight(high_yPeaks[y], rho_y, m_autocorr.rows) - calcPeakHeight(high_yPeaks[y2], rho_y, m_autocorr.rows));
			float d1   = fabs(fabs(rho_y[high_yPeaks[y]] - rho_y[high_yPeaks[y] - 1]) - fabs(rho_y[high_yPeaks[y2]] - rho_y[high_yPeaks[y2] - 1]));
			float d2   = fabs(fabs(rho_y[high_yPeaks[y]] - rho_y[high_yPeaks[y] + 1]) - fabs(rho_y[high_yPeaks[y2]] - rho_y[high_yPeaks[y2] + 1]));
			p.size 	= high_yPeaks[y2] - high_yPeaks[y];
			p.s	= high_yPeaks[y];
			p.fit = dist + d1 + d2;
			y_patterns.push(p);
		}
	}

	//Could not find more than one peak
	if (y_patterns.empty())
	{
		sizeY = m_image.rows;
		sY = 0;
	}
	else
	{
		//Test the first elements of the priority queuer by cross correlation
		float y_highest_correlation = -FLT_MAX;
		for (int y = 0; y < std::min((size_t)10, y_patterns.size()); y++)
		{
			//choose size for subrect
			int width = m_image.cols;
			int height  = y_patterns.top().size;

			//choose center for the subrect
			int cx = width / 2;
			int cy = y_patterns.top().s + width / 2;

			//extract the subrect
			cv::Mat dst;
			cv::getRectSubPix(m_image, cv::Size(width, height), cv::Point2f(cx, cy), dst);
		
			//calculate cross correlation between dst and m_image
			CrossCorr* cc = new CrossCorr(m_image, dst);
			float correlation = 0;	
			for (int i = 0; i < m_image.rows / height; i++)
			{
				correlation += cc->at(0, (y_patterns.top().s + i * height) % m_image.rows);
			}	
//			std::cout<<"y: "<<y<<" "<<correlation<<std::endl;
			if (correlation > y_highest_correlation)
			{
				y_highest_correlation = correlation;
				sizeY 	= height;
				sY	= y_patterns.top().s;
			}
			y_patterns.pop();
		}
	}

	return 0; //TODO
}