这学期上了一门课叫DSP实验,学会了使用C5509A芯片,并且做了一系列实验,最后一个大PJ是使用DSP进行人脸识别。
基本思想是首先对人脸照片进行变换提取特征,最后在利用某种分类器对特征分类,用以决定属于哪一个人,最后再进行识别,计算准确度,这个项目主要是为了训练我们对于DSP的熟练情况和使用情况,同时了解一些小波变换和分类方法,仅用来学习,对于正确率没有要求,所以最后做好后准确率大概70%左右,也不算高。
首先我们小组利用的是harr小波变换进行特征提取
先简单说一下harr小波变换的原理:
小波变换(wavelettransform,WT)是一种新的变换分析方法,它继承和发展了短时傅立叶变换局部化的思想,同时又克服了窗口大小不随频率变化等缺点,能够提供一个随频率改变的“时间-频率”窗口,是进行信号时频分析和处理的理想工具。它的主要特点是通过变换能够充分突出问题某些方面的特征,能对时间(空间)频率的局部化分析,通过伸缩平移运算对信号(函数)逐步进行多尺度细化,最终达到高频处时间细分,低频处频率细分,能自动适应时频信号分析的要求,从而可聚焦到信号的任意细节,解决了Fourier变换的困难问题
哈尔函数是由Haar提出的一种正交完备函数系;是一种既反映整体又反映局部的函数;它是小波变换中的典型小波,;
哈尔变换和小波变换适用非平稳信号的分析与处理。
哈尔变换的特点:
(1) 具有尺度和位移两个特性;
(2) 变换范围窄;
(3) 其变换特性与图像中的边界或线条的特性十分接近,因此图像中的边缘和线条经哈尔变换后,会产生较大的变换系数,而其它区划的变换系数小。
因为DSP上直接进行小波变换的源码比较少,因此我们先从matlab入手,找到了部分matlab的harr变换源码
先了解harr变换的一维代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
function out=selfdwt(in,J) % 完成J尺度Haar小波变换 % in 是输入信号 % out 是输出的小波系数 %h0,h1是相应的小波和尺度向量 h0=[1/sqrt(2),1/sqrt(2)]; h1=[-1/sqrt(2),1/sqrt(2)]; out=zeros(size(in)); m=size(in);%此处的m为一向量 x=length(in); k=0; l=0; Wl=in; for i=1:J %=================此处对应于高频部分,结果中抽取偶数的点===================== Wh=conv(h1,Wl);%卷积函数 for j=1:(length(h1)+length(Wl)-1) if mod(j,2)==0%mod函数求j/2的模,相当于求余数,且余数一定是整数 k=k+1; out(round(x/2)+k)=Wh(j);%round是四舍五入函数,因为这里x一定是整数,所以roundx/2相当于如果x为偶数则为x/2,奇数则为x/2+1 end end %============================================================================ %===============下面对应于低频部分,结果中抽取偶数点========================= Wl1=conv(h0,Wl); for j=1:(length(h0)+length(Wl)-1) if mod(j,2)==0 l=l+1; out(l)=Wl1(j); end end %=========================================================================== x=round(x/2); m=round(m/2); Wl=zeros(m); for j=1:x Wl(j)=out(j); end k=0; l=0; end |
利用这个函数可以得到对二维图像进行harr变换的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
%对一幅图像I进行M尺度的小波变换 I=imread('s1.bmp'); M=1;% M----小波变换的尺度 I1=double(I);%强制转换类型为double型,I为512*512*3的像素数组 [m,n]=size(I);%m=128,n=128 Iout=zeros(size(I));%生成512*512*3的全零矩阵 W1=zeros(size(I));%生成512*512*3的全零矩阵 %=============Haar wavelete transform================== W1=I1;%W1=像素数组 for k=1:M%进行两次迭代 for i=1:n%对所有列进行变换 W1(:,i)=selfdwt(W1(:,i),1);%对列进行变换 end for i=1:m%对所有行进行变换 W1(i,:)=selfdwt(W1(i,:),1);%对行进行变换 end for i=1:m%输出值 for j=1:n Iout(i,j)=W1(i,j); end end m=m/2;%m=256 n=n/2;%m=256*3 W1=zeros(m,n);%生成第一次得出的结果 for i=1:m for j=1:m W1(i,j)=Iout(i,j); end end end %====================================================== %========================scaling归一化======================= [m,n]=size(I);%m=512,n=1536 min=0; for i=1:m for j=1:n if(Iout(i,j)<min) min=Iout(i,j); end end end%找出Iout中的最小值 Iout1=(Iout+abs(min))*.5;%将数组中的每个值加上最小值的绝对值保证为正数,在乘以0.5 max=255; for i=1:m for j=1:n if(Iout1(i,j)>max) max=Iout1(i,j); end end end%找出Iout1中的最大值 if(max>255) Iout1=(Iout1*(255/max)).*2; end%保证每个值的大小在0-255之间 %====================================================== Iout1(:,256)=255; Iout1(256,:)=255; Iout1(1:256,128)=255; Iout1(128,1:256)=255; Iout1(1:128,64)=255; Iout1(64,1:128)=255;%画分割线 figure imshow(uint8(Iout.*28)) title('uncaling') figure imshow(uint8(Iout1)) title('after scaling') %Iout2=imidwt2(Iout,M); |
调试的过程中要修改imdwt1.m文件中的第二行的图像名,图像放在与源码相同的目录下。
而分类器我们想要用的是KNN分类器,KNN分类器的原理和实现都非常简单,原理如下:
邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。
kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。
下图中,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。
K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 KNN方法虽然从原理上也依赖于极限定理,但在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。
KNN算法不仅可以用于分类,还可以用于回归。通过找出一个样本的k个最近邻居,将这些邻居的属性的平均值赋给该样本,就可以得到该样本的属性。更有用的方法是将不同距离的邻居对该样本产生的影响给予不同的权值(weight),如权值与距离成反比。
确定了算法之后,主要由三个工作,第一是把matlab的harr变换代码改成C语言代码,第二是写出KNN分类器,第三是把这两个结合起来。中间过程不说了,代码贴出来供大家学习。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
/******************************************宏定义begin************************************************/ #define IMAGEWIDTH 32//图像宽度 #define IMAGEHEIGHT 32//图像高度 #define LENGTH 32//图像进行一维harr变换时的长度,相当于图像宽度和高度 //来自例程文件,说明哪些图片 #define MODEPHOTO00 1 #define MODEPHOTO01 2 #define MODEPHOTO02 3 #define MODEPHOTO03 4 #define MODEPHOTO04 5 #define MODEPHOTO05 6 #define MODEPHOTO06 7 #define MODEPHOTO07 8 #define MODEPHOTO10 9 #define MODEPHOTO11 10 #define MODEPHOTO12 11 #define MODEPHOTO13 12 #define MODEPHOTO14 13 #define MODEPHOTO15 14 #define MODEPHOTO16 15 #define MODEPHOTO17 16 #define MODEPHOTO20 17 #define MODEPHOTO21 18 #define MODEPHOTO22 19 #define MODEPHOTO23 20 #define MODEPHOTO24 21 #define MODEPHOTO25 22 #define MODEPHOTO26 23 #define MODEPHOTO27 24 #define MODEPHOTO30 25 #define MODEPHOTO31 26 #define MODEPHOTO32 27 #define MODEPHOTO33 28 #define MODEPHOTO34 29 #define MODEPHOTO35 30 #define MODEPHOTO36 31 #define MODEPHOTO37 32 #define MODEPHOTO40 33 #define MODEPHOTO41 34 #define MODEPHOTO42 35 #define MODEPHOTO43 36 #define MODEPHOTO44 37 #define MODEPHOTO45 38 #define MODEPHOTO46 39 #define MODEPHOTO47 40 //#define TESTMATRIX 101 #define TRAINPHOTO00 101 #define TRAINPHOTO01 102 #define TRAINPHOTO02 103 #define TRAINPHOTO10 104 #define TRAINPHOTO11 105 #define TRAINPHOTO12 106 #define TRAINPHOTO20 107 #define TRAINPHOTO21 108 #define TRAINPHOTO22 109 #define TRAINPHOTO30 110 #define TRAINPHOTO31 111 #define TRAINPHOTO32 112 #define TRAINPHOTO40 113 #define TRAINPHOTO41 114 #define TRAINPHOTO42 115 #define GRAYBARLEVEL 16 /******************************************宏定义end************************************************/ void InitImage(unsigned int nMode,unsigned char *pImage,int nWidth,int nHeight); void conv(float* f,float* g,float* y,int length); void haarone(float *input,float *output,int length); void FloatImage(unsigned char *pImage,float *qImage,int nWidth,int nHeight); void UcharImage(float *pImage,unsigned char *qImage,int nWidth,int nHeight); void AddImage(float *pImage,int nWidth,int nHeight); void CopyImage(float *pImage,float *qImage,int nWidth,int nHeight); void MinImage(float *pImage,float *qImage,int nWidth,int nHeight); void MaxImage(float *pImage,float *qImage,int nWidth,int nHeight); unsigned int imageIndex[5][8]; unsigned int trainIndex[5][3]; unsigned char dbImage[IMAGEWIDTH*IMAGEHEIGHT];//输入图像 float outImage[IMAGEWIDTH][IMAGEHEIGHT];//输出图像 float changeImage[IMAGEWIDTH][IMAGEHEIGHT];//中间变量1 float nextImage[IMAGEWIDTH][IMAGEHEIGHT];//中间变量2 float endImage[IMAGEWIDTH/2][IMAGEHEIGHT/2]; int label[40]={1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5}; //unsigned char outcharImage[IMAGEWIDTH][IMAGEHEIGHT];//输出图像 //unsigned char changecharImage[IMAGEWIDTH][IMAGEHEIGHT];//中间变量1 //unsigned char nextcharImage[IMAGEWIDTH][IMAGEHEIGHT];//中间变量2 //定义所有图像的Harr特征数组 unsigned char endcharImage[40][IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char trainImage[15][IMAGEWIDTH/2][IMAGEHEIGHT/2]; /* unsigned char endcharImage00[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage01[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage02[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage03[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage04[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage05[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage06[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage07[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage10[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage11[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage12[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage13[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage14[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage15[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage16[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage17[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage20[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage21[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage22[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage23[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage24[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage25[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage26[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage27[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage30[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage31[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage32[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage33[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage34[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage35[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage36[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage37[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage40[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage41[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage42[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage43[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage44[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage45[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage46[IMAGEWIDTH/2][IMAGEHEIGHT/2]; unsigned char endcharImage47[IMAGEWIDTH/2][IMAGEHEIGHT/2]; */ float index[LENGTH]; float outdex[LENGTH]; int result[5][3]; int main() { int i,j,m,n; int a,b; int raw,col;//定义行和列变量 m=1; n=101; raw=IMAGEWIDTH; col=IMAGEHEIGHT; for(i=0;i<5;i++) for(j=0;j<8;j++) { imageIndex[i][j]= m; m++; }//设置图像索引数组 for(a=0;a<5;a++) for(b=0;b<8;b++) { InitImage(imageIndex[a][b],dbImage,IMAGEWIDTH,IMAGEHEIGHT);//读入图像 FloatImage(dbImage,*changeImage,IMAGEWIDTH,IMAGEHEIGHT);//强制转换为float型 for(i=0;i<col;i++) { for(j=0;j<raw;j++) { index[j]=changeImage[j][i]; } haarone(index,outdex,LENGTH); for(j=0;j<raw;j++) { changeImage[j][i]=outdex[j]; } }//对所有列进行harr变换 for(i=0;i<raw;i++) { for(j=0;j<col;j++) { index[j]=changeImage[i][j]; } haarone(index,outdex,LENGTH); for(j=0;j<col;j++) { changeImage[i][j]=outdex[j]; } } //对图像进行归一化,经过归一化之后轨迹主要在左上角方格的右下角中,大小为32*32 MinImage(*changeImage,*nextImage,IMAGEWIDTH,IMAGEHEIGHT); MaxImage(*nextImage,*outImage,IMAGEWIDTH,IMAGEHEIGHT); //特征存入endImage数组中并输出 /* AddImage(*changeImage,IMAGEWIDTH,IMAGEHEIGHT); UcharImage(*changeImage,*changecharImage,IMAGEWIDTH,IMAGEHEIGHT);//强制转换为float型//对所有的行进行harr变化 UcharImage(*outImage,*outcharImage,IMAGEWIDTH,IMAGEHEIGHT);//强制转换为float型//对所有的行进行harr变化 */ for(i=IMAGEHEIGHT/2;i<IMAGEHEIGHT;i++) { for(j=0;j<IMAGEWIDTH/2;j++) { endImage[i-IMAGEWIDTH/2][j]=outImage[i][j]; //printf("%f\t",endImage[i-IMAGEWIDTH/4][j]); } //printf("\n"); } UcharImage(*endImage,*(endcharImage[8*a+b]),IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 /* switch (imageIndex[a][b]) { case MODEPHOTO00: UcharImage(*endImage,*endcharImage00,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO01: UcharImage(*endImage,*endcharImage01,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO02: UcharImage(*endImage,*endcharImage02,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO03: UcharImage(*endImage,*endcharImage03,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO04: UcharImage(*endImage,*endcharImage04,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO05: UcharImage(*endImage,*endcharImage05,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO06: UcharImage(*endImage,*endcharImage06,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO07: UcharImage(*endImage,*endcharImage07,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO10: UcharImage(*endImage,*endcharImage10,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO11: UcharImage(*endImage,*endcharImage11,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO12: UcharImage(*endImage,*endcharImage12,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO13: UcharImage(*endImage,*endcharImage13,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO14: UcharImage(*endImage,*endcharImage14,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO15: UcharImage(*endImage,*endcharImage15,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO16: UcharImage(*endImage,*endcharImage16,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO17: UcharImage(*endImage,*endcharImage17,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO20: UcharImage(*endImage,*endcharImage20,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO21: UcharImage(*endImage,*endcharImage21,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO22: UcharImage(*endImage,*endcharImage22,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO23: UcharImage(*endImage,*endcharImage23,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO24: UcharImage(*endImage,*endcharImage24,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO25: UcharImage(*endImage,*endcharImage25,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO26: UcharImage(*endImage,*endcharImage26,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO27: UcharImage(*endImage,*endcharImage27,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO30: UcharImage(*endImage,*endcharImage30,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO31: UcharImage(*endImage,*endcharImage31,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO32: UcharImage(*endImage,*endcharImage32,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO33: UcharImage(*endImage,*endcharImage33,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO34: UcharImage(*endImage,*endcharImage34,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO35: UcharImage(*endImage,*endcharImage35,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO36: UcharImage(*endImage,*endcharImage36,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; case MODEPHOTO37: UcharImage(*endImage,*endcharImage37,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 break; default: break; } */ //UcharImage(*endImage,*endcharImage,IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 } //while (1); /*******************************************生成测试图形数据**************************************************/ for(i=0;i<5;i++) for(j=0;j<3;j++) { trainIndex[i][j]= n; n++; }//设置图像索引数组 for(a=0;a<5;a++) for(b=0;b<3;b++) { InitImage(trainIndex[a][b],dbImage,IMAGEWIDTH,IMAGEHEIGHT);//读入图像 FloatImage(dbImage,*changeImage,IMAGEWIDTH,IMAGEHEIGHT);//强制转换为float型 for(i=0;i<col;i++) { for(j=0;j<raw;j++) { index[j]=changeImage[j][i]; } haarone(index,outdex,LENGTH); for(j=0;j<raw;j++) { changeImage[j][i]=outdex[j]; } }//对所有列进行harr变换 for(i=0;i<raw;i++) { for(j=0;j<col;j++) { index[j]=changeImage[i][j]; } haarone(index,outdex,LENGTH); for(j=0;j<col;j++) { changeImage[i][j]=outdex[j]; } } //对图像进行归一化,经过归一化之后轨迹主要在左上角方格的右下角中,大小为32*32 MinImage(*changeImage,*nextImage,IMAGEWIDTH,IMAGEHEIGHT); MaxImage(*nextImage,*outImage,IMAGEWIDTH,IMAGEHEIGHT); //特征存入endImage数组中并输出 /* AddImage(*changeImage,IMAGEWIDTH,IMAGEHEIGHT); UcharImage(*changeImage,*changecharImage,IMAGEWIDTH,IMAGEHEIGHT);//强制转换为float型//对所有的行进行harr变化 32UcharImage(*outImage,*outcharImage,IMAGEWIDTH,IMAGEHEIGHT);//强制转换为float型//对所有的行进行harr变化 */ for(i=IMAGEHEIGHT/2;i<IMAGEHEIGHT;i++) { for(j=0;j<IMAGEWIDTH/2;j++) { endImage[i-IMAGEWIDTH/2][j]=outImage[i][j]; //printf("%f\t",endImage[i-IMAGEWIDTH/4][j]); } //printf("\n"); } UcharImage(*endImage,*(trainImage[3*a+b]),IMAGEWIDTH/2,IMAGEHEIGHT/2);//强制转换为float型//对所有的行进行harr变化 } /*******************************************生成测试结果**************************************************/ for(i=0;i<5;i++) for(j=0;j<3;j++) result[i][j]=KNNclassify(trainImage[3*i+j],endcharImage,label); //printf("%d",result); } |
这个是主函数,首先的宏代表的是不同的图片,MODEPHOTO的40张是训练的图片,TRAINPHOTO的15张是测试的图片,所以最后只要看这15张有几张是满足要求的即可。下方是一些函数的声明,InitImage用来读取图片,conv是卷积运算,harrone是一维harr百年换,FloatImage将unsigned char型的图片数组转化为Float型,UcharImage将float型转化为unsigned char型,AddImage是对图像的像素值做放大,CopyImage将一个图像数组复制到另一个数组中,MinImage和MaxImage分别限定图像的像素最大值和最小值。
要注意所有全局变量的定义要放在main函数外,否则DSP会报错
全局变量中imageIndex代表训练的图像的标签,5组,每组8张正好40张,trainIndex代表测试的图片的标签,5组每组3张正好15张,进入main函数后,首先让训练的40张图分别对应1-40这40个数字,然后分别对没张图片做harr变换,提取出特征值存入三维数组中。接着对测试的15张图片进行同样的操作。最后利用KNN的函数得出结果存在result数组中,按理说result的结果应该为111,222,333,444,555则是完全正确的,若不对可以计算正确率。
所有的函数定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 |
#include<stdio.h> /******************************************宏定义begin************************************************/ #define IMAGEWIDTH 32//图像宽度 #define IMAGEHEIGHT 32//图像高度 #define LENGTH 32//图像进行一维harr变换时的长度,相当于图像宽度和高度 //来自例程文件,说明哪些图片 #define MODEPHOTO00 1 #define MODEPHOTO01 2 #define MODEPHOTO02 3 #define MODEPHOTO03 4 #define MODEPHOTO04 5 #define MODEPHOTO05 6 #define MODEPHOTO06 7 #define MODEPHOTO07 8 #define MODEPHOTO10 9 #define MODEPHOTO11 10 #define MODEPHOTO12 11 #define MODEPHOTO13 12 #define MODEPHOTO14 13 #define MODEPHOTO15 14 #define MODEPHOTO16 15 #define MODEPHOTO17 16 #define MODEPHOTO20 17 #define MODEPHOTO21 18 #define MODEPHOTO22 19 #define MODEPHOTO23 20 #define MODEPHOTO24 21 #define MODEPHOTO25 22 #define MODEPHOTO26 23 #define MODEPHOTO27 24 #define MODEPHOTO30 25 #define MODEPHOTO31 26 #define MODEPHOTO32 27 #define MODEPHOTO33 28 #define MODEPHOTO34 29 #define MODEPHOTO35 30 #define MODEPHOTO36 31 #define MODEPHOTO37 32 #define MODEPHOTO40 33 #define MODEPHOTO41 34 #define MODEPHOTO42 35 #define MODEPHOTO43 36 #define MODEPHOTO44 37 #define MODEPHOTO45 38 #define MODEPHOTO46 39 #define MODEPHOTO47 40 //#define TESTMATRIX 101 #define TRAINPHOTO00 101 #define TRAINPHOTO01 102 #define TRAINPHOTO02 103 #define TRAINPHOTO10 104 #define TRAINPHOTO11 105 #define TRAINPHOTO12 106 #define TRAINPHOTO20 107 #define TRAINPHOTO21 108 #define TRAINPHOTO22 109 #define TRAINPHOTO30 110 #define TRAINPHOTO31 111 #define TRAINPHOTO32 112 #define TRAINPHOTO40 113 #define TRAINPHOTO41 114 #define TRAINPHOTO42 115 #define GRAYBARLEVEL 16 /******************************************宏定义end************************************************/ /******************************************函数定义begin************************************************/ /*以下两个函数来自例程文件,读入一张图片并存到一个一维数组中*/ void ReadImage(unsigned char *pImage,char *cFileName,int nWidth,int nHeight); void InitImage(unsigned int nMode,unsigned char *pImage,int nWidth,int nHeight) { switch ( nMode ) { case MODEPHOTO00: ReadImage(pImage,"..\\learn\\01\\s1.bmp",nWidth,nHeight); break; case MODEPHOTO01: ReadImage(pImage,"..\\learn\\01\\s2.bmp",nWidth,nHeight); break; case MODEPHOTO02: ReadImage(pImage,"..\\learn\\01\\s3.bmp",nWidth,nHeight); break; case MODEPHOTO03: ReadImage(pImage,"..\\learn\\01\\s4.bmp",nWidth,nHeight); break; case MODEPHOTO04: ReadImage(pImage,"..\\learn\\01\\s5.bmp",nWidth,nHeight); break; case MODEPHOTO05: ReadImage(pImage,"..\\learn\\01\\s6.bmp",nWidth,nHeight); break; case MODEPHOTO06: ReadImage(pImage,"..\\learn\\01\\s7.bmp",nWidth,nHeight); break; case MODEPHOTO07: ReadImage(pImage,"..\\learn\\01\\s8.bmp",nWidth,nHeight); break; case MODEPHOTO10: ReadImage(pImage,"..\\learn\\02\\s1.bmp",nWidth,nHeight); break; case MODEPHOTO11: ReadImage(pImage,"..\\learn\\02\\s2.bmp",nWidth,nHeight); break; case MODEPHOTO12: ReadImage(pImage,"..\\learn\\02\\s3.bmp",nWidth,nHeight); break; case MODEPHOTO13: ReadImage(pImage,"..\\learn\\02\\s4.bmp",nWidth,nHeight); break; case MODEPHOTO14: ReadImage(pImage,"..\\learn\\02\\s5.bmp",nWidth,nHeight); break; case MODEPHOTO15: ReadImage(pImage,"..\\learn\\02\\s6.bmp",nWidth,nHeight); break; case MODEPHOTO16: ReadImage(pImage,"..\\learn\\02\\s7.bmp",nWidth,nHeight); break; case MODEPHOTO17: ReadImage(pImage,"..\\learn\\02\\s8.bmp",nWidth,nHeight); break; case MODEPHOTO20: ReadImage(pImage,"..\\learn\\03\\s1.bmp",nWidth,nHeight); break; case MODEPHOTO21: ReadImage(pImage,"..\\learn\\03\\s2.bmp",nWidth,nHeight); break; case MODEPHOTO22: ReadImage(pImage,"..\\learn\\03\\s3.bmp",nWidth,nHeight); break; case MODEPHOTO23: ReadImage(pImage,"..\\learn\\03\\s4.bmp",nWidth,nHeight); break; case MODEPHOTO24: ReadImage(pImage,"..\\learn\\03\\s5.bmp",nWidth,nHeight); break; case MODEPHOTO25: ReadImage(pImage,"..\\learn\\03\\s6.bmp",nWidth,nHeight); break; case MODEPHOTO26: ReadImage(pImage,"..\\learn\\03\\s7.bmp",nWidth,nHeight); break; case MODEPHOTO27: ReadImage(pImage,"..\\learn\\03\\s8.bmp",nWidth,nHeight); break; case MODEPHOTO30: ReadImage(pImage,"..\\learn\\04\\s1.bmp",nWidth,nHeight); break; case MODEPHOTO31: ReadImage(pImage,"..\\learn\\04\\s2.bmp",nWidth,nHeight); break; case MODEPHOTO32: ReadImage(pImage,"..\\learn\\04\\s3.bmp",nWidth,nHeight); break; case MODEPHOTO33: ReadImage(pImage,"..\\learn\\04\\s4.bmp",nWidth,nHeight); break; case MODEPHOTO34: ReadImage(pImage,"..\\learn\\04\\s5.bmp",nWidth,nHeight); break; case MODEPHOTO35: ReadImage(pImage,"..\\learn\\04\\s6.bmp",nWidth,nHeight); break; case MODEPHOTO36: ReadImage(pImage,"..\\learn\\04\\s7.bmp",nWidth,nHeight); break; case MODEPHOTO37: ReadImage(pImage,"..\\learn\\04\\s8.bmp",nWidth,nHeight); break; case MODEPHOTO40: ReadImage(pImage,"..\\learn\\05\\s1.bmp",nWidth,nHeight); break; case MODEPHOTO41: ReadImage(pImage,"..\\learn\\05\\s2.bmp",nWidth,nHeight); break; case MODEPHOTO42: ReadImage(pImage,"..\\learn\\05\\s3.bmp",nWidth,nHeight); break; case MODEPHOTO43: ReadImage(pImage,"..\\learn\\05\\s4.bmp",nWidth,nHeight); break; case MODEPHOTO44: ReadImage(pImage,"..\\learn\\05\\s5.bmp",nWidth,nHeight); break; case MODEPHOTO45: ReadImage(pImage,"..\\learn\\05\\s6.bmp",nWidth,nHeight); break; case MODEPHOTO46: ReadImage(pImage,"..\\learn\\05\\s7.bmp",nWidth,nHeight); break; case MODEPHOTO47: ReadImage(pImage,"..\\learn\\05\\s8.bmp",nWidth,nHeight); break; case TRAINPHOTO00: ReadImage(pImage,"..\\train\\01\\s9.bmp",nWidth,nHeight); break; case TRAINPHOTO01: ReadImage(pImage,"..\\train\\01\\s10.bmp",nWidth,nHeight); break; case TRAINPHOTO02: ReadImage(pImage,"..\\train\\01\\s11.bmp",nWidth,nHeight); break; case TRAINPHOTO10: ReadImage(pImage,"..\\train\\02\\s9.bmp",nWidth,nHeight); break; case TRAINPHOTO11: ReadImage(pImage,"..\\train\\02\\s10.bmp",nWidth,nHeight); break; case TRAINPHOTO12: ReadImage(pImage,"..\\train\\02\\s11.bmp",nWidth,nHeight); break; case TRAINPHOTO20: ReadImage(pImage,"..\\train\\03\\s9.bmp",nWidth,nHeight); break; case TRAINPHOTO21: ReadImage(pImage,"..\\train\\03\\s10.bmp",nWidth,nHeight); break; case TRAINPHOTO22: ReadImage(pImage,"..\\train\\03\\s11.bmp",nWidth,nHeight); break; case TRAINPHOTO30: ReadImage(pImage,"..\\train\\04\\s9.bmp",nWidth,nHeight); break; case TRAINPHOTO31: ReadImage(pImage,"..\\train\\04\\s10.bmp",nWidth,nHeight); break; case TRAINPHOTO32: ReadImage(pImage,"..\\train\\04\\s11.bmp",nWidth,nHeight); break; case TRAINPHOTO40: ReadImage(pImage,"..\\train\\05\\s9.bmp",nWidth,nHeight); break; case TRAINPHOTO41: ReadImage(pImage,"..\\train\\05\\s10.bmp",nWidth,nHeight); break; case TRAINPHOTO42: ReadImage(pImage,"..\\train\\05\\s11.bmp",nWidth,nHeight); break; /* case TRAINPHOTO00: ReadImage(pImage,"..\\train\\01\\s9.bmp",nWidth,nHeight); break; case TRAINPHOTO01: ReadImage(pImage,"..\\train\\01\\s10.bmp",nWidth,nHeight); break; case TRAINPHOTO02: ReadImage(pImage,"..\\train\\01\\s11.bmp",nWidth,nHeight); break; case TRAINPHOTO10: ReadImage(pImage,"..\\train\\02\\s9.bmp",nWidth,nHeight); break; case TRAINPHOTO11: ReadImage(pImage,"..\\train\\02\\s10.bmp",nWidth,nHeight); break; case TRAINPHOTO12: ReadImage(pImage,"..\\train\\02\\s11.bmp",nWidth,nHeight); break; case TRAINPHOTO20: ReadImage(pImage,"..\\train\\03\\s9.bmp",nWidth,nHeight); break; case TRAINPHOTO21: ReadImage(pImage,"..\\train\\03\\s10.bmp",nWidth,nHeight); break; case TRAINPHOTO22: ReadImage(pImage,"..\\train\\03\\s11.bmp",nWidth,nHeight); break; case TRAINPHOTO30: ReadImage(pImage,"..\\train\\04\\s9.bmp",nWidth,nHeight); break; case TRAINPHOTO31: ReadImage(pImage,"..\\train\\04\\s10.bmp",nWidth,nHeight); break; case TRAINPHOTO32: ReadImage(pImage,"..\\train\\04\\s11.bmp",nWidth,nHeight); break; case TRAINPHOTO40: ReadImage(pImage,"..\\train\\05\\s9.bmp",nWidth,nHeight); break; case TRAINPHOTO41: ReadImage(pImage,"..\\train\\05\\s10.bmp",nWidth,nHeight); break; case TRAINPHOTO42: ReadImage(pImage,"..\\train\\05\\s11.bmp",nWidth,nHeight); break; */ default: break; } } void ReadImage(unsigned char *pImage,char *cFileName,int nWidth,int nHeight) { int j; unsigned char *pWork; FILE *fp; if ( fp=fopen(cFileName,"rb" ) ) { fseek(fp,1078L,SEEK_SET); pWork=pImage+(nHeight-1)*nWidth; for ( j=0;j<nHeight;j++,pWork-=nWidth ) fread(pWork,nWidth,1,fp); fclose(fp); } } /*以下两个函数达到计算卷积的目的,因为matlab自带的是循环卷积,所以相当于线性卷积做了一点变形*/ float convolute(float* f,float* g, int k, int length) { int n =0; float sum = 0; if(k>length) k = length; for(n=0;n!=k+1;n++){ sum+=(f[n]*g[k-n]); } return sum; } void conv(float* f,float* g,float* y,int length) { int k; for(k=0;k<length+1;k++,y++){ *y=convolute(f,g,k,length+1); //printf("%f\n",*y); } } /* int round(float x) { if(int(x)%2==0) return x; else return (x+0.5); } */ /*一维harr小波变换*/ void haarone(float *input,float *output,int length) { int i,k,l,x; //定义小波尺度向量 float h0[LENGTH+1]={0.7071,0.7071}; float h1[LENGTH+1]={-0.7071,0.7071}; //定义变量数组 float wh[LENGTH+1]; float wh1[LENGTH+1]; float *pWork; pWork=input; //定义变量 k=0; l=0; x=LENGTH; //高频部分提取结果中偶数的点 conv(pWork,h1,wh,LENGTH); for(i=0;i<LENGTH+1;i++) { if(i%2==1) { output[x/2+k]=wh[i]; k++; } } //低频部分提取结果中的偶数点 conv(pWork,h0,wh1,LENGTH); for(i=0;i<LENGTH+1;i++) { if(i%2==1) { output[l]=wh1[i]; l++; } } k=0; l=0; } /*将unsigned char型的数组编程float型,方便计算 */ void FloatImage(unsigned char *pImage,float *qImage,int nWidth,int nHeight) { int i,j; unsigned char *pWork; pWork=pImage; for ( i=0;i<nHeight;i++ ) { for ( j=0;j<nWidth;j++,pWork++,qImage++ ) { *qImage=(float)(*pWork); } } } /*将float型的数组编程unsigned char型,方便计算 */ void UcharImage(float *pImage,unsigned char *qImage,int nWidth,int nHeight) { int i,j; float *pWork; pWork=pImage; for ( i=0;i<nHeight;i++ ) { for ( j=0;j<nWidth;j++,pWork++,qImage++ ) { *qImage=(unsigned char)(*pWork); } } } /*将数组的每个值放大28倍型,方便计算 */ void AddImage(float *pImage,int nWidth,int nHeight) { int i,j; //float *pWork; //pWork=pImage; for ( i=0;i<nHeight;i++ ) { for ( j=0;j<nWidth;j++,pImage++ ) { *pImage=28*(*pImage); if(*pImage>255.0) { *pImage=255.0; } if(*pImage<0.0) { *pImage=0.0; } } } } /*把以个数组中的内容复制到另一个数组(相当于把一幅图像复制到另一个数组中,允许一维数组复制到二维数组)*/ void CopyImage(float *pImage,float *qImage,int nWidth,int nHeight) { int i,j; float *pWork; pWork=pImage; for ( i=0;i<nHeight;i++ ) { for ( j=0;j<nWidth;j++,pWork++,qImage++ ) { *qImage=*pWork; } } } /*求一个数的绝对值*/ float absfloat(float index) { if(index<=0.0) index=-index; return index; } /*把p图像的最小值变到0以上,p赋值给q图像,用于图像归一化*/ void MinImage(float *pImage,float *qImage,int nWidth,int nHeight) { int i,j; float min=0.0; float *pWork; pWork=pImage; for (i=0;i<nHeight;i++ ) { for (j=0;j<nWidth;j++,pWork++) { if(*pWork<min) min=*pWork; } } //printf("\nmin=%f\n",min); pWork=pImage; for ( i=0;i<nHeight;i++ ) { for ( j=0;j<nWidth;j++,pWork++,qImage++) { *qImage=(*pWork+absfloat(min))*0.5; } } } /*把p图像的最大值限制到225以下,p赋值给q图像,用于图像归一化*/ void MaxImage(float *pImage,float *qImage,int nWidth,int nHeight) { int i,j; float max=255.0; float *pWork; pWork=pImage; for ( i=0;i<nHeight;i++ ) { for ( j=0;j<nWidth;j++,pWork++) { if(*pWork>max) max=*pWork; } } //printf("\nmax=%f\n",max); pWork=pImage; if(max>=255.0) { for ( i=0;i<nHeight;i++ ) { for ( j=0;j<nWidth;j++,pWork++,qImage++) { *qImage=(*pWork*(255.0/max))*2; } } } } /*****************************************函数定义end************************************************/ /******************************************测试主函数begin************************************************/ /* void main_test() { int i; float input[IMAGEWIDTH][IMAGEHEIGHT]={-20,37,290,-4}; float output[IMAGEWIDTH][IMAGEHEIGHT]={0,0,0,0}; float change[IMAGEWIDTH][IMAGEHEIGHT]={9,48.45,300,13.6}; float in[11]={1,2,3,4,5,6,7,8,9,10}; float out[11]={0,0,0,0,0,0,0,0,0,0,0}; for(i=0;i<11;i++) printf("%f\t%f\n",in[i],out[i]); haarone(in,out,10); printf("\n\n"); for(i=0;i<11;i++) printf("%f\t%f\n",in[i],out[i]); CopyImage(*input,*output,IMAGEWIDTH,IMAGEHEIGHT); MinImage(*input,*change,IMAGEWIDTH,IMAGEHEIGHT); for(int i=0;i<2;i++) for(int j=0;j<2;j++) { printf("%f\t%f\t%f\n",input[i][j],change[i][j],output[i][j]); } printf("\n\n"); CopyImage(*change,*input,IMAGEWIDTH,IMAGEHEIGHT); for(int i=0;i<2;i++) for(int j=0;j<2;j++) { printf("%f\t%f\t%f\n",input[i][j],change[i][j],output[i][j]); } printf("\n\n"); MaxImage(*change,*output,IMAGEWIDTH,IMAGEHEIGHT); for(int i=0;i<2;i++) for(int j=0;j<2;j++) { printf("%f\t%f\t%f\n",input[i][j],change[i][j],output[i][j]); } } */ /******************************************测试主函数end************************************************/ [/sourcecode] <p> KNN分类器的函数定义如下: </p> [sourcecode language="c"] #include "KNN.h" float MaxVecLoc(float* vec, int n_vecNum, int* loc) //计算数组中的最大值,返回值为最大值,并且参数中的指针loc指向最大值的位置 { int i; float maxn=vec[0]; *loc=0; for (i=0;i<n_vecNum;i++) { if(maxn<vec[i]) { maxn=vec[i]; *loc=i; } } return maxn; } int label_most(int* labels) { int i,lmax=0; int index; int l[5]={0,0,0,0,0};//统计每个分组的“票数” for (i=0;i<K_KNN;i++) l[labels[i]-1]++; for(i=0;i<5;i++) { if(l[i]>lmax) lmax=l[i]; } for(i=0;i<5;i++) { if(l[i]==lmax) index= i+1; } return index; } float distance(unsigned char *test, unsigned char *train)//已修改 //////////////////////////////////////////////////////////////////////////////////////////////////////// // // 求 vector1=(x1,x2,...,xn)和vector2=(y1,y2,...,yn)的欧几里德距离 // //////////////////////////////////////////////////////////////////////////////////////////////////////// { float dist; float sum=0.0; int i,j; for (i=0;i<16;i++) for (j=0;j<16;j++) { sum+=(*test-*train)*(*test-*train); test++; train++; } dist=sqrt(sum); return dist; } int KNNclassify(unsigned char* testPerFeature/*单个测试样本(1个)*/,unsigned char trainFeatureMaxtix[][16][16]/*训练样本集(40个训练样本)*/, int* label) //单个测试样本所属类别 { int i,loc=0,predictResult=0; float dist=0.0; //K_KNN=5 float K_Neighbor_dist[K_KNN];//存储该测试样本最邻近的K_KNN个训练样本 unsigned char K_Neighbor_Index[K_KNN];//存储该测试样本最邻近的K_KNN个训练样本是哪个 int K_Neighbor_Label[K_KNN]={0};// for (i=0;i<K_KNN;i++) { K_Neighbor_dist[i]=MAXKNN;//MAXKNN足够大 } for (i=0;i<40;i++) { //计算一个测试样本和每个训练样本的距离 dist=distance(testPerFeature,*(trainFeatureMaxtix[i])); //求K个最邻近距离 if (dist<MaxVecLoc(K_Neighbor_dist,K_KNN,&loc)) { K_Neighbor_dist[loc]=dist; K_Neighbor_Index[loc]=i; K_Neighbor_Label[loc]=label[i]; } } //求测试样本所属类别 predictResult=label_most(K_Neighbor_Label); return predictResult; } [/sourcecode] <p> KNN分类器的头文件定义如下: </p> [sourcecode language="c"] #include <math.h> #include <stdlib.h> #include <stdio.h> #define K_KNN 6 #define MAXKNN 100000000000 float distance(unsigned char *test, unsigned char *train); int KNNclassify(unsigned char* testPerFeature,unsigned char trainFeatureVec[][16][16], int* label); float MaxVecLoc(float* vec, int n_vecNum, int* loc); int label_most(int* labels); |
最后的项目文件可以到这个地址下载:
http://download.csdn.net/detail/shenda123/9401703