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

📄 bp.h

📁 给出了用VC++进行编写的数字识别系统源代码
💻 H
📖 第 1 页 / 共 2 页
字号:

#include <stdio.h>
#include <math.h> 
#include <time.h>
#include <stdlib.h>
#define BIGRND 32767

double drnd();
double dpn1();
double squash(double x);
double *alloc_1d_dbl(int n);
double *alloc_1d_dbl(int n);
double **alloc_2d_dbl(int m, int n);
void bpnn_initialize(int seed);
void bpnn_randomize_weights(double **w, int m, int n);
void bpnn_zero_weights(double **w, int m, int n);
void bpnn_layerforward(double *l1, double *l2, double **conn, int n1, int n2);
void bpnn_output_error(double *delta, double *target, double *output, int nj);
void bpnn_hidden_error(double* delta_h, int nh, double *delta_o, int no, double **who, double *hidden);
void bpnn_adjust_weights(double *delta, int ndelta, double *ly, int nly, double** w, double **oldw, double eta, double momentum);
void w_weight(double **w,int n1,int n2,char*name);
bool r_weight(double **w,int n1,int n2,char *name);
void w_num(int n1,int n2,int n3,char*name);
bool r_num(int *n,char *name);

void code(BYTE*image ,int *p,int w,int h,int dw);
void BpTrain(HDIB hDIB,int n_hidden,double min_ex,double momentum,double eta ,int width,int height);
void CodeRecognize(HDIB hDIB,int width ,int height ,int n_in ,int n_hidden,int n_out);


/*** 返回0-1的双精度随机数 ***/
double drnd()
{
	return ((double) rand() / (double) BIGRND);
}

/*** 返回-1.0到1.0之间的双精度随机数 ***/
double dpn1()
{
	return ((drnd() * 2.0) - 1.0);
}

double squash(double x)
{
	return (1.0 / (1.0 + exp(-x)));
}
/*** 申请1维双精度实数数组 ***/

double *alloc_1d_dbl(int n)
{
	double *new1;
	
	new1 = (double *) malloc ((unsigned) (n * sizeof (double)));
	if (new1 == NULL) {
		printf("ALLOC_1D_DBL: Couldn't allocate array of doubles\n");
		return (NULL);
	}
	return (new1);
}

/*** 申请2维双精度实数数组 ***/

double **alloc_2d_dbl(int m, int n)
{
	int i;
	double **new1;
	
	new1 = (double **) malloc ((unsigned) (m * sizeof (double *)));
	if (new1 == NULL) {
		//	printf("ALLOC_2D_DBL: Couldn't allocate array of dbl ptrs\n");
		return (NULL);
	}
	
	for (i = 0; i < m; i++) {
		new1[i] = alloc_1d_dbl(n);
	}
	
	return (new1);
}

/*** 设置随机数种子 ***/
void bpnn_initialize(int seed)
{
	//printf("Random number generator seed: %d\n", seed);
	srand(seed);
}

/*** 随机初始化权值 ***/
void bpnn_randomize_weights(double **w, int m, int n)
{
	int i, j;
	
	for (i = 0; i <= m; i++) {
		for (j = 0; j <= n; j++) {
			
			w[i][j] = dpn1();
		}
	}
}
/*** 0初始化权值 ***/
void bpnn_zero_weights(double **w, int m, int n)
{
	int i, j;
	
	for (i = 0; i <= m; i++) {
		for (j = 0; j <= n; j++) {
			w[i][j] = 0.0;
		}
	}
}

/*********前向传输*********/
void bpnn_layerforward(double *l1, double *l2, double **conn, int n1, int n2)
{
	double sum;
	int j, k;
	
	/*** 设置阈值 ***/
	l1[0] = 1.0;
	
	/*** 对于第二层的每个神经元 ***/
	for (j = 1; j <= n2; j++) {
		
		/*** 计算输入的加权总和 ***/
		sum = 0.0;
		for (k = 0; k <= n1; k++) {
			sum += conn[k][j] * l1[k];
		}
		l2[j] = squash(sum);
	}
}

/* 输出误差 */

void bpnn_output_error(double *delta, double *target, double *output, int nj)
{
	int j;
	double o, t, errsum;
	
	errsum = 0.0;
	for (j = 1; j <= nj; j++) {
		o = output[j];
		t = target[j];
		delta[j] = o * (1.0 - o) * (t - o);
		
	}
	
}

/* 隐含层误差 */

void bpnn_hidden_error(double* delta_h, int nh, double *delta_o, int no, double **who, double *hidden)
{
	int j, k;
	double h, sum, errsum;
	
	errsum = 0.0;
	for (j = 1; j <= nh; j++) {
		h = hidden[j];
		sum = 0.0;
		for (k = 1; k <= no; k++) {
			sum += delta_o[k] * who[j][k];
		}
		delta_h[j] = h * (1.0 - h) * sum;
		
	}
	
}

/* 调整权值 */
void bpnn_adjust_weights(double *delta, int ndelta, double *ly, int nly, double** w, double **oldw, double eta, double momentum)
{
	double new_dw;
	int k, j;
	
	ly[0] = 1.0;
	for (j = 1; j <= ndelta; j++) {
		for (k = 0; k <= nly; k++) {
			new_dw = ((eta * delta[j] * ly[k]) + (momentum * oldw[k][j]));
			w[k][j] += new_dw;
			oldw[k][j] = new_dw;
		}
	}
}
/*******保存权值**********/
void w_weight(double **w,int n1,int n2,char*name)
{
	int i,j;
	double *buffer;
	FILE *fp;
	fp=fopen(name,"wb+");
	buffer=(double*)malloc((n1+1)*(n2+1)*sizeof(double));
	for(i=0;i<=n1;i++)
	{
		for(j=0;j<=n2;j++)
			buffer[i*(n2+1)+j]=w[i][j];
	}
	fwrite((char*)buffer,sizeof(double),(n1+1)*(n2+1),fp);
	fclose(fp);
	free(buffer);
}



/************读取权值*************/
bool  r_weight(double **w,int n1,int n2,char *name)
{
	int i,j;
	double *buffer;
	FILE *fp;
	if((fp=fopen(name,"rb"))==NULL)
	{
		::MessageBox(NULL,"无法读取权值信息",NULL,MB_ICONSTOP);
		return (false);
	}
	buffer=(double*)malloc((n1+1)*(n2+1)*sizeof(double));
	fread((char*)buffer,sizeof(double),(n1+1)*(n2+1),fp);
	
	for(i=0;i<=n1;i++)
	{
		for(j=0;j<=n2;j++)
			w[i][j]=buffer[i*(n2+1)+j];
	}
	fclose(fp);
	free(buffer);
	return(true);
}

/*****保存各层结点的数目******/
void w_num(int n1,int n2,int n3,char*name)
{
	FILE *fp;
	fp=fopen(name,"wb+");
	int *buffer;
	buffer=(int*)malloc(3*sizeof(int));
	buffer[0]=n1;
	buffer[1]=n2;
	buffer[2]=n3;
	fwrite((char*)buffer,sizeof(int),3,fp);
	fclose(fp);
	free(buffer);
}

/********读取各层结点数目*********/

bool r_num(int *n,char *name)
{
	int *buffer;
	FILE *fp;
	buffer=(int *)malloc(3*sizeof(int));
	if((fp=fopen(name,"rb"))==NULL)
	{
		::MessageBox(NULL,"结点参数",NULL,MB_ICONSTOP);
		return (false);
	}
	fread((char*)buffer,sizeof(int),3,fp);
	n[0]=buffer[0];
	n[1]=buffer[1];
	n[2]=buffer[2];
	fclose(fp);
	free(buffer);
	return(true);
}
/********************************************************
* 函数名称 VerticalCode()
*
* 参量:
*   BYTE* lpDIBBits   -指向输入图像的象素其实位置的指针 
*   int  num          -图片中样本的个数
*   LONG lLineByte    -输入图片每行的字节数
*   LONG lSwidth      -预处理时归一化的宽度
*   LONG lSheight     -预处理时归一化的长度
*
* 返回值:
*   double**           -特征向量矩阵
*
*  函数功能 :
*      对于输入样本提取特征向量,在这里把归一化样本的
*	   水平和竖直方向的统计特征作为特征提取出来
***************************************************************/

double** VerticalCode(BYTE* lpDIBBits,int num, LONG lLineByte,LONG lSwidth,LONG lSheight)
{   
   //循环变量
    int i,j,k;
    BYTE* lpSrc; 
    
	//统计变量
	int sum;

    //  建立保存特征向量的二维数组
   double **data;
   
   // 为这个数组申请二维存储空间
   data = alloc_2d_dbl(num,lSwidth+lSheight);
 
   // 将归一化的样本的每个象素作为一个特征点提取出来

   //逐个数据扫描
   for(k=0;k<num;k++)  
   { 
     //统计每行的象素点个数
      for(i=0;i<lSheight;i++)
	  {    
        //对统计变量初始化
	 	  sum=0;

          //对每个数据逐列扫描
          for(j=k*lSwidth;j<(k+1)*lSwidth;j++)
		  {
            // 指向图像第i行第j列个象素的指针
            lpSrc = lpDIBBits + i*lLineByte + j;

             //如果这个象素是黑色的
             if(*(lpSrc)==0)

             //统计变量加1
                sum++;
		  }
         data[k][i]=sum;
	  }

    //统计每列的象素点个数
    for(j=k*lSwidth;j<(k+1)*lSwidth;j++)
	{    
        //对统计变量初始化
	 	  sum=0;

          //对每个数据逐行扫描
         for(i=0;i<lSheight;i++)
          {
            // 指向图像第i行第j列个象素的指针
            lpSrc = lpDIBBits + i*lLineByte + j;

             //如果这个象素是黑色的
             if(*(lpSrc)==0)

             //统计变量加1
                sum++;
		  }
         data[k][j-k*lSwidth+lSheight]=sum;
	  }

   }
 
//返回特征向量矩阵
   return(data);  
}

/*******************************************************************
*
*函数名称:
*	TZTQ_13
*参数:
*	HDIB hDIB				-待提取特征的位图的句柄
*	int num					-字符的数目
*	int dim					-提取特征的维数。这里固定为13
*说明:
*	图像分为8块,作为8个特征;象素总数作为一个特征;水平切割过去两条线,得*到两个特征;垂直的两个,总共得到13个特征
*
*********************************************************************/
double * * TZTQ_13(HDIB hDIB,int num,int dim)
{	
int i,j,k,m;

	//分配一个内存空间并得到二维指针
	double * * tezheng=alloc_2d_dbl(num,dim);

	//锁定图像句柄并获取其指针
	BYTE* lpDIB=(BYTE*)::GlobalLock ((HGLOBAL)hDIB);

	//取得图像象素数据区的起始地址
	BYTE* lpDIBBits=(BYTE*)::FindDIBBits((char*)lpDIB);
	BYTE* lpSrc;	

	//获取图像高度
	LONG lHeight=::DIBHeight ((char*)lpDIB);

	//获取图像宽度
	LONG lWidth=::DIBWidth ((char*)lpDIB);

	LONG width=lWidth/num;
	//每行的字节数
	LONG lLineBytes = WIDTHBYTES(lWidth * 8);

	int b;

	//存储临时的特征
	double * tz=new double[dim];

	for(k=0;k<num;k++)
	{	
		for(i=0;i<dim;i++) tz[i]=0;

		//提取前8个特征
		for(m=0;m<8;m++)
		{	for(i=int(m/2)*8;i<(int(m/2)+1)*8;i++)
				for(j=m%2*8+k*width;j<(m%2+1)*8+k*width;j++)
				{	lpSrc=(unsigned char*)lpDIBBits + lLineBytes *  i + j;

⌨️ 快捷键说明

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