📄 feature.cpp
字号:
// Feature.cpp: implementation of the CFeature class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Feature.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// CFeaEdge Class
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFeaEdge::CFeaEdge()
{
}
CFeaEdge::~CFeaEdge()
{
}
int CFeaEdge::m_nFeaLen = 176;
int CFeaEdge::GetFeaLen()
{
return m_nFeaLen;
}
BOOL CFeaEdge::GetFeature(CImage &ImgIn,BYTE *pFea)
{
int nLen = 0;
CImage ImgTemp = ImgIn;
ImgTemp.Stretch(CSize(16,32));
//提取特征
BYTE * pFeaT = pFea;
BYTE byData[64];
BYTE * pBuf = ImgTemp.m_pR;
int i,j,k,l;
int nWAndH = ImgTemp.GetHeight()+ImgTemp.GetWidth();
memset(pFeaT,0,3*nWAndH);
int nW = ImgTemp.GetWidth();
//先宽后高
//求垂直跳变次数
for(i=0;i<ImgTemp.GetWidth();i++)
{
for(j=0;j<ImgTemp.GetHeight()-1;j++)
{
if (pBuf[j*nW+i]!=pBuf[(j+1)*nW+i]&&pBuf[j*nW+i]==0)
{
pFeaT[i]++;
}
}
if (pBuf[j*nW+i]==0)
{
pFeaT[i]++;
}
}
pFeaT += ImgTemp.GetWidth();
nLen += ImgTemp.GetWidth();
//水平跳变次数
for(i=0;i<ImgTemp.GetHeight();i++)
{
for(j=0;j<ImgTemp.GetWidth()-1;j++)
{
if (pBuf[i*nW+j]!=pBuf[i*nW+j+1]&&pBuf[i*nW+j]==0)
{
pFeaT[i]++;
}
}
if (pBuf[i*nW+j]==0)
{
pFeaT[i]++;
}
}
pFeaT += ImgTemp.GetHeight();
nLen += ImgTemp.GetHeight();
//求垂直方向起始位置
for(i=0;i<ImgTemp.GetWidth();i++)
{
pFeaT[i] = 0;
pFeaT[i+nW] = ImgTemp.GetHeight()-1;
for(j=0;j<ImgTemp.GetHeight();j++)
{
if (pBuf[j*nW+i]==0)
{
pFeaT[i] = j;
break;
}
}
for(j=ImgTemp.GetHeight()-1;j>=0;j--)
{
if (pBuf[j*nW+i]==0)
{
pFeaT[i+nW] = j;
break;
}
}
}
pFeaT += 2*ImgTemp.GetWidth();
nLen += 2*ImgTemp.GetWidth();
//水平起始位置
for(i=0;i<ImgTemp.GetHeight();i++)
{
pFeaT[i] = 0;
pFeaT[i+nW] = ImgTemp.GetWidth()-1;
for(j=0;j<ImgTemp.GetWidth();j++)
{
if (pBuf[i*nW+j]==0)
{
pFeaT[i] = j;
break;
}
}
for(j=ImgTemp.GetWidth()-1;j>=0;j--)
{
if (pBuf[i*nW+j]==0)
{
pFeaT[i+nW] = j;
break;
}
}
}
pFeaT += 2*ImgTemp.GetHeight();
nLen += 2*ImgTemp.GetHeight();
//横竖撇捺
int nS = 4;
for(i=0;i<ImgTemp.GetHeight()/nS;i++)
{
for(j=0;j<ImgTemp.GetWidth()/nS;j++)
{
for(k=0;k<nS;k++)
{
for(l=0;l<nS;l++)
{
byData[k*nS+l] = pBuf[(i*nS+k)*16+j*nS+l];
}
}
GetFeaNN(pFeaT[0],pFeaT[0],pFeaT[0],pFeaT[0],pFeaT[0],byData,nS);
pFeaT += 1;
nLen += 1;
}
}
return TRUE;
}
void CFeaEdge::GetFeaNN(BYTE &nH, BYTE &nV, BYTE &nL, BYTE &nR, BYTE &nS, BYTE * pData,int nDim)
{
int i,j;//i表示高,j表示宽
nS = 0;
nH = 0;
nV = 0;
nL = 0;
nR = 0;
//总数
for(i=0;i<nDim;i++)
{
for(j=0;j<nDim;j++)
{
if (pData[i*nDim+j]==0)
{
nS++;
}
}
}
return;
//横
for(i=0;i<nDim;i++)
{
for(j=0;j<nDim-1;j++)
{
if (pData[i*nDim+j]==0&&pData[i*nDim+j+1]==0)
{
nH++;
}
}
}
//竖
for(i=0;i<nDim-1;i++)
{
for(j=0;j<nDim;j++)
{
if (pData[i*nDim+j]==0&&pData[(i+1)*nDim+j]==0)
{
nV++;
}
}
}
//撇
for(i=1;i<nDim;i++)
{
for(j=0;j<i-1;j++)
{
if (pData[i*nDim+j]==0&&pData[(i+1)*nDim+j-1]==0)
{
nL++;
}
}
}
for(i=nDim-2;i>0;i--)
{
for(j=nDim-1;j>i;j--)
{
if (pData[i*nDim+j]==0&&pData[(i-1)*nDim+j+1]==0)
{
nL++;
}
}
}
//捺
for(j=0;j<nDim;j++)
{
for(i=0;i<j-1;i++)
{
if (pData[i*nDim+j]==0&&pData[(i+1)*nDim+j+1]==0)
{
nR++;
}
}
}
for(j=0;j<nDim-1;j++)
{
for(i=nDim-1;i>j;i--)
{
if (pData[i*nDim+j]==0&&pData[(i-1)*nDim+j-1]==0)
{
nR++;
}
}
}
}
//////////////////////////////////////////////////////////////////////
// CFeaPosition Class
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFeaPosition::CFeaPosition()
{
}
CFeaPosition::~CFeaPosition()
{
}
int CFeaPosition::m_nFeaLen = 128;
int CFeaPosition::GetFeaLen()
{
return m_nFeaLen;
}
BOOL CFeaPosition::GetFeature(CImage &ImgIn,BYTE *pFea)
{
CImage ImgTemp = ImgIn;
ImgTemp.Stretch(CSize(16,32));
int nS = 2;
int nLenFea = 0;
int i,j,k,l;
for(i=0;i<ImgTemp.GetHeight()/nS;i++)
{
for(j=0;j<ImgTemp.GetWidth()/nS;j++)
{
pFea[nLenFea] = 0;
for(k=0;k<nS;k++)
{
for(l=0;l<nS;l++)
{
if (ImgTemp.m_pR[(i*nS+k)*16+j*nS+l]==0)
{
pFea[nLenFea]++;
}
}
}
nLenFea += 1;
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CRecBase Class
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CRecBase::CRecBase(int nType)
{
m_nFeaType = nType;
if(nType==0)
{
m_pFeature = new CFeaEdge;
}
else if (nType==1)
{
m_pFeature = new CFeaPosition;
}
else if(nType==2)
{
m_pFeature = new CHVLRFeature;
}
else
{
m_pFeature = NULL;
}
}
void CRecBase::StopTrain()
{
m_BpNet.stop();
}
CRecBase::~CRecBase()
{
if (m_pFeature)
{
delete m_pFeature;
}
}
BOOL CRecBase::LoadBpNet(CString strPath)
{
CFile file;
if (!file.Open(strPath,CFile::modeRead)) {
return FALSE;
}
CArchive myar(&file,CArchive::load);
m_BpNet.Serialize(myar);
myar.Close();
file.Read(&m_nFeaType,sizeof(int));
int nSizeChar;
file.Read(&nSizeChar,sizeof(int));
char pCh[1024];
memset(pCh,0,1024);
file.Read(pCh,nSizeChar);
file.Close();
m_strListChar = pCh;
if(m_pFeature)
{
delete m_pFeature;
m_pFeature = NULL;
}
if (m_nFeaType==0)
{
m_pFeature = new CFeaEdge;
}
else if (m_nFeaType==1)
{
m_pFeature = new CFeaPosition;
}
else if(m_nFeaType==2)
{
m_pFeature = new CHVLRFeature;
}
return TRUE;
}
BOOL CRecBase::TrainChinese(CString strOutPath,CString strListChar,int nPerNum)
{
ASSERT(nPerNum<=200);
ASSERT(m_pFeature!=NULL);
CString strPath;
int nSizeChar = strListChar.GetLength();
CString PathList[31][200];
CMatrix mInput;
mInput.Zeros(nPerNum*nSizeChar,m_pFeature->GetFeaLen());
BYTE *byFea = new BYTE[m_pFeature->GetFeaLen()];
CMatrix mTarget;
mTarget.Zeros(nPerNum*nSizeChar,nSizeChar);
for(int i=0;i<nSizeChar;i++)
{
CFileFind filefind;
CString strFolder;
strFolder.Format("%sExaple\\Chinese\\%c\\",GetAppPath(),strListChar.GetAt(i));
int nTop = 0;
if(filefind.FindFile(strFolder+"*.jpg"))
{
while (filefind.FindNextFile())
{
if(nTop>=nPerNum)
{
break;
}
PathList[i][nTop] = strFolder+filefind.GetFileName();
nTop++;
}
if(nTop<nPerNum)
{
PathList[i][nTop] = strFolder+filefind.GetFileName();
nTop++;
}
}
if(filefind.FindFile(strFolder+"*.bmp"))
{
while (filefind.FindNextFile())
{
if(nTop>=nPerNum)
{
break;
}
PathList[i][nTop] = strFolder+filefind.GetFileName();
nTop++;
}
if(nTop<nPerNum)
{
PathList[i][nTop] = strFolder+filefind.GetFileName();
nTop++;
}
}
}
CImage ImgIn;
int nLenFea;
for(int k=0;k<nPerNum;k++)
{
for(int j=0;j<nSizeChar;j++)
{
if (!ImgIn.Load(PathList[j][k]))
{
CString strTemp;
strTemp.Format("无法读取图象:%c第%d图",strListChar.GetAt(j),k);
AfxMessageBox(strTemp);
delete []byFea;
return FALSE;
}
nLenFea = m_pFeature->GetFeaLen();
m_pFeature->GetFeature(ImgIn,byFea);
for(int nPix = 0;nPix<nLenFea;nPix++)
{
mInput.Set(k*nSizeChar+j,nPix,byFea[nPix]);
}
mTarget.Set(k*nSizeChar+j,j,1);
}
}
m_BpNet.Create(mInput,mTarget,mInput.cols(),mInput.cols()/2,nSizeChar);
m_BpNet.learn();
CFile file;
if (!file.Open(strOutPath,CFile::modeCreate|CFile::modeWrite)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -