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)); } }
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 }