给定一幅Lena.bmp的彩色图像,大小为256*256或512*512,求图像中的信息熵和R、G、B三色的条件熵。
计算环境:VS2010+Opencv2.4.6、
#include<iostream>
#include<math.h>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main(){
//求图像的R、G、B的信息熵
/* IplImage *src,*red,*green,*blue;
src=cvLoadImage("lena.bmp");
red=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
green=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
blue=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
cvSplit(src,blue,green,red,NULL);
double entropy_r=0,entropy_g=0,entropy_b=0;
double a[256]={0},b[256]={0},c[256]={0};
for(int x=0;x<red->width;x++){
for(int y=0;y<red->height;y++){
int temp=((char*)(red->imageData+y*red->widthStep))[x]+128;
a[temp]++;
temp=((char*)(green->imageData+y*green->widthStep))[x]+128;
b[temp]++;
temp=((char*)(blue->imageData+y*blue->widthStep))[x]+128;
c[temp]++;
}
}
for(int i=0;i<256;i++){
a[i]=a[i]/65536;
b[i]=b[i]/65536;
c[i]=c[i]/65536;
}
for(int j=0;j<256;j++){
if(a[j]!=0){
entropy_r-=a[j]*(log10((float)a[j])/log10((float)2));
}
if(b[j]!=0){
entropy_g-=b[j]*(log10((float)b[j])/log10((float)2));
}
if(c[j]!=0){
entropy_b-=c[j]*(log10((float)c[j])/log10((float)2));
}
}
cout<<entropy_r<<endl;
cout<<entropy_g<<endl;
cout<<entropy_b<<endl;
cvNamedWindow("src");
cvNamedWindow("r");
cvNamedWindow("g");
cvNamedWindow("b");
cvShowImage("src",src);
cvShowImage("r",r);
cvShowImage("g",g);
cvShowImage("b",b);
cvWaitKey(0);
cin.get();
cvReleaseImage(&blue);
cvReleaseImage(&green);
cvReleaseImage(&red);
cvReleaseImage(&src);
cvDestroyWindow("b");
cvDestroyWindow("g");
cvDestroyWindow("r");
cvDestroyWindow("src");*/
//求图像的联合熵(R、G、B)
/* IplImage *src;
src=cvLoadImage("lena.bmp");
double entropy=0;
float ***a=(float***)new float**[256];
for(int i=0;i<256;i++){
a[i]=(float**)new float*[256];
}
for(int i=0;i<256;i++){
for(int j=0;j<256;j++){
a[i][j]=new float[256];
memset(a[i][j],0,sizeof(float)*256);
}
}
for(int y=0;y<src->height;y++){
char* ptr=(char*)(src->imageData+y*src->widthStep);
for(int x=0;x<src->width;x++){
int temp1=ptr[3*x]+128;
int temp2=ptr[3*x+1]+128;;
int temp3=ptr[3*x+2]+128;;
a[temp1][temp2][temp3]++;
}
}
for(int i=0;i<256;i++){
for(int j=0;j<256;j++){
for (int k=0;k<256;k++)
{
if(a[i][j][k]!=0){
a[i][j][k]/=65536;
entropy-=a[i][j][k]*(log10((float)a[i][j][k])/log10((float)2));
}
}
}
}
cout<<entropy<<endl;
cin.get();
cvReleaseImage(&src);*/
//求图像的条件熵
/*IplImage *src,*gray;
src=cvLoadImage("lena.bmp");
gray=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
cvCvtColor(src,gray,CV_BGR2GRAY);
float entropy=0;
float s1_probability[256]={0};
float **s0_probability=new float*[256];
for(int i=0;i<256;i++){
s0_probability[i]=new float[256];
memset(s0_probability[i],0,sizeof(float)*256);
}
for(int y=0;y<gray->height;y++){
char* ptr=(char*)(gray->imageData+y*gray->widthStep);
for(int x=0;x<gray->width-1;x++){
int s1=ptr[x]+128;
int s0=ptr[x+1]+128;
s1_probability[s1]++;
s0_probability[s0][s1]++;
}
}
int sum=0;
for (int s0=0;s0<256;s0++)
{
for (int s1=0;s1<256;s1++){
if(s0_probability[s0][s1]!=0){
float probability=s0_probability[s0][s1]/256/255;
float conditional_probability=s0_probability[s0][s1]/s1_probability[s1];
entropy-=probability*(log10(conditional_probability)/log10((float)2));
}
}
}
cout<<entropy<<endl;
cin.get();
cvReleaseImage(&gray);
cvReleaseImage(&src);*/
IplImage *src,*gray;
src=cvLoadImage("lena.bmp");
gray=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
cvCvtColor(src,gray,CV_BGR2GRAY);
float entropy=0;
float s2_probability[256]={0};
float **s0_probability=new float*[256];
for(int i=0;i<256;i++){
s0_probability[i]=new float[256];
memset(s0_probability[i],0,sizeof(float)*256);
}
for(int y=0;y<gray->height-1;y++){
char* ptr=(char*)(gray->imageData+y*gray->widthStep);
for(int x=0;x<gray->width-1;x++){
int s2=ptr[x]+128;
int s0=ptr[x+gray->widthStep+1]+128;
s2_probability[s2]++;
s0_probability[s0][s2]++;
}
}
for (int s0=0;s0<256;s0++)
{
for (int s2=0;s2<256;s2++){
if(s0_probability[s0][s2]!=0){
float probability=s0_probability[s0][s2]/256/255;
float conditional_probability=s0_probability[s0][s2]/s2_probability[s2];
entropy-=probability*(log10(conditional_probability)/log10((float)2));
}
}
}
cout<<entropy<<endl;
cin.get();
cvReleaseImage(&gray);
cvReleaseImage(&src);
return 0;
}