⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 numrecogbpdlg.cpp

📁 采用BP神经网络算法实现的大写金融汉字识别软件的核心识别功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{
			dc->FillSolidRect(dot.x, dot.y-10, 10, 10, RGB(0, 0, 0));
		}
		dot.x += 10;
		if(dot.x==ix+10*NN_RESX)
		{
			dot.x = ix;
			dot.y += 10; 
		}
		cell ++;
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CNumRecogBPDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

/////////////////////////////////////////////////////////////////////////
// 由于某些原因,若采用“Maxinum Speed”优化将引起程序运行失败,所以先
// 关闭此优化,在该段代码运行结束后再打开此优化功能
/////////////////////////////////////////////////////////////////////////
#pragma optimize("", off)

// 训练按钮处理函数
void CNumRecogBPDlg::OnButtonTrain() 
{
	// TODO: Add your control notification handler code here
	srand((unsigned)time(NULL));  // 设置随机数
	m_RunInfor.ResetContent();    // 程序运行信息
	
	// 所有权值0初始化
	memset(&m_fWeights, 0, sizeof(m_fWeights));

	// 产生带有随机噪声的训练数据
	m_RunInfor.InsertString(-1, "产生带有随机噪声的训练数据......");
	int num = 0;
	for(int i=0; i<NN_NUMBERS*NN_NOISY; i++)
	{
		for(int j=0; j<NN_RESX*NN_RESY; j++)
		{
			if(rand()%100 < 7)
			{
				m_iTrainNoisy[i][j] = !m_iTrainData[num][j];
			}
			else
				m_iTrainNoisy[i][j] = m_iTrainData[num][j];
		}
		if(((float)(i+1)/NN_NOISY == (i+1)/NN_NOISY)&&(i != 0))
		{
			num++;
		}
	}

	m_RunInfor.InsertString(-1, "训练中......");
	RunBPNet(true);  // 运行网络

	m_RunInfor.InsertString(-1, "训练结束......");

	GetDlgItem(IDC_BUTTON_RECOG)->EnableWindow(true);  // 运行训练后再开始识别
}

// 识别按钮处理函数
void CNumRecogBPDlg::OnButtonRecog() 
{
	// TODO: Add your control notification handler code here
	m_RunInfor.ResetContent();    // 程序运行信息
	m_RunInfor.InsertString(-1, "开始识别......");

	float d[NN_NUMBERS];
	for(int j=0; j<NN_NUMBERS; j++)
	{
		d[j] = 0;
		for(int k=0; k<NN_RESX*NN_RESY; k++)
		{
			d[j] += m_fWeights[j][k]*m_iRecogData[0][k];
		}
	}

	int bestind = 0;
	for(j=1; j<NN_NUMBERS; j++)
	{
		if(d[j]>d[bestind])
		{
			bestind = j;
		}
	}
/////////////////////////////////////////////////////////////////////////////
// 零、壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、元、角、分
/////////////////////////////////////////////////////////////////////////////
	switch(bestind)
	{
		case 0:
			m_RunInfor.InsertString(-1, "识别结果为元");
			break;
		case 1:
			m_RunInfor.InsertString(-1, "识别结果为角");
			break;
		case 2:
			m_RunInfor.InsertString(-1, "识别结果为分");
			break;
		case 3:
			m_RunInfor.InsertString(-1, "识别结果为零");
			break;
		case 4:
			m_RunInfor.InsertString(-1, "识别结果为壹");
			break;
		case 5:
			m_RunInfor.InsertString(-1, "识别结果为贰");
			break;
		case 6:
			m_RunInfor.InsertString(-1, "识别结果为叁");
			break;
		case 7:
			m_RunInfor.InsertString(-1, "识别结果为肆");
			break;
		case 8:
			m_RunInfor.InsertString(-1, "识别结果为伍");
			break;
		case 9:
			m_RunInfor.InsertString(-1, "识别结果为陆");
			break;
		case 10:
			m_RunInfor.InsertString(-1, "识别结果为柒");
			break;
		case 11:
			m_RunInfor.InsertString(-1, "识别结果为捌");
			break;
		case 12:
			m_RunInfor.InsertString(-1, "识别结果为玖");
			break;
		case 13:
			m_RunInfor.InsertString(-1, "识别结果为拾");
			break;
		default:
			m_RunInfor.InsertString(-1, "无法识别");
	}
}

// 运行BP网络处理函数
void CNumRecogBPDlg::RunBPNet(bool training)
{
	// 检测带有噪声的数据
	float d[NN_NUMBERS];
	int cycles = 0;  // 初始化循环次数为0
	bool correct;

	do
	{
		correct = true;
		for(int i=0; i<NN_NUMBERS*NN_NOISY; i++)
		{
			for(int j=0; j<NN_NUMBERS; j++)
			{
				d[j] = 0;
				for(int k=0; k<NN_RESX*NN_RESY; k++)
				{
					d[j] += m_fWeights[j][k]*m_iTrainNoisy[i][k];
				}
			}

			int bestind = 0;
			for(j=1; j<NN_NUMBERS; j++)
			{
				if(d[j]>d[bestind])
				{
					bestind = j;
				}
			}

			int realval = (int)(i/NN_NOISY);
			if(bestind == realval)
				continue;

			if(training)
			{
				correct = false;

				for(j=0; j<NN_RESX*NN_RESY; j++)
				{
					m_fWeights[bestind][j] -= m_iTrainNoisy[i][j];
					m_fWeights[realval][j] += m_iTrainNoisy[i][j];
				}
			}
		}
		++cycles;  //???
	}while(!correct && cycles<=NN_MAXITER);

	// 如果循环次数太大还没得到结果则退出
	if(cycles >= NN_MAXITER)
	{
		MessageBox("训练超时!", "训练错误", MB_OK|MB_ICONINFORMATION);
		return;
	}
}

// 恢复系统优化
#pragma optimize("", on)

// 训练数据滚动条的处理函数
void CNumRecogBPDlg::OnDeltaposSpinTrainnum(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
	// TODO: Add your control notification handler code here
	int iPos = pNMUpDown->iPos;
	int iDelta = pNMUpDown->iDelta;
	
	if((iPos==0 && iDelta==-1) || (iPos==NN_NUMBERS-1 && iDelta== 1))
	{
		if(iDelta==-1)
		{
			m_ipDrawTrainNum = &m_iTrainData[0][0];
			InvalidateTrainPic();
		}
		else
		{
			m_ipDrawTrainNum = &m_iTrainData[NN_NUMBERS-1][0];
			InvalidateTrainPic();
		}
	}
	else
	{
		m_ipDrawTrainNum = &m_iTrainData[iPos+iDelta][0];
		InvalidateTrainPic();
	}

	*pResult = 0;
}

//////////////////////////////////////////////////////////////////////
// 强制重绘函数
// 训练区重绘函数
void CNumRecogBPDlg::InvalidateTrainPic()
{
	// 获取绘画区域
	CRect rect_Train;  // 训练窗口
	
	// 生成训练窗口绘图区
	m_TrainPic.GetClientRect(&rect_Train);
	m_TrainPic.ClientToScreen(&rect_Train);
	ScreenToClient(&rect_Train);	

	InvalidateRect(rect_Train, false);
}

// 识别区重绘函数
void CNumRecogBPDlg::InvalidateRecogPic()
{
	// 获取绘画区域
	CRect rect_Recog;  // 识别窗口
	
	// 生成识别窗口绘图区
	m_RecogPic.GetClientRect(&rect_Recog);
	m_RecogPic.ClientToScreen(&rect_Recog);
	ScreenToClient(&rect_Recog);
	
	InvalidateRect(rect_Recog, false);
}

////////////////////////////////////////////////////////////////////
// 打开识别文件
void CNumRecogBPDlg::OnOpenrecogfile() 
{
	// TODO: Add your control notification handler code here
	CFileDialog OpenFileDlg(TRUE, NULL, NULL, 
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		"识别文件(*.dat)|*.dat|所有文件(*.*)|*.*||");

	if(OpenFileDlg.DoModal()==IDOK)
	{
		CString fileName = OpenFileDlg.GetFileName();

		// 打开文件
		ifstream recogdata(fileName, ios::nocreate);

		// 检查文件的有效性
		if(!recogdata)
		{
			MessageBox("没有找到保存识别数据的文件!", "载入文件错误!",
			MB_OK|MB_ICONERROR);
		}

		// 读文件(打开待识别的文件)
		for(int i=0; i<NN_NUMBERS; i++)
		{
			for(int j=0; j<NN_RESX*NN_RESY; j++)
			{
				int onoff;
				recogdata >> onoff;
				m_iRecogData[i][j] = onoff;
			}
		}

		m_bDrawNum = 1;  // 设置画数字标志
		m_ipDrawRecogNum = &m_iRecogData[0][0];  // 画数字指针赋值
		InvalidateRecogPic();  // 绘图区刷新

		m_RunInfor.ResetContent();    // 载入新文件,程序运行信息初始化
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -