void fhog(const cv::Mat& image, vector<Mat>& fhogs, int binSize, int orientations) { assert(image.type() == CV_32F || image.type() == CV_32FC3); assert(image.isContinuous()); float *M = new float[image.rows * image.cols]; float *O = new float[image.rows * image.cols]; int hb = image.rows / binSize; int wb = image.cols / binSize; int nChannls = orientations * 3 + 5; float *H = new float[hb * wb * nChannls]; fill_n(H, hb * wb * nChannls, 0); gradientMagnitude(image, M, O); fhog(M, O, H, image.rows, image.cols, binSize, orientations, -1, 0.2f); for (size_t i = 0; i < nChannls; i++) { Mat tmp(Size(wb, hb), CV_32FC1); Matlab2OpenCVC1(H + ( i * (wb * hb)), tmp); fhogs.push_back(tmp); } delete[] H; delete[] M; delete[] O; }
// H=gradHist(M,O,[...]) - see gradientHist.m void mGradHist( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) { int h, w, d, hb, wb, nChns, binSize, nOrients, softBin, useHog; bool full; float *M, *O, *H, clipHog; checkArgs(nl,pl,nr,pr,1,3,2,8,&h,&w,&d,mxSINGLE_CLASS,(void**)&M); O = (float*) mxGetPr(pr[1]); if( mxGetM(pr[1])!=h || mxGetN(pr[1])!=w || d!=1 || mxGetClassID(pr[1])!=mxSINGLE_CLASS ) mexErrMsgTxt("M or O is bad."); binSize = (nr>=3) ? (int) mxGetScalar(pr[2]) : 8; nOrients = (nr>=4) ? (int) mxGetScalar(pr[3]) : 9; softBin = (nr>=5) ? (int) mxGetScalar(pr[4]) : 1; useHog = (nr>=6) ? (int) mxGetScalar(pr[5]) : 0; clipHog = (nr>=7) ? (float) mxGetScalar(pr[6]) : 0.2f; full = (nr>=8) ? (bool) (mxGetScalar(pr[7])>0) : false; hb = h/binSize; wb = w/binSize; nChns = useHog== 0 ? nOrients : (useHog==1 ? nOrients*4 : nOrients*3+5); pl[0] = mxCreateMatrix3(hb,wb,nChns,mxSINGLE_CLASS,1,(void**)&H); if( nOrients==0 ) return; if( useHog==0 ) { gradHist( M, O, H, h, w, binSize, nOrients, softBin, full ); } else if(useHog==1) { hog( M, O, H, h, w, binSize, nOrients, softBin, full, clipHog ); } else { fhog( M, O, H, h, w, binSize, nOrients, softBin, clipHog ); } }
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); } }
void fhog(const cv::Mat& image, Mat& fhogs, int binSize, int orientations) { assert(image.type() == CV_32F || image.type() == CV_32FC3); float *M = new float[image.rows * image.cols]; float *O = new float[image.rows * image.cols]; int hb = image.rows / binSize; int wb = image.cols / binSize; int nChannls = orientations * 3 + 5; float *H = new float[hb * wb * nChannls]; gradientMagnitude(image, M, O); fhog(M, O, H, image.rows, image.cols, binSize, orientations, -1, 0.2f); fhogs = Mat::zeros(Size(wb, hb), CV_32FC(nChannls)); Matlab2OpenCV(H, fhogs); delete [] H; delete [] M; delete [] O; }
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); }