Ask Your Question

Revision history [back]

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.