Пример #1
0
void gradientMagnitude(const cv::Mat& image, float *M, float *O) {
    assert(image.type() == CV_32F || image.type() == CV_32FC3);
    float *tI = new float[image.rows * image.cols * image.channels()];
    if (image.channels() == 3)
    { OpenCVBGR_MatlabRGB(image, tI); }
    else
    { OpenCV2MatlabC1(image, tI); }
    gradMag(tI, M, O, image.rows, image.cols, image.channels(), true);
    delete[] tI;
}
Пример #2
0
// [M,O] = gradMag( I, [channel] ) - see gradientMag.m
void mGradMag( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) {
  int h, w, d, c; float *I, *M, *O=0;
  checkArgs(nl,pl,nr,pr,1,2,1,2,&h,&w,&d,mxSINGLE_CLASS,(void**)&I);
  if(h<2 || w<2) mexErrMsgTxt("I must be at least 2x2.");
  c = (nr>=2) ? (int) mxGetScalar(pr[1]) : 0;
  if( c>0 && c<=d ) { I += h*w*(c-1); d=1; }
  pl[0] = mxCreateMatrix3(h,w,1,mxSINGLE_CLASS,0,(void**)&M);
  if(nl>=2) pl[1] = mxCreateMatrix3(h,w,1,mxSINGLE_CLASS,0,(void**)&O);
  gradMag(I, M, O, h, w, d );
}
Пример #3
0
/* H = hog( I, [sBin], [oBin] ) - see hog.m */
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
  int h, w, d, hb, wb, nb, hb1, wb1, sBin, oBin;
  double *I, *M, *H, *HG; float *O;
  checkArgs(nlhs,plhs,nrhs,prhs,1,1,1,3,&h,&w,&d,&I);
  sBin = (nrhs>=2) ? (int) mxGetScalar(prhs[1]) : 8;
  oBin = (nrhs>=3) ? (int) mxGetScalar(prhs[2]) : 9;
  hb=h/sBin; wb=w/sBin; nb=wb*hb; hb1=hb>2?hb-2:0; wb1=wb>2?wb-2:0;
  plhs[0] = mxCreateMatrix3( hb1, wb1, oBin*4, mxDOUBLE_CLASS, 0, (void**) &HG);
  if( hb1==0 || wb1==0 ) return;
  M = (double*) mxMalloc(h*w*sizeof(double));
  O = (float*) mxMalloc(h*w*sizeof(float));
  H = (double*) mxCalloc(nb*oBin, sizeof(double));
  gradMag( I, M, O, h, w, d );
  gradHist( M, O, H, h, w, d, sBin, oBin, true, true );
  hog( H, HG, h, w, d, sBin, oBin );
  mxFree(M); mxFree(O); mxFree(H);
}
Пример #4
0
//Compute gradient magnitude and orientation at each image location.
//This code requires SSE2 to compile and run (most modern Intel and AMD
//processors support SSE2). Please see: http://en.wikipedia.org/wiki/SSE2.
//Image should be single (float datatype) values [0, 1]
void gradientMagnitude(const cv::Mat& image, cv::Mat& M, cv::Mat& O) {
    assert(image.type() == CV_32F || image.type() == CV_32FC3);
    M = Mat::zeros(image.size(), CV_32FC1);
    O = Mat::zeros(image.size(), CV_32FC1);
    float *tI = new float[image.rows * image.cols * image.channels()];
    float *tM = new float[image.rows * image.cols];
    float *tO = new float[image.rows * image.cols];

    if (image.channels() == 3)
    { OpenCVBGR_MatlabRGB(image, tI); }
    else
    { OpenCV2MatlabC1(image, tI); }

    gradMag(tI, tM, tO, image.rows, image.cols, image.channels(), true);

    Matlab2OpenCVC1(tM, M);
    Matlab2OpenCVC1(tO, O);

    delete [] tI;
    delete [] tM;
    delete [] tO;
}
Пример #5
0
GradMagChannel::GradMagChannel(const ColorChannel& CC)
{
    //	std::cout << "We work with a " <<  CC.getWidth() << "x" << CC.getHeight() << " image with " << CC.getnChns() << " channels" << std::endl;

    int w = CC.getWidth();
    int h = CC.getHeight();
    int nchns = CC.getnChns();

    this->mag = (float*)malloc(sizeof(float) * w * h); // only one channel deep
    this->orientation = (float*)malloc(sizeof(float) * w * h);

    gradMag(CC.getData(), mag, orientation, h, w, nchns, 0);

    float* S = (float*)malloc(sizeof(float) * w * h);
    convTri(mag, S, h, w, 1, 5, 1);

    gradMagNorm(mag, S, h, w, 0.0050);

    //Smoothing is performed, so  delete the temporary data
    free(S);

    // Set the  magnitude as the data to use for this channel
    setChanneldata(mag, w, h, 1);
}
Пример #6
0
    void cvFhogT(const cv::Mat& img, std::shared_ptr<OUT>& cvFeatures, int binSize, int fhogChannelsToCopy = 31) {
        const int orientations = 9;
        // ensure array is continuous
        const cv::Mat& image = (img.isContinuous() ? img : img.clone());

        int channels = image.channels();
        int computeChannels = 32;
        int width = image.cols;
        int height = image.rows;
        int widthBin = width / binSize;
        int heightBin = height / binSize;

        CV_Assert(channels == 1 || channels == 3);

        float* const H = (float*)wrCalloc(static_cast<size_t>(widthBin * heightBin * computeChannels), sizeof(float));
        float* const M = (float*)wrCalloc(static_cast<size_t>(width * height), sizeof(float));
        float* const O = (float*)wrCalloc(static_cast<size_t>(width * height), sizeof(float));

        float* I = NULL;

        if (channels == 1)
        { I = reinterpret_cast<float*>(image.data); }
        else {
            I = (float*)wrCalloc(static_cast<size_t>(width * height * channels), sizeof(float));
            float* imageData = reinterpret_cast<float*>(image.data);
            float* redChannel = I;
            float* greenChannel = I + width * height;
            float* blueChannel = I + 2 * width * height;

            for (int i = 0; i < height * width; ++i) {
                blueChannel[i] = imageData[i * 3];
                greenChannel[i] = imageData[i * 3 + 1];
                redChannel[i] = imageData[i * 3 + 2];
            }
        }

        // calc fhog in col major - switch width and height
        gradMag(I, M, O, width, height, channels, true);

        if (fhogChannelsToCopy == 27)
        { fhog(M, O, H, width, height, binSize, orientations, -1, 0.2f, false); }
        else
        { fhog(M, O, H, width, height, binSize, orientations, -1, 0.2f); }

        // only copy the amount of the channels the user wants
        // or the amount that fits into the output array
        int channelsToCopy = std::min(fhogChannelsToCopy, OUT::numberOfChannels());

        // init channels
        for (int c = 0; c < channelsToCopy; ++c) {
            cv::Mat_<PRIMITIVE_TYPE> m(heightBin, widthBin);
            cvFeatures->channels[c] = m;
        }

        PRIMITIVE_TYPE* cdata = 0;

        // implicit transpose on every channel due to col-major to row-major matrix
        for (int c = 0; c < channelsToCopy; ++c) {
            float* Hc = H + widthBin * heightBin * c;
            cdata = reinterpret_cast<PRIMITIVE_TYPE*>(cvFeatures->channels[c].data);

            for (int i = 0; i < heightBin * widthBin; ++i)
            { cdata[i] = Hc[i]; }
        }

        wrFree(M);
        wrFree(O);

        if (channels != 1)
        { wrFree(I); }

        wrFree(H);
    }
Пример #7
0
    void cvFhog(const cv::Mat& img, std::shared_ptr<OUT>& cvFeatures, int binSize, int fhogChannelsToCopy = 31) {
        const int orientations = 9;
        // ensure array is continuous
        const cv::Mat& image = (img.isContinuous() ? img : img.clone());
        int channels = image.channels();
        int computeChannels = 32;
        int width = image.cols;
        int height = image.rows;
        int widthBin = width / binSize;
        int heightBin = height / binSize;

        float* const I = (float*)wrCalloc(static_cast<size_t>(width * height * channels), sizeof(float));
        float* const H = (float*)wrCalloc(static_cast<size_t>(widthBin * heightBin * computeChannels), sizeof(float));
        float* const M = (float*)wrCalloc(static_cast<size_t>(width * height), sizeof(float));
        float* const O = (float*)wrCalloc(static_cast<size_t>(width * height), sizeof(float));

        // row major (interleaved) to col major (non interleaved;clustered)
        float* imageData = reinterpret_cast<float*>(image.data);

        float* const redChannel = I;
        float* const greenChannel = I + width * height;
        float* const blueChannel = I + 2 * width * height;
        int colMajorPos = 0, rowMajorPos = 0;

        for (int row = 0; row < height; ++row) {
            for (int col = 0; col < width; ++col) {
                colMajorPos = col * height + row;
                rowMajorPos = row * channels * width + col * channels;

                blueChannel[colMajorPos] = imageData[rowMajorPos];
                greenChannel[colMajorPos] = imageData[rowMajorPos + 1];
                redChannel[colMajorPos] = imageData[rowMajorPos + 2];
            }
        }

        // calc fhog in col major
        gradMag(I, M, O, height, width, channels, true);

        if (fhogChannelsToCopy == 27)
        { fhog(M, O, H, height, width, binSize, orientations, -1, 0.2f, false); }
        else
        { fhog(M, O, H, height, width, binSize, orientations, -1, 0.2f); }

        // only copy the amount of the channels the user wants
        // or the amount that fits into the output array
        int channelsToCopy = std::min(fhogChannelsToCopy, OUT::numberOfChannels());

        for (int c = 0; c < channelsToCopy; ++c) {
            cv::Mat_<PRIMITIVE_TYPE> m(heightBin, widthBin);
            cvFeatures->channels[c] = m;
        }

        PRIMITIVE_TYPE* cdata = 0;

        //col major to row major with separate channels
        for (int c = 0; c < channelsToCopy; ++c) {
            float* Hc = H + widthBin * heightBin * c;
            cdata = reinterpret_cast<PRIMITIVE_TYPE*>(cvFeatures->channels[c].data);

            for (int row = 0; row < heightBin; ++row)
                for (int col = 0; col < widthBin; ++col)

                { cdata[row * widthBin + col] = Hc[row + heightBin * col]; }
        }

        wrFree(M);
        wrFree(O);
        wrFree(I);
        wrFree(H);
    }
Пример #8
0
    void fhogToCol(const cv::Mat& img, cv::Mat& cvFeatures,
        int binSize, int colIdx, PRIMITIVE_TYPE cosFactor)
    {
        const int orientations = 9;
        // ensure array is continuous
        const cv::Mat& image = (img.isContinuous() ? img : img.clone());
        int channels = image.channels();
        int computeChannels = 32;
        int width = image.cols;
        int height = image.rows;
        int widthBin = width / binSize;
        int heightBin = height / binSize;

        CV_Assert(channels == 1 || channels == 3);
        CV_Assert(cvFeatures.channels() == 1 && cvFeatures.isContinuous());

        float* const H = (float*)wrCalloc(static_cast<size_t>(widthBin * heightBin * computeChannels), sizeof(float));
        float* const I = (float*)wrCalloc(static_cast<size_t>(width * height * channels), sizeof(float));
        float* const M = (float*)wrCalloc(static_cast<size_t>(width * height), sizeof(float));
        float* const O = (float*)wrCalloc(static_cast<size_t>(width * height), sizeof(float));

        // row major (interleaved) to col major (non-interleaved;clustered;block)
        float* imageData = reinterpret_cast<float*>(image.data);

        float* const redChannel = I;
        float* const greenChannel = I + width * height;
        float* const blueChannel = I + 2 * width * height;
        int colMajorPos = 0, rowMajorPos = 0;

        for (int row = 0; row < height; ++row)
        {
            for (int col = 0; col < width; ++col)
            {
                colMajorPos = col * height + row;
                rowMajorPos = row * channels * width + col * channels;

                blueChannel[colMajorPos] = imageData[rowMajorPos];
                greenChannel[colMajorPos] = imageData[rowMajorPos + 1];
                redChannel[colMajorPos] = imageData[rowMajorPos + 2];
            }
        }

        // calc fhog in col major
        gradMag(I, M, O, height, width, channels, true);
        fhog(M, O, H, height, width, binSize, orientations, -1, 0.2f);

        // the order of rows in cvFeatures does not matter
        // as long as it is the same for all columns;
        // zero channel is not copied as it is the last
        // channel in H and cvFeatures rows doesn't include it
        PRIMITIVE_TYPE* cdata = reinterpret_cast<PRIMITIVE_TYPE*>(cvFeatures.data);
        int outputWidth = cvFeatures.cols;

        for (int row = 0; row < cvFeatures.rows; ++row)
            cdata[outputWidth*row + colIdx] = H[row] * cosFactor;

        wrFree(H);
        wrFree(M);
        wrFree(O);
        wrFree(I);
    }
Пример #9
0
    void fhogToCvColT(const cv::Mat& img, cv::Mat& cvFeatures,
        int binSize, int colIdx, PRIMITIVE_TYPE cosFactor)
    {
        const int orientations = 9;
        // ensure array is continuous
        const cv::Mat& image = (img.isContinuous() ? img : img.clone());
        int channels = image.channels();
        int computeChannels = 32;
        int width = image.cols;
        int height = image.rows;
        int widthBin = width / binSize;
        int heightBin = height / binSize;

        CV_Assert(channels == 1 || channels == 3);
        CV_Assert(cvFeatures.channels() == 1 && cvFeatures.isContinuous());

        float* const H = (float*)wrCalloc(static_cast<size_t>(widthBin * heightBin * computeChannels), sizeof(float));
        float* const M = (float*)wrCalloc(static_cast<size_t>(width * height), sizeof(float));
        float* const O = (float*)wrCalloc(static_cast<size_t>(width * height), sizeof(float));

        float* I = NULL;

        if (channels == 1)
            I = reinterpret_cast<float*>(image.data);
        else
        {
            I = (float*)wrCalloc(static_cast<size_t>(width * height * channels), sizeof(float));
            float* imageData = reinterpret_cast<float*>(image.data);
            float* redChannel = I;
            float* greenChannel = I + width * height;
            float* blueChannel = I + 2 * width * height;

            for (int i = 0; i < height * width; ++i)
            {
                blueChannel[i] = imageData[i * 3];
                greenChannel[i] = imageData[i * 3 + 1];
                redChannel[i] = imageData[i * 3 + 2];
            }
        }

        // calc fhog in col major - switch width and height
        gradMag(I, M, O, width, height, channels, true);
        fhog(M, O, H, width, height, binSize, orientations, -1, 0.2f);

        // the order of rows in cvFeatures does not matter
        // as long as it is the same for all columns;
        // zero channel is not copied as it is the last
        // channel in H and cvFeatures rows doesn't include it
        PRIMITIVE_TYPE* cdata = reinterpret_cast<PRIMITIVE_TYPE*>(cvFeatures.data);
        int outputWidth = cvFeatures.cols;

        for (int row = 0; row < cvFeatures.rows; ++row)
            cdata[outputWidth*row + colIdx] = H[row] * cosFactor;

        wrFree(H);
        wrFree(M);
        wrFree(O);

        if (channels != 1)
            wrFree(I);
    }
// M=gradientMex('gradientMag',I,channel,full); ou [M,O] = gradientMex('gradientMag',I,channel,full);
// if(!strcmp(action,"gradientMag")) mGradMag(nl,pl,nr,pr);
std::vector<float*> GradientMagnitudeChannel::mGradMag(float* source, int rows, int cols, int channel)
{
  /*
  int h, w, d, c, full; 
  float *I, *M, *O=0;
  checkArgs(nl,pl,nr,pr,1,2,3,3,&h,&w,&d,mxSINGLE_CLASS,(void**)&I);
  */

  /*
  void checkArgs( int nl, mxArray *pl[], int nr, const mxArray *pr[], int nl0, int nl1, int nr0, int nr1, int *h, int *w, int *d, mxClassID id, void **I )
  {
    const int *dims; int nDims;
    if( nl<nl0 || nl>nl1 ) mexErrMsghTxt("Incorrect number of outputs.");
    if( nr<nr0 || nr>nr1 ) mexErrMsgTxt("Incorrect number of inputs.");
    nDims = mxGetNumberOfDimensions(pr[0]); 
    dims = mxGetDimensions(pr[0]);
    *h=dims[0]; *w=dims[1]; 
    *d=(nDims==2) ? 1 : dims[2]; 
    *I = mxGetPr(pr[0]); // I recebe o valor de pr[0] (que é o I dentro do Matlab)
    if( nDims!=2 && nDims!=3 ) mexErrMsgTxt("I must be a 2D or 3D array.");
    if( mxGetClassID(pr[0])!=id ) mexErrMsgTxt("I has incorrect type.");
  }
  */

  // h = I.rows, w = I.cols
  // nDims =  mxGetNumberOfDimensions(pr[0]);
  // dims = mxGetDimensions(pr[0]);
  // if (nDims == 2) d = 1; else d = dims[2];
  // c = pr[1];


  int h = rows, w = cols, c = channel, d = 3; 
  float *M, *O=0;
  float *I = source;
  std::vector<float*> result(2);
  
  /*
  if(h<2 || w<2) mexErrMsgTxt("I must be at least 2x2.");
  c = (int) mxGetScalar(pr[1]); 
  full = (int) mxGetScalar(pr[2]);
  */
	if (h>=2 && w>=2)
	{
    // if( c>0 && c<=d ) { I += h*w*(c-1); d=1; }
		if (c>0 && c<=d)
		{
      // does this modify the input?
			I += h*w*(c-1); 
      d=1;
		}

    // pl[0] = mxCreateMatrix3(h,w,1,mxSINGLE_CLASS,0,(void**)&M);
    M = (float*)malloc(h*w*1*sizeof(float));

    // if(nl>=2) pl[1] = mxCreateMatrix3(h,w,1,mxSINGLE_CLASS,0,(void**)&O);
    O = (float*)malloc(h*w*1*sizeof(float));

    // gradMag(I, M, O, h, w, d, full>0 );
		// call to the actual function: gradMag(I, M, O, h, w, d, full>0 );
		// void gradMag(float*, float*, float*, int, int, int, bool);
    gradMag(I, M, O, h, w, d, full>0);

		// next, we assign the values of M and O to the matrix thats going to be returned
    result[0] = M;
    result[1] = O;
	}
	else
	{
		//error: matrix I must be at least 2x2
    std::cout << " # mGradMag error: provided matrix should have two dimensions!" << std::endl;
	}

	return result;
}