#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <ctype.h>
#include <iostream>
using namespace std;
#define PI 3.14
int main(){
IplImage* src=cvLoadImage("0013-03.bmp", 0); // force to gray image
if(src==0) return -1;
cvNamedWindow( "Histogram", 0 );
CvSize size=cvGetSize(src);
IplImage* canny=cvCreateImage(cvGetSize(src),8,1);//边缘图像
IplImage* dx=cvCreateImage(cvGetSize(src),32,1);//x方向上的差分,此处的数据类型为U不怕溢出
IplImage* dy=cvCreateImage(cvGetSize(src),32,1);
IplImage* gradient_im=cvCreateImage(cvGetSize(src),32,1);//梯度图像
CvMat* canny_m=cvCreateMat(size.height,size.width,CV_32FC1);//边缘矩阵
CvMat* dx_m=cvCreateMat(size.height,size.width,CV_32FC1);
CvMat* dy_m=cvCreateMat(size.height,size.width,CV_32FC1);
CvMat* gradient=cvCreateMat(size.height,size.width,CV_32FC1);//梯度矩阵
CvMat* gradient_dir=cvCreateMat(size.height,size.width,CV_32FC1);//梯度方向矩阵
CvMat* mask=cvCreateMat(size.height,size.width,CV_32FC1);//掩码
cvCanny(src,canny,60,180,3);//边缘检测
cvConvert(canny,canny_m);//把图像转换为矩阵
cvSobel(src,dx,1,0,3);// 一阶X方向的图像差分:dx
cvSobel(src,dy,0,1,3);// 一阶Y方向的图像差分:dy
cvConvert(dx,dx_m);
cvConvert(dy,dy_m);
cvAdd(dx_m,dy_m,gradient); //梯度不是等于根号下x的导数的平方加上y导数的平方吗?
cvDiv(dx_m,dy_m,gradient_dir); // direction
int i,j;
CvHistogram *hist = 0; // define multi_demention histogram
float theta;
int hdims = 300; // 划分HIST的个数,越高越精确
float hranges_arr[] = {-PI/2,PI/2}; // 直方图的上界和下界
float* hranges = hranges_arr;
float max_val;
int bin_w;
for(i=0;i<size.height;i++)
for(j=0;j<size.width;j++)
{
if(cvmGet(canny_m,i,j)!=0 && cvmGet(dx_m,i,j)!=0){//此行是什么意思?只看边缘上的方向?
theta=cvmGet(gradient_dir,i,j);
theta=atan(theta);
cvmSet(gradient_dir,i,j,theta);
}
else
{
cvmSet(gradient_dir,i,j,0);
}
}
hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 );
//创建一个指定尺寸的直方图,并返回创建的直方图指针
cvConvert(gradient_dir,gradient_im);//把梯度方向矩阵转化为图像
cvCalcHist( &gradient_im, hist, 0, canny ); // 计算直方图
float bin_val[300];
for(i=0;i < hdims; i++ )
bin_val[i] = cvQueryHistValue_1D(hist, i);
cvGetMinMaxHistValue( hist, 0, &max_val, 0, 0 ); // 只找最大值
cvConvertScale( hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0 );
//缩放bin 到区间[0,255] ,比例系数
return 0;
}