Ask Your Question

calcHist() usage for RGB histogram...?

The code:


int imgCount = 1;
int dims = 3;
const int sizes[] = {256,256,256};
const int channels[] = {0,1,2};
float* rRange = {0,256};
float* gRange = {0,256};
float* bRange = {0,256};
const float ranges[] = {rRange,gRange,bRange};
Mat mask = Mat();

calcHist(src, imgCount, channels, mask, hist, dims, sizes, ranges);


Produces "error: No matching function..." among other errors..

What are my mistakes?

edit retag close merge delete

2 answers

Sort by ยป oldest newest most voted
int imgCount = 1;
int dims = 3;
const int sizes[] = {256,256,256};
const int channels[] = {0,1,2};
float rRange[] = {0,256};
float gRange[] = {0,256};
float bRange[] = {0,256};
const float *ranges[] = {rRange,gRange,bRange};
Mat mask = Mat();
calcHist(&src, imgCount, channels, mask, hist, dims, sizes, ranges);

more

Comments

1

lol, i bet your next question is : how do i access a 3d-Matrix ?

(i got no idea)

( 2013-05-27 03:09:43 -0500 )edit

@berak lol. Me wishful thinks I'll manage... :) I just need the MAX and some gray-ish local MAXs, in my attempt to be rid of the damn shadows! They are ruining the canny!

( 2013-05-27 03:21:06 -0500 )edit
1

shadows are a tough problem to deal with in this kind of task... There are lots of paper about it

( 2013-05-27 04:11:39 -0500 )edit

@yes123 Yes I ""understand"" how tough this subject is, by looking around.. In my case though, it is a shadow of a person (not wearing gray scale clothing :) cast on a "white" wall. If I floodFill the MAX of the histogram with correct diffs, in points valued gray-ish local MAXs (of the histogram), I might make the shadows almost disappear.. Then I could maybe succeed in the canny of the person. The big question is: How can the algorithm pick aprox. 1 point from each shadow region, so floodFill wouldn't run 10000 times...?

( 2013-05-27 04:27:40 -0500 )edit
1

i am still having problems with the calcHist... i can use the function with 1D and 2D histograms, however when u try to use on BGR images as described above, the code crashes.

I am using exactly the same code above, tried also with an empty image (cv::Mat image2 = cv::Mat::zeros(10, 10, CV_8UC3);) to discard the possibility of a corrupted input image.

supose it is a bug with the current version (2.4.5), don't know exactly. i am using visual studio ultimate 2012 by the way, and the crash is "Unhandled exception at 0x77CF18D0 (ntdll.dll)" The call stack shows "msvcr110.dll!free(void * pBlock)" in the next line.

so, anyone with a similar problem? anyone who uses vs2012 achieved to pass through the calcHist?

( 2013-06-28 12:03:06 -0500 )edit

@lucas i am having same problem on ios framework too.

( 2013-12-13 03:49:41 -0500 )edit

I think that it could be an answer how tou calcHist. I don't know how to make slice using opencv functions even using this post

#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/videoio/videoio.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char **argv)
{
#define NBBIN 256
Mat m=imread("f:/lib/opencv/samples/data/lena.jpg",CV_LOAD_IMAGE_ANYCOLOR);
vector<int> hManual(0xFFFFFF);
int scale[]={2,4,8};
// My own histogram to check
for (int i=0;i<m.rows;i++)
for (int j = 0; j < m.cols; j++)
{
Vec3b v=m.at<Vec3b>(j,i);
hManual[v[0] / scale[0] +256*(v[1] / scale[1]) +65536*(v[2] / scale[2])]++;
}
const int indCanaux[] = {0,1,2 };
Mat histo3d;
const int bins[] = { NBBIN / scale[0],NBBIN / scale[1],NBBIN/scale[2] };
float etenduI[2] = { 0,NBBIN };
float etenduJ[2] = { 0,NBBIN };
float etenduK[2] = { 0,NBBIN };
float *lEtendu[]={ etenduI,etenduJ,etenduK};

calcHist(&m,1, indCanaux,Mat(),histo3d,3,bins, (const float **)lEtendu,true,false);

Range rangesHisto[] = { Range(0,bins[0]), Range(0,bins[1]),Range(0,bins[2]) };
int nbManual=0,nb2dnz=0,nb3dnz=0,nbPb=0,nbPbBis=0;
float   max=0;
int nbPixel2d=0,nbPixel3d=0;
cout << "Size 0 = " << histo3d.size[0] << "\n";
cout << "Size 1 = " << histo3d.size[1] << "\n";
cout << "Size 2 = " << histo3d.size[2] << "\n";
for (int i = 0; i < bins[0]; i++)
{
Mat coupe;
rangesHisto[0] = cv::Range(i, i + 1);
coupe = histo3d(rangesHisto).clone();
if (i==0)
{
cout << "Size 0 = " << coupe.size[0] << "\n";
cout << "Size 1 = " << coupe.size[1] << "\n";
cout << "Size 2 = " << coupe.size[2] << "\n";
}
Mat histo2d(2, &(histo3d.size[1]), histo3d.type());
coupe.copySize(histo2d);
{
for (int j = 0; j<bins[1]; j ++)
for (int k = 0; k<bins[2]; k ++)
if (histo3d.type()==CV_32S  )
{
float h2d = histo2d.at<int>(j, i), h3d = histo3d.at<int>(k, j, i);
if (h2d > 0)
nb2dnz++;
if (h3d > 0)
nb3dnz++;
if (h3d>max)
max=h3d;
if (h3d != h2d)
nbPb++;
if (h3d!=hManual[i+j*256+k*65536])
nbPbBis++;
nbPixel3d += h3d;
nbPixel2d += h2d;
}
else
if (histo3d.type() == CV_32F  )
{
float h2d= histo2d.at<float>(j,k),h3d= histo3d.at<float>(i,j,k),hM= hManual[i + j * 256 + k * 65536];
if (h2d > 0)
nb2dnz++;
if (h3d > 0)
nb3dnz++;
if (h3d>max)
max = h3d;
if (h3d != h2d)
nbPb++;
if (abs(h3d-hM)>1)
nbPbBis++;
nbPixel3d += h3d;
nbPixel2d += h2d;
}
}
}
cout<<"Using slice Voxel != 0 ==> "<< nb2dnz <<"\n"<<"Using histo3d Voxel !=0 ==> "<< nb3dnz <<"\n";
cout << "Using slice Voxel !=  Using histo3d Voxel ==> " << nbPb << "\n";
cout << "Using slice Voxel in histogram  ==> " << nbPixel2d << "\n";
cout << "Using  histo3d Voxel in histogram  ==> " << nbPixel3d << "\n";
cout << "Using histo3d Voxel!=manual  ==> " << nbPbBis << "\n";
cout<<"max = "<<max<<"\n";
int indPlan=0;
Mat plan(bins[0], bins[1],CV_32FC1);
for (int i = 0; i<bins[0]; i++)
for (int j = 0; j<bins[1]; j++)
plan.at<float>(i,j) = i/256.0;
imshow("Plane Histo", plan);
waitKey();
for (int i = 0; i<bins[0 ...
more

Stats

Asked: 2013-05-27 02:17:41 -0500

Seen: 9,799 times

Last updated: Dec 29 '15