Last active
August 29, 2015 14:23
-
-
Save berak/9a556537dccea2709712 to your computer and use it in GitHub Desktop.
standalone test case for https://github.com/Itseez/opencv_contrib/issues/195
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "opencv2/opencv.hpp" | |
| using namespace cv; | |
| using namespace std; | |
| #ifndef CV_SQR | |
| # define CV_SQR(x) ((x)*(x)) | |
| #endif | |
| #ifndef CV_INIT_VECTOR | |
| # define CV_INIT_VECTOR(vname, type, ...) \ | |
| static const type vname##_a[] = __VA_ARGS__; \ | |
| std::vector <type> vname(vname##_a, \ | |
| vname##_a + sizeof(vname##_a) / sizeof(*vname##_a)) | |
| #endif | |
| static cv::Mat imsmooth(const cv::Mat &src, const int rad) | |
| { | |
| if (rad == 0) | |
| return src; | |
| else | |
| { | |
| const float p = 12.0f/rad/(rad + 2) - 2; | |
| cv::Mat dst; | |
| if (rad <= 1) | |
| { | |
| CV_INIT_VECTOR(kernelXY, float, {1/(p + 2), p/(p + 2), 1/(p + 2)}); | |
| cv::sepFilter2D(src, dst, -1, kernelXY, kernelXY); | |
| } | |
| else | |
| { | |
| float nrml = CV_SQR(rad + 1.0f); | |
| std::vector <float> kernelXY(2*rad + 1); | |
| for (int i = 0; i <= rad; ++i) | |
| { | |
| kernelXY[2*rad - i] = (i + 1) / nrml; | |
| kernelXY[i] = (i + 1) / nrml; | |
| } | |
| sepFilter2D(src, dst, -1, kernelXY, kernelXY); | |
| } | |
| return dst; | |
| } | |
| } | |
| static void gradientHist(const cv::Mat &src, cv::Mat &magnitude, cv::Mat &histogram, | |
| const int nBins, const int pSize, const int gnrmRad) | |
| { | |
| cv::Mat phase, Dx, Dy; | |
| magnitude.create( src.size(), cv::DataType<float>::type ); | |
| phase.create( src.size(), cv::DataType<float>::type ); | |
| // changing to ceil will make it work ! | |
| //histogram.create( cv::Size( cvCeil(src.size().width/float(pSize)), | |
| // cvCeil(src.size().height/float(pSize)) ), | |
| histogram.create( cv::Size( cvRound(src.size().width/float(pSize)), | |
| cvRound(src.size().height/float(pSize)) ), | |
| CV_MAKETYPE(cv::DataType<float>::type, nBins) ); | |
| CV_Assert(phase.cols>=histogram.cols); /// added just to show, that both rows and cols are overflowing | |
| histogram.setTo(0); | |
| cv::Sobel( src, Dx, cv::DataType<float>::type, | |
| 1, 0, 1, 1.0, 0.0, cv::BORDER_REFLECT ); | |
| cv::Sobel( src, Dy, cv::DataType<float>::type, | |
| 0, 1, 1, 1.0, 0.0, cv::BORDER_REFLECT ); | |
| int nchannels = src.channels(); | |
| for (int i = 0; i < src.rows; ++i) | |
| { | |
| const float *pDx = Dx.ptr<float>(i); | |
| const float *pDy = Dy.ptr<float>(i); | |
| float *pMagnitude = magnitude.ptr<float>(i); | |
| float *pPhase = phase.ptr<float>(i); | |
| for (int j = 0; j < src.cols*nchannels; j += nchannels) | |
| { | |
| float fMagn = float(-1e-5), fdx = 0, fdy = 0; | |
| for (int k = 0; k < nchannels; ++k) | |
| { | |
| float cMagn = CV_SQR( pDx[j + k] ) + CV_SQR( pDy[j + k] ); | |
| if (cMagn > fMagn) | |
| { | |
| fMagn = cMagn; | |
| fdx = pDx[j + k]; | |
| fdy = pDy[j + k]; | |
| } | |
| } | |
| pMagnitude[j/nchannels] = sqrtf(fMagn); | |
| float angle = cv::fastAtan2(fdy, fdx) / 180.0f - 1.0f * (fdy < 0); | |
| if (std::fabs(fdx) + std::fabs(fdy) < 1e-5) | |
| angle = 0.5f; | |
| pPhase[j/nchannels] = angle; | |
| } | |
| } | |
| magnitude /= imsmooth( magnitude, gnrmRad ) | |
| + 0.01*cv::Mat::ones( magnitude.size(), magnitude.type() ); | |
| for (int i = 0; i < phase.rows; ++i) | |
| { | |
| const float *pPhase = phase.ptr<float>(i); | |
| const float *pMagn = magnitude.ptr<float>(i); | |
| float *pHist = histogram.ptr<float>(i/pSize); | |
| for (int j = 0; j < phase.cols; ++j) | |
| pHist[cvRound((j/pSize + pPhase[j])*nBins)] += pMagn[j] / CV_SQR(pSize); | |
| } | |
| } | |
| int main( int argc, const char** argv ) | |
| { | |
| Mat src = Mat(400,400,CV_8U); // content does not matter | |
| for (int i=0; i<100; i++) | |
| { | |
| Mat rez,hist,mag; | |
| Size siz(400,400+i); | |
| cerr << i << " " << siz << endl; | |
| try | |
| { | |
| resize(src,rez,siz); | |
| gradientHist(rez,mag,hist,8,2,8); | |
| } catch(cv::Exception &e){} | |
| } | |
| return 0; | |
| } |
Author
berak
commented
Jun 19, 2015
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment