通过对地图的特征分析,发现在地图所在地物的边缘、交界以及文字注记处的像素值变化较大。所以用方差来作为边缘地带的特征值处理,给出以下步骤:
Step1. 得到图像内容;
Step2. 按照设定的大小分成N*N的小块,试验中设定N=8;
Step3. 计算每块像素值的均值和方差;
Step4. 方差按照规则对应于255级灰度拉伸;这里只是把方差值除以最大方差值再乘以255;
Step5. 生成图像。
这样就得到了一副显示边缘的成果图。
具体代码如下:
BOOL CWMRasterDCTExtract::VarianceZeroWmarkMakep(HANDLE hImage)
{
if(hImage==NULL)
{
WriteLog(TRA_LEVEL_WARN,_T("CWMRasterDCTExtract::VarianceZeroWmarkMakep, Image is null"));
return FALSE;
}
int i, j;
int nTestNum = 230;
BITMAPINFOHEADER ds;
memcpy(&ds,hImage, sizeof(ds));
int effwdt = ((((ds.biBitCount * ds.biWidth ) + 31) / 32) * 4);
int nPad = effwdt - (((ds.biWidth * ds.biBitCount) + 7) / 8);
BYTE* pbBits = (BYTE*)hImage + *(DWORD*)hImage + ds.biClrUsed * sizeof(RGBQUAD);
WriteLog(TRA_LEVEL_DEBUG,_T("CWMRasterDCTExtract::VarianceZeroWmarkMakep, Pic's width=%d,height=d"),ds.biWidth,ds.biHeight);
BYTE* pImage=NULL;
// 得到图像内容
LONG k,l,biWidth,biHeight;
biWidth=ds.biWidth;
biHeight=ds.biHeight;
// 生成
CString filename;
char szFilter[]="BMP文件(*.bmp)|*.bmp||";
CFileDialog dlg(FALSE,"bmp",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);
WriteLog(TRA_LEVEL_INFO,_T("CWMRasterDCTExtract::VarianceZeroWmarkMakep, 选择保存零水印文件..."));
if(dlg.DoModal()==IDOK)
{
filename=dlg.GetPathName();
int nIndex=0;
double dInput[1024];// 数据容器32*32
double dMaxE=0.0;
double dSum,dE;
if(ds.biBitCount==8)
{
pImage = new BYTE[effwdt*ds.biHeight];
memset(pImage,0,effwdt*ds.biHeight);
m_ipFramework->ShowProgressCtrl();
int nStep = 2;
biHeight = ds.biHeight/nStep*nStep;
biWidth = ds.biWidth/nStep*nStep;
for (i=0; i<biHeight; i+=nStep)
{
for (j=0; j<biWidth; j+=nStep)
{
for(k=0;k<nStep;k++)
{
for(l=0;l<nStep;l++)
{
dInput[k*nStep+l] = pbBits[(i+k)*effwdt + (j+l)];
}
}
CalculateMean(dInput,nStep*nStep,&dSum,&dE);
if(dMaxE<dE)
{
dMaxE = dE;
}
// 测试断点条件
if(nIndex==nTestNum)
{
}
if(dE>0.0)
{/*
BYTE byValue = dE/30.0;
for(k=0;k<nStep;k++)
{
for(l=0;l<nStep;l++)
{
pImage[(i+k)*effwdt + (j+l)] = byValue;
}
}*/
//WriteLog(TRA_LEVEL_DEBUG,_T("CWMRasterDCTExtract::VarianceZeroWmarkMakep, Index=%d, Sum=%f, Ex=%f!"), nIndex, dSum,dE);
}
nIndex++;
}
m_ipFramework->SetPosProgressCtrl(int((i+1)*100/ds.biHeight));
}
m_ipFramework->SetPosProgressCtrl(100);
m_ipFramework->HideProgressCtrl();
WriteLog(TRA_LEVEL_DEBUG,_T("CWMRasterDCTExtract::VarianceZeroWmarkMakep, MaxEx=%f!"), dMaxE);
// 归一化
for (i=0; i<biHeight; i+=nStep)
{
for (j=0; j<biWidth; j+=nStep)
{
for(k=0;k<nStep;k++)
{
for(l=0;l<nStep;l++)
{
dInput[k*nStep+l] = pbBits[(i+k)*effwdt + (j+l)];
}
}
CalculateMean(dInput,nStep*nStep,&dSum,&dE);
if(dE>0.0)
{
BYTE byValue = dE/dMaxE*255;
for(k=0;k<nStep;k++)
{
for(l=0;l<nStep;l++)
{
pImage[(i+k)*effwdt + (j+l)] = byValue;
}
}
}
nIndex++;
}
}
// 保存文件
SaveAsBmpFileEx(filename, 8, effwdt, ds.biHeight, pImage);
}
else
{
WriteLog(TRA_LEVEL_WARN,_T("CWMRasterDCTExtract::VarianceZeroWmarkMakep, no support this format"));
}
}
else
{
WriteLog(TRA_LEVEL_INFO,_T("CWMRasterDCTExtract::VarianceZeroWmarkMakep, Cancel."));
}
if(pImage!=NULL)
{
delete pImage;
}
return TRUE;
} |