Пример #1
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);
    }
Пример #2
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); }
    }
Пример #3
0
// pad A by [pt,pb,pl,pr] and store result in B
template<class T> void imPad( T *A, T *B, int h, int w, int d, int pt, int pb,
  int pl, int pr, int flag, T val )
{
  int h1=h+pt, hb=h1+pb, w1=w+pl, wb=w1+pr, x, y, z, mPad;
  int ct=0, cb=0, cl=0, cr=0;
  if(pt<0) { ct=-pt; pt=0; } if(pb<0) { h1+=pb; cb=-pb; pb=0; }
  if(pl<0) { cl=-pl; pl=0; } if(pr<0) { w1+=pr; cr=-pr; pr=0; }
  int *xs, *ys; x=pr>pl?pr:pl; y=pt>pb?pt:pb; mPad=x>y?x:y;
  bool useLookup = ((flag==2 || flag==3) && (mPad>h || mPad>w))
    || (flag==3 && (ct || cb || cl || cr ));
  // helper macro for padding
  #define PAD(XL,XM,XR,YT,YM,YB) \
  for(x=0;  x<pl; x++) for(y=0;  y<pt; y++) B[x*hb+y]=A[(XL+cl)*h+YT+ct]; \
  for(x=0;  x<pl; x++) for(y=pt; y<h1; y++) B[x*hb+y]=A[(XL+cl)*h+YM+ct]; \
  for(x=0;  x<pl; x++) for(y=h1; y<hb; y++) B[x*hb+y]=A[(XL+cl)*h+YB-cb]; \
  for(x=pl; x<w1; x++) for(y=0;  y<pt; y++) B[x*hb+y]=A[(XM+cl)*h+YT+ct]; \
  for(x=pl; x<w1; x++) for(y=h1; y<hb; y++) B[x*hb+y]=A[(XM+cl)*h+YB-cb]; \
  for(x=w1; x<wb; x++) for(y=0;  y<pt; y++) B[x*hb+y]=A[(XR-cr)*h+YT+ct]; \
  for(x=w1; x<wb; x++) for(y=pt; y<h1; y++) B[x*hb+y]=A[(XR-cr)*h+YM+ct]; \
  for(x=w1; x<wb; x++) for(y=h1; y<hb; y++) B[x*hb+y]=A[(XR-cr)*h+YB-cb];
  // build lookup table for xs and ys if necessary
  if( useLookup ) {
    xs = (int*) wrMalloc(wb*sizeof(int)); int h2=(pt+1)*2*h;
    ys = (int*) wrMalloc(hb*sizeof(int)); int w2=(pl+1)*2*w;
    if( flag==2 ) {
      for(x=0; x<wb; x++) { z=(x-pl+w2)%(w*2); xs[x]=z<w ? z : w*2-z-1; }
      for(y=0; y<hb; y++) { z=(y-pt+h2)%(h*2); ys[y]=z<h ? z : h*2-z-1; }
    } else if( flag==3 ) {
      for(x=0; x<wb; x++) xs[x]=(x-pl+w2)%w;
      for(y=0; y<hb; y++) ys[y]=(y-pt+h2)%h;
    }
  }
  // pad by appropriate value
  for( z=0; z<d; z++ ) {
    // copy over A to relevant region in B
    for( x=0; x<w-cr-cl; x++ )
      memcpy(B+(x+pl)*hb+pt,A+(x+cl)*h+ct,sizeof(T)*(h-ct-cb));
    // set boundaries of B to appropriate values
    if( flag==0 && val!=0 ) { // "constant"
      for(x=0;  x<pl; x++) for(y=0;  y<hb; y++) B[x*hb+y]=val;
      for(x=pl; x<w1; x++) for(y=0;  y<pt; y++) B[x*hb+y]=val;
      for(x=pl; x<w1; x++) for(y=h1; y<hb; y++) B[x*hb+y]=val;
      for(x=w1; x<wb; x++) for(y=0;  y<hb; y++) B[x*hb+y]=val;
    } else if( useLookup ) { // "lookup"
      PAD( xs[x], xs[x], xs[x], ys[y], ys[y], ys[y] );
    } else if( flag==1 ) {  // "replicate"
      PAD( 0, x-pl, w-1, 0, y-pt, h-1 );
    } else if( flag==2 ) { // "symmetric"
      PAD( pl-x-1, x-pl, w+w1-1-x, pt-y-1, y-pt, h+h1-1-y );
    } else if( flag==3 ) { // "circular"
      PAD( x-pl+w, x-pl, x-pl-w, y-pt+h, y-pt, y-pt-h );
    }
    A += h*w;  B += hb*wb;
  }
  if( useLookup ) { wrFree(xs); wrFree(ys); }
  #undef PAD
}
Пример #4
0
// compute HOG features
void hog( float *M, float *O, float *H, int h, int w, int binSize,
  int nOrients, int softBin, bool full, float clip )
{
  float *N, *R; const int hb=h/binSize, wb=w/binSize, nb=hb*wb;
  // compute unnormalized gradient histograms
  R = (float*) wrCalloc(wb*hb*nOrients,sizeof(float));
  gradHist( M, O, R, h, w, binSize, nOrients, softBin, full );
  // compute block normalization values
  N = hogNormMatrix( R, nOrients, hb, wb, binSize );
  // perform four normalizations per spatial block
  hogChannels( H, R, N, hb, wb, nOrients, clip, 0 );
  wrFree(N); wrFree(R);
}
Пример #5
0
// compute FHOG features
void fhog( float *M, float *O, float *H, int h, int w, int binSize,
  int nOrients, int softBin, float clip )
{
  const int hb=h/binSize, wb=w/binSize, nb=hb*wb, nbo=nb*nOrients;
  float *N, *R1, *R2; int o, x;
  // compute unnormalized constrast sensitive histograms
  R1 = (float*) wrCalloc(wb*hb*nOrients*2,sizeof(float));
  gradHist( M, O, R1, h, w, binSize, nOrients*2, softBin, true );
  // compute unnormalized contrast insensitive histograms
  R2 = (float*) wrCalloc(wb*hb*nOrients,sizeof(float));
  for( o=0; o<nOrients; o++ ) for( x=0; x<nb; x++ )
    R2[o*nb+x] = R1[o*nb+x]+R1[(o+nOrients)*nb+x];
  // compute block normalization values
  N = hogNormMatrix( R2, nOrients, hb, wb, binSize );
  // normalized histograms and texture channels
  hogChannels( H+nbo*0, R1, N, hb, wb, nOrients*2, clip, 1 );
  hogChannels( H+nbo*2, R2, N, hb, wb, nOrients*1, clip, 1 );
  hogChannels( H+nbo*3, R1, N, hb, wb, nOrients*2, clip, 2 );
  wrFree(N); mxFree(R1); wrFree(R2);
}
Пример #6
0
// compute HOG features given gradient histograms
void hog( float *H, float *G, int h, int w, int bin, int nOrients, float clip ){
  float *N, *N1, *H1; int o, x, y, hb=h/bin, wb=w/bin, nb=wb*hb;
  float eps = 1e-4f/4/bin/bin/bin/bin; // precise backward equality
  // compute 2x2 block normalization values
  N = (float*) wrCalloc(nb,sizeof(float));
  for( o=0; o<nOrients; o++ ) for( x=0; x<nb; x++ ) N[x]+=H[x+o*nb]*H[x+o*nb];
  for( x=0; x<wb-1; x++ ) for( y=0; y<hb-1; y++ ) {
    N1=N+x*hb+y; *N1=1/float(sqrt( N1[0] + N1[1] + N1[hb] + N1[hb+1] +eps )); }
  // perform 4 normalizations per spatial block (handling boundary regions)
  #define U(a,b) Gs[a][y]=H1[y]*N1[y-(b)]; if(Gs[a][y]>clip) Gs[a][y]=clip;
  for( o=0; o<nOrients; o++ ) for( x=0; x<wb; x++ ) {
    H1=H+o*nb+x*hb; N1=N+x*hb; float *Gs[4]; Gs[0]=G+o*nb+x*hb;
    for( y=1; y<4; y++ ) Gs[y]=Gs[y-1]+nb*nOrients;
    bool lf, md, rt; lf=(x==0); rt=(x==wb-1); md=(!lf && !rt);
    y=0; if(!rt) U(0,0); if(!lf) U(2,hb);
    if(lf) for( y=1; y<hb-1; y++ ) { U(0,0); U(1,1); }
    if(md) for( y=1; y<hb-1; y++ ) { U(0,0); U(1,1); U(2,hb); U(3,hb+1); }
    if(rt) for( y=1; y<hb-1; y++ ) { U(2,hb); U(3,hb+1); }
    y=hb-1; if(!rt) U(1,1); if(!lf) U(3,hb+1);
  } wrFree(N);
  #undef U
}
void alFree(void *aligned)
{
    void* raw = *(void**)((char*)aligned-sizeof(void*));
    wrFree(raw);
}
Пример #8
0
// platform independent alignned memory de-allocation (see also alMalloc)
inline void alFree(void* aligned) {
    const size_t pSize = sizeof(void*);
    void* raw = *(void**)((char*)aligned - pSize);
    wrFree(raw);
}
Пример #9
0
pyrOutput* chnsPyramid(float *image, pyrInput *input){
/*
 * Declaring variables
 */
    float *I;
    int height = input->sz[0],
	    width = input->sz[1],
	    heightO = input->sz[0],
	    widthO = input->sz[1],
	    channels = input->sz[2];

    int heightOriginal = height, widthOriginal = width;
    int misalign = 1;
    int sOfF = sizeof(float);

/*
 * Get default parameters pPyramid
 */
    if ( !input->complete ){
	if(input->nApprox<0)
	    input->nApprox = input->nPerOct - 1;

	input->pchns->pGradHist->binSize = input->shrink;
	input->pad[0] = round(input->pad[0]/input->shrink) * input->shrink;
	input->pad[1] = round(input->pad[1]/input->shrink) * input->shrink;
	input->minDs[0] = max(input->minDs[0], input->shrink * 4);
	input->minDs[1] = max(input->minDs[1], input->shrink * 4);

	input->complete = true;
    }

/*
 * Convert I to appropriate color space (or simply normalize)
 */
    int cs = input->pchns->pColor->colorSpace;
    I = rgbConvert(image, height*width, channels, cs, 1.0f);
    input->pchns->pColor->colorSpace = orig;

/*
 * Get scales at which to compute features and list of real/approx scales
 */
    float *scales = 0;
    float *scaleshw = 0;
    int nScales = getScales(scales, scaleshw, input->nPerOct, input->nOctUp,
		  input->minDs, input->shrink, input->sz);
    
    //TODO :: WARNING :: This was done in the Dollar's Code
    int isRMax;
    if(true)
	isRMax = 0;
    else
	isRMax = 0 + input->nOctUp * input->nPerOct;
    //TODO :: WARNING :: END
    
    int *isR, *isA, *isN;

    //isR Vector Allocation
    int countIsR = 0;
    for ( int i = isRMax; i < nScales; i += (input->nApprox + 1) )
	countIsR++;
    
    isR = new int[countIsR];

    for ( int i = isRMax, j = 0; i < nScales; j++, i += (input->nApprox + 1) )
	isR[j] = i;

    //isA and isN Vector Allocation
    int countIsA = nScales - countIsR;
    int countIsN = nScales;
    isA = new int[countIsA];
    isN = new int[countIsN];

    for ( int i = 0, auxI = 0; i < nScales; i++){
	bool ok = true;
	for (int j = 0; j < countIsR; j++)
	    if(i == isR[j]){
		ok = false;
		break;
	    }

	if (ok){
	    isA[auxI] = i;
	    auxI++;
	}

	isN[i] = i;
    }

    int *auxIsJ;
    auxIsJ = new int[countIsR + 1];

    auxIsJ[0] = 0;
    auxIsJ[countIsR] = nScales;

    for (int i = 0; i < countIsR - 1; i++)
	auxIsJ[i+1] = floor((isR[i] + 1 + isR[i+1] + 1) / 2); 
    // " +1 " because we are in c++ and the vector already assumes the first
    // element to be index 0.

    for (int i = 0; i < countIsR; i++){
	int minJ = auxIsJ[i];
	int maxJ = auxIsJ[i+1];

	for (int j = minJ; j < maxJ; j++)
	    isN[j] = isR[i];
    }

/*
 * Compute image pyramid [real scales]
 */
    int nTypes = 0;
    imgWrap ***data =  (imgWrap ***) wrCalloc(nScales, sizeof(imgWrap**));

    int shrink = input->shrink;
    float shr[3] = { 0, 0, 0};
    for (int it = 0, i = isR[0]; it < countIsR; it++, i=isR[it]){
	float scale = scales[i];
	int newHeight = round((float) heightO * (float) scale /
			(float) shrink) * shrink;

	int newWidth = round((float) widthO * (float) scale /
			(float) shrink) * shrink;
	
	float *I1;
	if ( height == newHeight && width == newWidth){
	    //TODO :: WARNING :: Should I copy it over?
	    I1 = (float*) wrCalloc(height*width*channels + misalign,
		  sOfF) + misalign;

	    int lengthArray = height*width*channels;
	    for (int j = 0; j < lengthArray; j++)
		    I1[j] = I[j];
	}else{
	    I1 = (float*) wrCalloc(newHeight*newWidth*channels + misalign,
		  sOfF) + misalign;

	    //TODO :: WARNING :: Hardcoded value :: 1.f
	    resample(I, I1, height, newHeight, width, newWidth, channels, 1.f);
	}

	if (scale == 0.5f && (input->nApprox > 0 || input->nPerOct == 1)){
	    //TODO :: WARNING :: Should I free "I"?
	    // I replace old I with new I1, as I reduced the image to half size
	    free(I);

	    I = I1;
	    height = newHeight;
	    width = newWidth;
	}

	//TODO :: WARNING :: Hardcoded value :: downsample
	float *I2 = 0;
	int downsample = 1;
	convTriAux(I1, I2, misalign, newHeight, newWidth, channels,
		input->smoothIm, downsample
		);

	/*
	 * Channels Compute for this isR[i] scale
	 */
	infoOut *chns = chnsCompute(I2, newHeight, newWidth, channels,
			input->pchns
			);

	imgWrap **data1 = chns->data;
	wrFree(I2-misalign);
	nTypes = chns->nTypes;

	if (i == isR[0]){
	    /*
	     * This is checking the size of each transformation. By design only
	     * the H channel will have the correct dimensions.
	     */
	    for (int j = 0; j < nTypes; j++){
		shr[j] = data1[j]->height;
		shr[j] = newHeight / shr[j];

		if (shr[j] > shrink || (int)shr[j] % 1 > 0){
		    cout << "Something went wrong with the shrinking."
			<< endl << "Source code line: " << __FILE__ << " @ "
			<< __LINE__ << endl;
		    return NULL; //This should never happen
		}

		shr[j]=shr[j]/shrink;
	    }
	}

	for(int j = 0; j < nTypes; j++){
	    if (shr[j] == 1)
		continue;

	    int nH = newHeight*shr[j],
		nW = newWidth*shr[j],
		chnsTransform = data1[j]->channels;

	    float *chnTypeData = (float*) wrCalloc(nH*nW*channels + misalign,
				sOfF) + misalign;

	    //TODO :: WARNING :: Hardcoded value :: 1.f
	    resample(data1[j]->image, chnTypeData, newHeight, nH, newWidth, nW,
		    chnsTransform, 1.f
		    );

	    data1[j]->height = nH;
	    data1[j]->width = nW;

	    wrFree(data1[j]->image - misalign);
	    data1[j]->image = chnTypeData;
	}

	data[i] = data1;
    }

    // In case I changed it when scale = 0.5f
    height = heightO;
    width = widthO;

/*
 * If lambdas not specified compute image specific lambdas
 */
    int nApprox = input->nApprox;
    float *lambdas = input->lambdas;
    if ( nApprox > 0 && !lambdas){
	int nOctUp = input->nOctUp;
	int nPerOct = input->nPerOct;

	//TODO :: WARNING :: Yet again I start at 0.
	// The is Vector :: is=1 + nOctUp*nPerOct:nApprox+1:nScales;
	int countIs = 0;

	int *isTemp = new int[nScales];
	for (int i = nOctUp*nPerOct; i < nScales; i += nApprox + 1){
	    isTemp[countIs] = i;
	    countIs++;
	}

	if (countIs > 2){
	    isTemp[0] = isTemp[1];
	    isTemp[1] = isTemp[2];
	}else{
	    cout << "Couldn't calculate lambdas. Not enough scales to use."
		<< endl << "Source code line: " << __FILE__ << " @ "
		<< __LINE__ << endl;
	    return NULL;
	}


	float *f0 = new float[nTypes];
	float *f1 = new float[nTypes];

	imgWrap **d0 = data[isTemp[0]];
	imgWrap **d1 = data[isTemp[1]];

	for (int i = 0; i < nTypes; i++){
	    float numElem = (float)
			    (d0[i]->width * d0[i]->height * d0[i]->channels);

	    float sumElem = 0.f;

	    for (int j = 0; j < numElem; j++)
		sumElem += d0[i]->image[j];

	    f0[i] = sumElem / numElem;
	}

	for (int i = 0; i < nTypes; i++){
	    float numElem = (float)
			    (d1[i]->width * d1[i]->height * d1[i]->channels);

	    float sumElem = 0.f;

	    for (int j = 0; j < numElem; j++)
		sumElem += d1[i]->image[j];

	    f1[i] = sumElem / numElem;
	}


	lambdas = new float[nTypes];
	float lambdaValue = log2(scales[isTemp[0]] / scales[isTemp[1]]);
	for (int i = 0; i < nTypes; i++)
	    lambdas[i] = -log2(f0[i] / f1[i]) / lambdaValue;
    }

/*
 * Compute image pyramid [approximated scales]
 */
    shrink = input->shrink;
    for (int it = 0, i = isA[0]; it < countIsA; it++, i=isA[it]){
	int iR = isN[i];

	float scale = scales[i];

	//TODO :: WARNING :: The value height may have been modified to half of
	//                   it, hence using heightOriginal (width)
	int newHeight = round((float) heightOriginal * (float) scale /
			(float) shrink);
	int newWidth = round((float) widthOriginal * (float) scale /
			(float) shrink);

	float scaleRatio = (scale / scales[iR]);
	float *rs = new float[nTypes];

	for (int j = 0; j < nTypes; j++)
	    rs[j] = pow(scaleRatio, -lambdas[j] );

	imgWrap **dataImgA = (imgWrap **) wrCalloc(nTypes, sizeof(imgWrap*));
	imgWrap **dataImgR = data[iR];

	for (int j = 0; j < nTypes; j++){
	    int ijChannels = dataImgR[j]->channels;

	    float *isAimage = (float*) wrCalloc(newHeight*newWidth*ijChannels +
			    misalign, sOfF) + misalign;

	    //TODO :: WARNING :: Hardcoded value
	    resample(dataImgR[j]->image, isAimage, dataImgR[j]->height,
		    newHeight, dataImgR[j]->width, newWidth, ijChannels, rs[j]);

	    dataImgA[j] = new imgWrap(isAimage, newWidth, newHeight,ijChannels);
	}

	data[i] = dataImgA;
	delete [] rs;
    }

/*
 * Smooth channels, optionally pad and concatenate channels
 */
    int downSample = 1; // WARNING : This is the default by dollar
    int s = downSample;

    for (int i = 0; i < nScales; i++){
	for (int j = 0; j < nTypes; j++){
	    float *S;
	    int height = data[i][j]->height;
	    int width = data[i][j]->width;
	    int channel = data[i][j]->channels;

	    /*
	      * Smoothing Channels
	      */
	    convTriAux(data[i][j]->image, S, misalign, height, width, channel,
			input->smoothChns, s
			);

	    wrFree(data[i][j]->image - misalign);

	    /*
	     * Padding according to the scale. Then change the shrink value.
	     */
	    int padTB = input->pad[0] / shrink,
		padLR = input->pad[1] / shrink;

	    if (padTB > 0 || padLR > 0){
		int newHeight = height + padTB * 2;
		int newWidth = width + padLR * 2;

		float *P = (float*) wrCalloc(newHeight*newWidth*channel +
			    misalign, sOfF) + misalign;

		imPad(S, P, height, width, channel, padTB, padTB, padLR, padLR,
		      padvalue, 0.f
		      );

		wrFree(S - misalign);

		data[i][j]->height = newHeight;
		data[i][j]->width = newWidth;

		S = P;
	    }

	    data[i][j]->image = S;
	}
    }

/*
 * Concatenate.
 */
    int totalChannels = 0;
    for (int j = 0; j < nTypes; j++)
	totalChannels += data[0][j]->channels;

    if(input->concat){
	int chnsArr[nTypes];

	for (int j = 0; j < nTypes; j++)
	    chnsArr[j] = data[0][j]->channels;

	for (int i = 0; i < nScales; i++){
	    int height = data[i][0]->height;
	    int width = data[i][0]->width;

	    float *imgC = (float*) wrCalloc(height*width*totalChannels +
			  misalign, sOfF) + misalign;

	    int totalSize = 0;
	    for (int j = 0; j < nTypes; j++){
		float *imgO = data[i][j]->image;

		copy(imgO, imgO + height*width*chnsArr[j], imgC + totalSize);
		totalSize += height*width*chnsArr[j];
	    }

	    for (int j=1; j < nTypes; j++){
		wrFree(data[i][j]->image - misalign);
		wrFree(data[i][j]);
	    }

	    wrFree(data[i][0]->image - misalign);
	    data[i][0]->image = imgC;
	    data[i][0]->channels = totalChannels;
	}
    }


/*
 * Create output struct
 */
    pyrOutput *output = new pyrOutput();
    output->input = input;
    output->chnsPerScale = data;
    output->nScales =  nScales;
    output->scales = scales;
    output->nChannels = totalChannels;

/*
 * Clean Memory
 */
    delete [] isR;
    delete [] isA;
    delete [] isN;
    delete [] lambdas;
    delete [] scaleshw;

/*
 * Output
 */
    return output;
}
Пример #10
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);
    }
Пример #11
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);
    }