Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

How to get histogram of a rectangular area (ROI) of an image?

What I am trying to accomplish is to read an image from a JPEG file, display it, select a rectangular region, and calculate a histogram of the HSV transform of the image. The book "Learning OpenCV" suggests that setting ROI will cause operations to be performed only on that part of the image, but that doesn't seem to be true for the histogram.

I am an OpenCV novice, and would appreciate any suggestions.

Here is my code:

CvRect ROI;
IplImage *m_cvImage = cvLoadImage( (LPCTSTR)ar.m_strFileName ); // read JPEG image from file
ROI.x=0; ROI.y=0; ROI.width=m_cvImage->width; ROI.height=m_cvImage->height;
// Make the histogram of entire image
CvHistogram *hist;
int err=HueSaturationHistogram(m_cvImage, ROI, false/*visualizeHist*/, hist );
...
// Change ROI according to selection with mouse
// Recalculate the image HSV histogram
HueSaturationHistogram(m_cvImage, ROI, false/*visualizeHist*/, hist);

and the function HueSaturationHistogram is

    HueSaturationHistogram( IplImage* src, const CvRect rect, const bool visualizeHist,
 CvHistogram *& hist )
    {
        // Set the part of the image we will be processing
        cvSetImageROI(src,rect);
        CvSize roiSize; roiSize.width=rect.width; roiSize.height=rect.height;
        // Compute the HSV image, and decompose it into separate planes.
        IplImage* hsv = cvCreateImage( roiSize, 8, 3 ); 
        cvCvtColor( src, hsv, CV_BGR2HSV ); // RGB to HSV (hue, saturation, value)

        IplImage* h_plane  = cvCreateImage( roiSize, 8, 1 );
        IplImage* s_plane  = cvCreateImage( roiSize, 8, 1 );
        IplImage* v_plane  = cvCreateImage( roiSize, 8, 1 );
        IplImage* planes[] = { h_plane, s_plane, v_plane };
        cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );

        // Build the histogram and compute its contents.
        int nH = 30, nS = 32, nV=30; 
        float  h_ranges[2], s_ranges[2], v_ranges[2];   // H is units of 2 deg
        h_ranges[0] = 0; h_ranges[1] = 180; // hue is [0,180], because 0-360 is divided by 2 (i e, units of 2 deg)
        s_ranges[0] = 0, s_ranges[1] = 255; 
        v_ranges[0] = 0; v_ranges[1] = 255; 
        {
        int hist_size[] = { nH, nS, nV };
        float* ranges[] = { h_ranges, s_ranges, v_ranges };
        hist = cvCreateHist( 
        3, 
        hist_size, 
        CV_HIST_ARRAY, 
        ranges, 
        1 // uniform
        ); 
        }
    cvCalcHist( planes, hist, 0, 0 );
    ...
    }

64-bit Windows 7, Visual Studio 10, C++