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; }
// [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 ); }
/* 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); }
//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; }
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); }
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); }
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); }
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); }
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; }