📄 mycolorfeature.cpp
字号:
// MyColorFeature.cpp: implementation of the MyColorFeature class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "myimagedb.h"
#include "MyColorFeature.h"
#include "mycolorspace.h"
#include <MATH.H>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
MyColorFeature::MyColorFeature()
{
}
MyColorFeature::~MyColorFeature()
{
}
D1ColorBin* MyColorFeature::CalcuHisD1(BYTE* rgbData, INT width, INT height)
//计算一维直方图,来自RemoteDemo;
//输入参数无需预分配内存;
{
unsigned long imglen = width*height;
MyHSV* myhsvbuf = new MyHSV[imglen];
HsvBelongTo* imgd1data = new HsvBelongTo[imglen];
int i,j;
unsigned long pos;
myColorSpace.RgbtoHsv(rgbData, width, height, myhsvbuf);
for(i=0;i<height;i++)
{
for (j=0;j<width;j++)
{
pos = i*width+j;
imgd1data[pos].hsv.h = myhsvbuf[pos].h;
imgd1data[pos].hsv.s = myhsvbuf[pos].s;
imgd1data[pos].hsv.v = myhsvbuf[pos].v;
imgd1data[pos].belongto = 0;
}
}
delete [] myhsvbuf;
//以下设定初始色彩薄
D1ColorBinUnit* mycolorbook = new D1ColorBinUnit[CBDIM];
D1ColorBinUnit* newcolorbook = new D1ColorBinUnit[CBDIM];//备份,互相交换;
int n;
for(n=0; n<CBDIM; n++)
{
if( ( n % 9 ) % 3 == 0){mycolorbook[n].hsv.v = 0.0;}
if( ( n % 9 ) % 3 == 1) {mycolorbook[n].hsv.v = (FLOAT)0.2;}
if( ( n % 9 ) % 3 == 2) {mycolorbook[n].hsv.v = (FLOAT)0.7;}
if( ( n % 9 ) / 3 == 0) {mycolorbook[n].hsv.s = (FLOAT)0.0;}
if( ( n % 9 ) / 3 == 1) {mycolorbook[n].hsv.s = (FLOAT)0.2;}
if( ( n % 9 ) / 3 == 2) {mycolorbook[n].hsv.s = (FLOAT)0.7;}
if(n / 9 == 0) { mycolorbook[n].hsv.h = (FLOAT)(2.0 * PI * 20.0 / 360.0); }
if(n / 9 == 1) { mycolorbook[n].hsv.h = (FLOAT)(2.0 * PI * 40.0 / 360.0); }
if(n / 9 == 2) { mycolorbook[n].hsv.h = (FLOAT)(2.0 * PI * 75.0 / 360.0); }
if(n / 9 == 3) { mycolorbook[n].hsv.h = (FLOAT)(2.0 * PI * 155.0 / 360.0); }
if(n / 9 == 4) { mycolorbook[n].hsv.h = (FLOAT)(2.0 * PI * 190.0 / 360.0); }
if(n / 9 == 5) { mycolorbook[n].hsv.h = (FLOAT)(2.0 * PI * 270.0 / 360.0); }
if(n / 9 == 6) { mycolorbook[n].hsv.h = (FLOAT)(2.0 * PI * 295.0 / 360.0); }
if(n / 9 == 7) { mycolorbook[n].hsv.h = (FLOAT)(2.0 * PI * 315.0 / 360.0); }
mycolorbook[n].count = 0;
}
//以下对一维色彩空间进行聚类
double mydis;
int k,c;
double dmold = 0;
double dmnew = 0;
double tempdis;
do{
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
pos = i*width + j;
mydis = 10.0;
for (k=0; k<CBDIM; k++)
{
tempdis = myColorSpace.GetHsvDistance(
mycolorbook[k].hsv, imgd1data[pos].hsv);
if (tempdis < mydis)
{
mydis = tempdis;
imgd1data[pos].belongto = k;
}
}
c = imgd1data[pos].belongto;
mycolorbook[c].count ++;
}
}
//完成对像素所属色彩薄及色彩薄颜色个个数的统计
//下面计算新色彩薄的色彩值和频数
for(k=0; k<CBDIM; k++)
{
if ( mycolorbook[k].count!=0 )
{
newcolorbook[k].hsv.h = 0;
newcolorbook[k].hsv.s = 0;
newcolorbook[k].hsv.v = 0;
}else{
newcolorbook[k].hsv.h = mycolorbook[k].hsv.h;
newcolorbook[k].hsv.s = mycolorbook[k].hsv.s;
newcolorbook[k].hsv.v = mycolorbook[k].hsv.v;
}
newcolorbook[k].count = mycolorbook[k].count;
}
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
pos = i*width+j;
c = imgd1data[pos].belongto;
newcolorbook[c].hsv.h += imgd1data[pos].hsv.h;
newcolorbook[c].hsv.s += imgd1data[pos].hsv.s;
newcolorbook[c].hsv.v += imgd1data[pos].hsv.v;
newcolorbook[c].count ++;
}
}
for (k=0; k<CBDIM; k++)
{
if (newcolorbook[k].count!=0)
{
newcolorbook[k].hsv.h = newcolorbook[k].hsv.h / newcolorbook[k].count;
newcolorbook[k].hsv.s = newcolorbook[k].hsv.s / newcolorbook[k].count;
newcolorbook[k].hsv.v = newcolorbook[k].hsv.h / newcolorbook[k].count;
}
mycolorbook[k].hsv.h = newcolorbook[k].hsv.h;
mycolorbook[k].hsv.s = newcolorbook[k].hsv.s;
mycolorbook[k].hsv.v = newcolorbook[k].hsv.v;
mycolorbook[k].count = 0;
}
//至此新的聚类完成,并以新聚类代替旧类,准备下一次迭代
//以下计算聚类误差
dmold = dmnew;
dmnew = 0;
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
pos = i*width+j;
c = imgd1data[pos].belongto;
tempdis = myColorSpace.GetHsvDistance(imgd1data[pos].hsv, newcolorbook[c].hsv);
tempdis = pow(tempdis,2.0) / sqrt(5.0);
dmnew += tempdis / imglen;
}
}
}while( fabs(dmnew-dmold) > 0.1 );
for (k=0; k<CBDIM; k++)
{
newcolorbook[k].count = newcolorbook[k].count / (FLOAT)imglen;
}
//将直方图归一化
delete [] mycolorbook;
delete [] imgd1data;
//单副图像的一维直方图特征已经计算完毕,特征值存储在m_newcolorbook中,
//newcolorbook中的元素个数现为CBDIM,
//将得到的直方图存入直方图结构;
D1ColorBin* toreturn = new D1ColorBin;
toreturn->bincount = CBDIM;
toreturn->binunits = newcolorbook;
return toreturn;
}
DOUBLE MyColorFeature::GetHisD1Distance(D1ColorBin* myhisd1, D1ColorBin* myhisd2)
//计算直方图距离;
{
//来自RemoteDemo;
DOUBLE hisd1dis = 0;
DOUBLE test1 = 0;
DOUBLE test2 = 0;
INT count = myhisd1->bincount;
INT i;
//测试直方图;
for (i=0; i<count; i++)
{
test1 += myhisd1->binunits[i].count;
test2 += myhisd2->binunits[i].count;
}
if (fabs(test1)>1.000001 || fabs(test2)>1.000001)
{
MessageBox(NULL,"","直方图数据有误",MB_OK);
}
//计算距离
for( i=0; i<count; i++)
{
FLOAT sum = myhisd1->binunits[i].count - myhisd2->binunits[i].count;
hisd1dis += pow(sum, 2.0);
}
hisd1dis = sqrt(hisd1dis);
hisd1dis = hisd1dis / sqrt(2.0);
return hisd1dis;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -