Ask Your Question

stuff273's profile - activity

2015-12-12 10:51:59 -0600 commented question lbp c++ how does spatial_histogram work?

Is there a way of doing this in java? In my implementation, result stays a Mat of all 0s. How would I update a specific row in java?

2015-12-12 10:36:16 -0600 asked a question lbp c++ how does spatial_histogram work?

I'm working on getting a java implementation of OpenCV's lbp histogram generation. I think I'm making progress, but I don't know what's happening with a specific function in OpenCV's code: spatial_histogram (the code can be found here). The code is as follows:

static Mat spatial_histogram(InputArray _src, int numPatterns,
                         int grid_x, int grid_y, bool /*normed*/)
{
    Mat src = _src.getMat();
    // calculate LBP patch size
    int width = src.cols/grid_x;
    int height = src.rows/grid_y;
    // allocate memory for the spatial histogram
    Mat result = Mat::zeros(grid_x * grid_y, numPatterns, CV_32FC1);
    // return matrix with zeros if no data was given
    if(src.empty())
        return result.reshape(1,1);
    // initial result_row
    int resultRowIdx = 0;
    // iterate through grid
    for(int i = 0; i < grid_y; i++) {
        for(int j = 0; j < grid_x; j++) {
            Mat src_cell = Mat(src, Range(i*height,(i+1)*height), Range(j*width,(j+1)*width));
            Mat cell_hist = histc(src_cell, 0, (numPatterns-1), true);
            // copy to the result matrix
            Mat result_row = result.row(resultRowIdx);
            cell_hist.reshape(1,1).convertTo(result_row, CV_32FC1);
            // increase row count in result matrix
            resultRowIdx++;
        }
    }
    // return result as reshaped feature vector
    return result.reshape(1,1);
}

I'm specifically confused about the Mat result because after it's set to all 0s, it doesn't ever seem to be changed. These lines say that they are used to copy to the result matrix...

// copy to the result matrix
Mat result_row = result.row(resultRowIdx);
cell_hist.reshape(1,1).convertTo(result_row, CV_32FC1);

But I'm not quite understanding how this works unless result_row points to the specific row in result... is that what is going on here? If so, how could I do something like this in Java. Below is the code I have so far:

private Mat spatialHistogram(Mat src, int numPatterns)
{
    Log.d(TAG, "spatialHistogram started");
    int width = src.cols() / grid_x;
    int height = src.rows() / grid_y;

    Mat result = Mat.zeros(grid_x * grid_y, numPatterns, CvType.CV_32FC1);

    src.convertTo(src, CvType.CV_32FC1);

    if (src.empty())
    {
        Log.e(TAG, "Image is empty.");
    } else
    {
        int resultRowIdx = 0;
        for (int i = 0; i < grid_y; i++)
        {
            for (int j = 0; j < grid_x; j++)
            {
                Mat src_cell = new Mat(src, new Range(i * height, (i + 1) * height), new Range(j * width, (j + 1) * width));
                Mat cell_hist = histc(src_cell.clone(), 0, (numPatterns - 1));

                //TODO: FIX
                Mat result_row = result.row(resultRowIdx);
                cell_hist.reshape(1, 1).convertTo(result_row, CvType.CV_32FC1);              
                resultRowIdx++;
            }
        }
    }

    Log.d(TAG, "spatialHistogram ended");
    return result.reshape(1, 1);
}

Advice on this code's working would be greatly appreciated, because the result Mat that is returned in my java implementation is just a Mat full of 0s.

2015-12-09 22:35:36 -0600 asked a question android histogram all zeros

I'm trying to generate a histogram based off a Mat that I have. The Mat is of size 524x700 and contains numbers from 0-255. Now when I try and run Imgproc.calcHist I am returned a Mat of size 1x25. This is fine, but the the only data in the histogram is the very first value while the remaining values are 0. Is there any reason for this? My code is shown below: (*dst is of type CvType.CV_32FC1.

MatOfInt channels = new MatOfInt(0);
Mat hist = new Mat();
MatOfInt mHistSize = new MatOfInt(HISTOGRAMSIZE);
MatOfFloat mRanges = new MatOfFloat(0f, 255f);

Imgproc.calcHist(Arrays.asList(dst), channels, new Mat(), hist, mHistSize, mRanges);

for (int i = 0; i < hist.rows(); i++)
{
    double[] data2 = hist.get(i, 0);
    for (int k = 0; k < data2.length; k++)
    {
        String log = "hist_data:\t" + data2[k];
        Log.d(TAG, log);
    }
}

And the for loop outputs:

hist_data: 222768.0
hist_data: 0.0
hist_data: 0.0
hist_data: 0.0
.
.
.

And there are 24 0s that appear.

2015-12-09 22:35:35 -0600 asked a question How to properly do LBP histogram creation in Android?

I'm currently working on a face detection and recognition algorithm on my Android device. I'm having a hard time properly generating a histogram through LBP. I found the c++ source code for lbp here and I've been trying (with some success) to get this to work on my Android device. Mostly I've been trying to convert these lines into something I can use in Android.

// calculate lbp image
Mat lbp_image = elbp(src[sampleIdx], _radius, _neighbors);
// get spatial histogram from this lbp image
Mat p = spatial_histogram(
        lbp_image, /* lbp_image */
        static_cast<int>(std::pow(2.0, static_cast<double>(_neighbors))), /* number of possible patterns */
        _grid_x, /* grid size x */
        _grid_y, /* grid size y */
        true);

For the first function used - elbp - I have created this code which SEEMS to work fine:

JNIEXPORT void JNICALL
Java_edu_mst_nsh9b3_privacypreservingfaceauthentication_AuthenticateFace_nativeCreateLBPHistorgram
    (JNIEnv *jenv, jclass, jlong _src, jlong _dst, jint radius, jint neighbors)
{
LOGD("PPFA_Native_LBPHistogram_CreateLBPHistorgram: start");

Mat* src = (Mat*)_src;
Mat* dst = (Mat*)_dst;

dst->setTo(0);

for(int n = 0; n < neighbors; n++)
{
    // sample points
    float x = static_cast<float>(radius * cos(2.0*CV_PI*n/static_cast<float>(neighbors)));
    float y = static_cast<float>(-radius * sin(2.0*CV_PI*n/static_cast<float>(neighbors)));
    // relative indices
    int fx = static_cast<int>(floor(x));
    int fy = static_cast<int>(floor(y));
    int cx = static_cast<int>(ceil(x));
    int cy = static_cast<int>(ceil(y));
    // fractional part
    float ty = y - fy;
    float tx = x - fx;
    // set interpolation weights
    float w1 = (1 - tx) * (1 - ty);
    float w2 =      tx  * (1 - ty);
    float w3 = (1 - tx) *      ty;
    float w4 =      tx  *      ty;

    // iterate through your data
    for(int i=radius; i < src->rows-radius;i++) {
        for(int j=radius;j < src->cols-radius;j++) {
            // calculate interpolated value
            float t = static_cast<float>(w1*src->at<unsigned char>(i+fy,j+fx) + w2*src->at<unsigned char>(i+fy,j+cx) + w3*src->at<unsigned char>(i+cy,j+fx) + w4*src->at<unsigned char>(i+cy,j+cx));
            // floating point precision, so check some machine-dependent epsilon
            dst->at<int>(i-radius,j-radius) += ((t > src->at<unsigned char>(i,j)) || (std::abs(t-src->at<unsigned char>(i,j)) < std::numeric_limits<float>::epsilon())) << n;
        }
    }
}

LOGD("PPFA_Native_LBPHistogram_CreateLBPHistorgram: end");
return;
}

The second function is where I'm having problems:

JNIEXPORT void JNICALL
Java_edu_mst_nsh9b3_privacypreservingfaceauthentication_AuthenticateFace_nativeSpatialHistogram
(JNIEnv *, jclass, jlong _src, jlong _result, jint numPatterns, jint grid_x, jint grid_y)
{
LOGD("PPFA_Native_LBPHistogram_SpatialHistogram: start");

Mat* src = (Mat*)_src;
Mat* result = (Mat*)_result;

int width = src->cols/grid_x;
int height = src->rows/grid_y;

if(src->empty())
{
    LOGD("PPFA_Native_LBPHistogram_SpatialHistogram: empty");
    result->reshape(1, 1);
    return;
}

int resultRowIdx = 0;

for(int i = 0; i < grid_y; i++) {
    for(int j = 0; j < grid_x; j++) {
        Mat src_cell = Mat_<float>(*src, Range(i*height,(i+1)*height), Range(j*width,(j+1)*width));

        // histc function
        Mat cell_hist;

        int histSize = numPatterns - 1;
        float range[] = { static_cast<float>(0), static_cast<float>(numPatterns)};
        const float* histRange {range};
        int channels[] = {0};

        calcHist(&src_cell, 1, channels, Mat(), cell_hist, 1, &histSize, &histRange, true, false);

        cell_hist.reshape(1,1);
        //

        //copy to the result matrix
        Mat result_row = result->row(resultRowIdx);
        cell_hist.reshape(1,1).convertTo(result_row, CV_32FC1);

        //increase row ...
(more)