我在写直方图规定化的代码过程中,发现OpenCV自带的cvCalcHist函数计算出的直方图的第255分量总是为0,测试了几张图都是这样,代码如下:
#include <opencv2/opencv.hpp>
#include <opencv2/legacy/compat.hpp>
#include <fstream>
using namespace std;
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
CvHistogram* CreateGrayImageHist(IplImage **ppImage)
{
int nHistSize = 256; //这句话表明有256个灰度级
float fRange[] = {0, 255}; //灰度级的范围是0到255
float *pfRanges[] = {fRange}; //下一句使用的cvCreateHist函数要求第四个参数是指针的指针,
//所以要作这样的处理,至于为什么要用指针的指针,我也不清楚
CvHistogram *pcvHistogram = cvCreateHist(1, &nHistSize, CV_HIST_ARRAY, pfRanges); //在使用直方图计算函数cvCalcHist前,
//需要先创建cvCalcHist的第二个参数需要数据类型
cvCalcHist(ppImage, pcvHistogram);//直方图计算函数cvCalcHist,注意第一个参数要求是指针的指针,具体为什么要这样,我也不清楚
//至于怎么取用存放在pcvHistogram中的直方图数据,看完下面的main函数就知道了
return pcvHistogram;
}
int main()
{
IplImage *a = cvLoadImage("coins.png", CV_LOAD_IMAGE_UNCHANGED);
CvHistogram *a_hist = CreateGrayImageHist(&a);// CreateGrayImageHist是自己写的函数哦
int index;
double watch_a_hist[256];
for (index = 0; index<256; index++)
{
watch_a_hist[index] = cvQueryHistValue_1D(a_hist,index);
}
return 0;
}
后来我又用OpenCV2.4.9中的 cv::calcHist计算出的255级灰度个数仍然为0,测试几张图也都是这样!所以OpenCV的这个直方图计算函数真心不能用了!
和MATLAB运行结果的对比截图如下:
于是自己写了一个直方图计算函数,经测试,无误 ,代码如下:
void mycvCalcHist(IplImage *img,double out_hist[256])
{
int i=0, j=0;
double temp1=0;
int temp2=0;
const int hist_sz = 256;//0到255,一共256个灰度值
double hist[hist_sz];
memset(hist, 0, sizeof(hist));
for( i = 0; i < img->height; i++ )
{
for( j = 0; j < img->width; j++ )
{temp1=cvGet2D(img,i,j).val[0];
temp2=int(temp1);//作类型转换
hist[temp2]++; //这里实现了hist中存储各灰度值出现的次数
}
}
memcpy(out_hist,hist, sizeof(hist)); //肯定有人要问,为啥不用数组名作为参数传递从而改变实参数组的值
//这种方法一般情况下都可以,我也测试了,然而这里就是不行,我估计与
//memset(hist, 0, sizeof(hist));这句语句有关
}
int main()
{
IplImage *a = cvLoadImage("coins.png", CV_LOAD_IMAGE_UNCHANGED);
double a_hist[256];
mycvCalcHist(a,a_hist);
return 0;
}
补充说明一下为啥用double类型的数组,因为直方图数据经常要参与浮点数运算,所以干脆用这个!
-------------------------------------------
欢迎大家加入图像识别技术交流群:271891601,另外,特别欢迎成都从事图像识别工作的朋友交流,我的QQ号2487872782