ImageProcessing.cpp
上传用户:cjd055
上传日期:2013-04-01
资源大小:608k
文件大小:41k
源码类别:

交通/航空行业

开发平台:

Visual C++

  1. #include <stdafx.h>
  2. #include <windows.h>
  3. #include <math.h>
  4. #include <malloc.h>
  5. #include "resource.h"
  6. #include "BmpTest.h"
  7. #include "BmpTestDoc.h"
  8. /********************************************************************   *
  9. *                                                                       *
  10. * ro_angle:rotated angle                                                *
  11. * size :the size of the rotated bitmap                                  *
  12. * pav_cent:the rotate centre                                                                      *
  13. *   **********************************************************************/                                                                  
  14.                                                                   
  15. extern void Sh_Rotate(CBmpTestDoc* pDoc,double ro_angle,double size,POINT *pav_cent) 
  16. {
  17. BYTE *lp=pDoc->m_Dib.m_Buffer,*ltemp;
  18. int  m,n;    
  19.     unsigned int  a,b,d,j,k,stand=150,Height,Width,BPL,i;
  20.     DWORD    shift,y_value;
  21.     DWORD    large;
  22.     double   rotate,x_value,sinth,costh;
  23.     m=pav_cent->x;
  24.     n=pav_cent->y; 
  25. sinth=sin(-ro_angle);
  26. Height=(int) pDoc->m_Dib.Height;
  27. Width=(int) pDoc->m_Dib.Width;
  28.     BPL=(int) pDoc->m_Dib.Bpl;
  29. costh=cos(-ro_angle);
  30. //loritemp 是本地的图像副本总指针,ltemp指向数据区,biSize是BITMAPINFORHEADER的大小为40
  31. ltemp=new BYTE[9600];
  32.     //initioalize the new field orign lpbi->biSizeImage
  33.     for(j=0;j<9600;j++)
  34. *(ltemp+j)=0; 
  35.    //if it is the bmppoint then enlage
  36.     for(k=0;k<Height;k++)
  37.     {
  38.     for(i=0;i<=(int)(Width/8);i++)
  39.     { 
  40.      if((i+1)*8<Width)
  41.        d=8;
  42.      else
  43.        d=(unsigned)(Width-i*8);
  44.       a=128;
  45.      if(d!=0)
  46.      {
  47.      for(j=0;j<d;j++)
  48.      {
  49.    //if the bit is equal to 0 it is background
  50. if((*(lp+(LONG)i+(LONG)k*BPL) & a) ==0)
  51.       a=a>>1;
  52. else
  53. {
  54. //i is the x coordinate so it is byte
  55.       x_value=(float)8*i+(float)j;
  56.       rotate=(x_value -m)*(costh)-(sinth) *((float)k-n);
  57.      rotate*=(double)110.0/size;  
  58.      rotate+=(double)160.0;
  59.       large=(int)(rotate/8);
  60.       shift=(int)rotate-large*8;
  61. b=128;
  62. //shift>=0 it is in the next store,本身他已处于下一单元(i 从零开始)        
  63.       y_value=(LONG)(((x_value -m)*sinth+costh*((float)k-n))
  64.         *110.0/size +(float)120 )*(LONG)(40);
  65.       large +=y_value;
  66.       b=b>>shift;
  67.       if(large < (9600-1))
  68.       *(ltemp+large)|= b;
  69.       a=a>>1;
  70. }
  71.  }
  72.      }    
  73.     }
  74.      }
  75.  // If the driver did not fill in the biSizeImage field, make one up 
  76.      pDoc->m_Dib.Width=320;
  77.      pDoc->m_Dib.Height=300;
  78.      pDoc->m_Dib.Resize(9600);
  79.  for(j=0;j<9600;j++)
  80.  {
  81.  *(pDoc->m_Dib.m_Buffer+j)=*(ltemp+j);
  82.  *(pDoc->m_Dib.m_Buffer1+j)=*(ltemp+j);
  83.  }
  84.    if(lp)
  85.  {
  86. delete [] lp;
  87. lp=0;
  88.  }
  89.    if(ltemp)
  90.  {
  91. delete [] ltemp;
  92. ltemp=0;
  93.  }
  94. }
  95.   
  96. /**************************************************************************
  97. *  n                                      *
  98. *  gcc:the gravity contour centre of the bitmap                            *
  99. ***************************************************************************/
  100. extern BOOL  GCC(CBmpTestDoc* pDoc,double *n,POINT *gcc)
  101. {
  102. //1:xnear 2:xfarer 3:ynear 4:yfarer
  103. BYTE *lp=pDoc->m_Dib.m_Buffer;
  104.    char name1[2]="1",name2[2]="2",name3[2]="3",name4[2]="4";
  105.     int i,k,tempx,xImagecon[2000],BPL,black,white,Height,Width;
  106.     unsigned int a=1,d,j,maxx,minx;
  107.     DWORD  x=0,y=0,centx=0,centy=0,counts=0;//counts represents the conunt of the contour
  108.     //cent represent the center_mass while av_cent represent the average center
  109.     DISTANCE   xdis[50];
  110.     PDISTANCE     pdis;
  111.     //let x repreterative the near  and y represertive the far 
  112. POINT Imagecon[100],min,max,last,cent,av_cent,*pcent,*pav_cent;
  113. //float distwo;
  114. BOOL maxfind=FALSE,minfind=FALSE,begin=TRUE,equal1,equal2,equal3;
  115. double l,dis,midx,midy,d_centx,d_centy;
  116. Height=(int) pDoc->m_Dib.Height;
  117. Width=(int) pDoc->m_Dib.Width;
  118. BPL=(int) pDoc->m_Dib.Bpl;
  119.     pcent=&cent;
  120.     pav_cent=&av_cent;
  121.     pdis=xdis;
  122.     for(i=0;i<50;i++)
  123.     (pdis+i)->number=0;    
  124.     for(i=0;i<2000;i++)
  125.     xImagecon[i]=0;
  126.     for(i=0;i<100;i++)
  127.     {
  128.     Imagecon[i].x=0;
  129. Imagecon[i].y=0;
  130.     }
  131.     for(k=0;k<Height;k++)
  132. {
  133.       for(i=0;i<=(int)((Width)/8);i++)
  134.   {  
  135.           a=255;
  136.   if(((*(lp+i+k*BPL)) & a) ==0)
  137.  continue; 
  138.       if((i+1)*8<(Width))
  139.        d=8;
  140.       else
  141.        d=(unsigned)((Width)-i*8);
  142.       a=128;
  143.       if(d!=0)
  144.   {
  145.      for(j=0;j<d;j++)
  146.      {
  147. //if the bit is equal to 0 it is background
  148.         if(((*(lp+i+k*BPL)) & a) ==0)
  149.       { y++;
  150.        a=a>>1;}
  151.         else
  152. {   x++;
  153.                         a=a>>1;
  154.     centx=(WORD)i*8+j+centx;
  155.     centy=(WORD)k+centy;
  156.  //分别求出从两个方向的投影点的轮廓
  157.  //从x方向求 k为其 坐标
  158. if(xImagecon[k] ==0)
  159. xImagecon[k] =i*8+j;    
  160. xImagecon[500+k] =max(xImagecon[500+k],i*8+(int)j);    
  161. xImagecon[k] =min(xImagecon[k],i*8+(int)j);
  162.  //从y方向求tempx为其坐标 
  163. tempx=i*8+j;
  164. if(xImagecon[1000+tempx]==0) 
  165. xImagecon[1000+tempx] =k;    
  166.             xImagecon[1500+tempx] =max(xImagecon[1500+tempx],k);
  167. xImagecon[1000+tempx] =min(xImagecon[1000+tempx],k);    
  168. }
  169.          }
  170.      }    
  171.     }
  172.     }                     
  173.  
  174.  //图的直方图
  175.     black=y;
  176.     white=x;
  177.  //求重心
  178. d_centx=((double)centx/x);
  179. d_centy=((double) centy/x);
  180.     for(k=0;k<4;k++)
  181.     {
  182.     max.x=0;
  183. max.y=0;
  184. min.x=0;
  185. min.y=0;
  186. j=0;
  187. maxx=0;
  188. begin=TRUE;
  189. maxfind=FALSE;
  190. minfind=FALSE;
  191.     for(i=1;i<500;i++)
  192.     {
  193.     //i  值为其 y方向的值 xImagecon 存的是X方向的最近和最远
  194.     if(xImagecon[k*500+i] !=0) 
  195.     {
  196.       if(max.x==0) 
  197.       {
  198.        max.x=xImagecon[k*500+i];
  199. //the first point is a contour point
  200.       if(j==0)
  201. {   j++;
  202. if(k<2)
  203. {
  204. Imagecon[k*20+j].x=max.x;
  205. Imagecon[k*20+j].y=i; 
  206. j++;
  207. }
  208.      else
  209.      {
  210. Imagecon[k*20+j].y=max.x;
  211. Imagecon[k*20+j].x=i; 
  212. j++;
  213.      }
  214. }
  215. }
  216.         if(min.x==0)     min.x=xImagecon[k*500+i];
  217. if(!minfind || begin)
  218. {
  219.      if(min.x>=xImagecon[k*500+i])  
  220.      {
  221.      min.x=xImagecon[k*500+i];
  222.      min.y=i;
  223.  minx=0;
  224.  }
  225.             else
  226.             {
  227.             minx++; 
  228.            if((minx>=2) && (min.x<=xImagecon[k*500+i]-2) && (min.x<=max.x+2))
  229.            {
  230.            minfind=TRUE;
  231.            begin=FALSE;
  232.            }
  233.             }
  234.             }
  235.     if(!maxfind || begin)
  236. {
  237.      if(max.x<=xImagecon[k*500+i])
  238.      {
  239.      max.x=xImagecon[k*500+i];
  240.      max.y=i; 
  241.          maxx=0;
  242.   }
  243.   else  
  244.   {
  245.      maxx++;
  246. if((maxx>=2) && (max.x>=xImagecon[k*500+i]+2) && (max.x>=min.x+2))
  247. {
  248. maxfind=TRUE;
  249. begin=FALSE;
  250. minfind=FALSE;
  251. }
  252.    }
  253.         last.x=xImagecon[k*500+i];
  254.     last.y=i;
  255.   if((maxfind && (maxx>=2)) || (minfind && (minx>=2)))
  256.   {
  257.   if(minfind)
  258. {
  259.      if(k==0)
  260.      {
  261.      Imagecon[k*20+j].x=min.x;
  262.      Imagecon[k*20+j].y=min.y; 
  263.      j++;
  264.      }
  265.       if(k==2)
  266.      {
  267.      Imagecon[k*20+j].y=min.x;
  268.      Imagecon[k*20+j].x=min.y; 
  269.                      j++;
  270.  }
  271.      max.x=min.x;
  272.      max.y=min.y;
  273.                  maxfind=FALSE;     
  274.                }
  275.    if(maxfind)
  276.    {
  277.      if(k==1)
  278.      {
  279.      Imagecon[k*20+j].x=max.x;
  280.      Imagecon[k*20+j].y=max.y; 
  281.      j++;
  282.      }
  283.    if(k==3)
  284.  {
  285.      Imagecon[k*20+j].y=max.x;
  286.      Imagecon[k*20+j].x=max.y; 
  287.      j++;
  288.  }
  289.  min.x=max.x;
  290.  min.y=max.y;
  291.      }
  292.      *(lp+Imagecon[k*20+j-1].x/8+Imagecon[k*20+j-1].y * BPL/4) ^ 255;
  293.      *(lp+Imagecon[k*20+j-1].x/8+Imagecon[k*20+j-1].y * BPL/4) ^ 255;
  294.      minx=0;     
  295.      maxx=0;
  296.      }
  297.     } 
  298.   }
  299.   Imagecon[k*20].x=j;
  300.   if(k<2)
  301.   {
  302.   Imagecon[k*20+j].x=last.x;
  303.   Imagecon[k*20+j].y=last.y;
  304.   }
  305.   else
  306.   {
  307.   Imagecon[k*20+j].x=last.y;
  308.   Imagecon[k*20+j].y=last.x;
  309.   }
  310. }  
  311. //去掉相同点
  312. for(i=0;i<4;i++)
  313. {
  314.     k=Imagecon[20*i].x;
  315. Imagecon[20*i].x=0;
  316. pav_cent->x =Imagecon[20*i+1].x;
  317. pav_cent->y =Imagecon[20*i+1].y;
  318. last.x=Imagecon[20*i+k].x;
  319. last.y=Imagecon[20*i+k].y;
  320. for(j=0;j<40;j++)
  321. {
  322. if((i==0) && (Imagecon[40+20*(int)(j/20)+2].x<=pav_cent->x) && (Imagecon[40+j].y==pav_cent->y) )
  323. equal1=TRUE;
  324. else
  325.           equal1=FALSE;
  326.         if((i==2) && (Imagecon[20*(int)(j/20)+2].y<=pav_cent->y) && (Imagecon[j].x==pav_cent->x) )           
  327. equal2=TRUE;
  328. else
  329.           equal2=FALSE;
  330.         tempx=40*(1-(int)(i/2))+j;
  331.     if((Imagecon[tempx].x==pav_cent->x) && (Imagecon[tempx].y==pav_cent->y))
  332.  equal3=TRUE;
  333. else
  334.    equal3=FALSE;
  335.     if(equal3 || equal1|| equal2)
  336. {                              
  337.  Imagecon[20*i+1].x=0;
  338.  Imagecon[20*i+1].y=0;
  339. }
  340.       if  ((i==0) && (Imagecon[40+20*(int)(j/20)+2].x<=last.x) && 
  341.    (Imagecon[40+j].y==last.y))
  342. equal1=TRUE;
  343. else
  344.            equal1=FALSE;
  345. if((i==2) &&(Imagecon[20*(int)(j/20)+2].y<=last.y) && (Imagecon[j].x==last.x))
  346.  equal2=TRUE;
  347. else 
  348.  equal2=FALSE;
  349.   tempx=40*(1-i/2)+j;
  350. if((Imagecon[tempx].x==last.x) && (Imagecon[tempx].y==last.y))  
  351.    equal3=TRUE;
  352. else
  353.  equal3=FALSE;
  354. if(equal3 || equal1 ||  equal2) 
  355. {
  356.  Imagecon[20*i+k].x=0;
  357.  Imagecon[20*i+k].y=0;
  358.  }
  359.        }
  360.     }
  361. //caculate the GCC  
  362. for(j=0;j<20;j++)
  363. {
  364.  last.x=Imagecon[20+j].x;
  365.  last.y=Imagecon[20+j].y;
  366.  Imagecon[20+j].x=Imagecon[60+j].x;
  367.  Imagecon[20+j].y=Imagecon[60+j].y;
  368.  Imagecon[60+j].x=last.x;
  369.  Imagecon[60+j].y=last.y;
  370. }                                          
  371. l=0.;
  372.     midx=0;
  373.     midy=0;
  374.     max.x=0;
  375.     max.y=0;
  376. for(i=0;i<80;i++)
  377. {
  378. if(Imagecon[i].x !=0)
  379. {
  380. min.x=Imagecon[i].x;
  381. min.y=Imagecon[i].y; 
  382. if(max.x==0)
  383. {
  384. //max store the initional value
  385. max.x=min.x;
  386. max.y=min.y;
  387. }
  388. j=i+1;
  389. while((Imagecon[j].x==0) && (j<80))
  390. j++;
  391. if((j>40) && (i<40))
  392. {
  393. // pav_cent store the end of the y direction maxmun value
  394. pav_cent->x=min.x;
  395. pav_cent->y=min.y;
  396. min.x=max.x;
  397. min.y=max.y; 
  398. }           
  399. last.x=Imagecon[j].x;
  400. last.y=Imagecon[j].y;
  401. if(j==80) 
  402. {
  403.   last.x=pav_cent->x;
  404.   last.y=pav_cent->y;
  405. }
  406. dis=sqrt((double)(min.x-last.x)*(min.x -last.x)+
  407. (double)(min.y-last.y)*(min.y-last.y));
  408. midx =(double)(min.x+last.x)/2 *dis +midx;
  409. midy =(double)(min.y+last.y)/2 *dis +midy;
  410. l+=dis;
  411. i=j-1;
  412. }
  413. }
  414.     midx=midx/l;
  415.     midy=midy/l;
  416.     gcc->x=(int)midx;
  417.     gcc->y=(int)midy;         
  418.     l=0;
  419. for(i=0;i<80;i++)
  420. {
  421. if(Imagecon[i].x !=0)
  422. {
  423. dis=(Imagecon[i].x-midx)*(Imagecon[i].x-midx)+(Imagecon[i].y-midy)*(Imagecon[i].y-midy);
  424. dis=sqrt(dis);
  425. l=max(dis,l);
  426.         }
  427. }
  428.     *n=l;
  429. return TRUE;
  430. }                          
  431. /***************************************************************************
  432. *  pAnew_mom:the query bitmap's moments                          *
  433. *  n:the size of the bitmap                                       *
  434. *  protate :the rotated angle           
  435. * the moment name of the calculation below is the same as the maths define *
  436. ***************************************************************************/
  437. extern BOOL  Contour(CBmpTestDoc* pDoc,double *pAnew_mon,BOOL bmoment,double n,double *protate)
  438. {
  439. //1:xnear 2:xfarer 3:ynear 4:yfarer
  440. BYTE *lp=pDoc->m_Dib.m_Buffer;
  441.    char Outtext[300]="",ext1[15]="mom.txt",filename1[30];
  442.     int  i,k,tempx,black,white,BPL,Height,Width;
  443.     unsigned int a=1,d,j;
  444.     DWORD  x=0,y=0,centx=0,centy=0,counts=0;//counts represents the conunt of the contour
  445.     //cent represent the center_mass while av_cent represent the average center
  446.     DISTANCE   xdis[50];
  447.     PDISTANCE     pdis; 
  448.     //let x repreterative the near  and y represertive the far 
  449. bool maxfind=false,minfind=false,begin=true;
  450. double  l,mid,d_centx,d_centy,A1,A2,A3,A4,A5,A6,A7,N,coefient,
  451.       u02,u20,u03,u30,u11,u21,u12,a1,a2,a3,a4,a5,a6,a7,
  452. m01,m02,m03,m20,m30,m11,m21,m12;
  453. FILE *ffp;
  454. Height=(int) pDoc->m_Dib.Height;
  455. Width=(int) pDoc->m_Dib.Width;
  456.     BPL=(int) pDoc->m_Dib.Bpl;
  457. pdis=xdis; 
  458.     N=n;
  459.     for(i=0;i<50;i++)
  460.     (pdis+i)->number=0;    
  461.     u02=0;u03=0;u20=0;
  462. //求直方图
  463.     for(k=0;k<(Height);k++)
  464.     {
  465.     for(i=0;i<=Width/8;i++)
  466.     {  
  467.        a=255;
  468.    if(((int)*(lp+i+k*BPL) & a) ==0)
  469.    continue; 
  470.            if((i+1)*8<Width)
  471.          d=8;
  472.    else
  473.       d=(unsigned)(Width-i*8);
  474.    a=128;
  475.    if(d!=0)
  476.    {
  477.       for(j=0;j<d;j++)
  478.   {
  479. //if the bit is equal to 0 it is background
  480.      if(((int)*(lp+i+k*BPL) & a) ==0)
  481.  {   
  482.  y++;
  483.        a=a>>1;
  484.  }
  485.      else
  486.  {  
  487.  x++;
  488.                     a=a>>1;
  489.             centx=(WORD)i*8+j+centx;
  490.     centy=(WORD)k+centy;
  491.  }
  492.       }
  493.     }    
  494.     }
  495.     }                     
  496. //图的面积=x+y
  497.     black=y;
  498.     white=x; 
  499. //求重心
  500.     d_centx=((double)centx/x);
  501. d_centy=((double) centy/x);
  502. //归一化系数    
  503.     coefient=(double)x*x;  
  504.     A7=sqrt((double)x);
  505. //A7=sqrt(a1); 
  506.     mid=coefient*A7;
  507.     u11=0;u02=0;u03=0;u20=0;u30=0;u12=0;u21=0; 
  508.     m11=0;m01=0;m02=0;m03=0;m20=0;m30=0;m12=0;m21=0;
  509. A1=0.;A2=0.;A3=0.;A4=0.;A5=0.;A6=0.;A7=0.;
  510.     for(k=0;k<Height;k++)
  511.     {
  512.     for(i=0;i<=(int)Width/8;i++)
  513.     {  
  514.        a=255;
  515.    if((((int)*(lp+i+k*BPL)) & a)==0)
  516.    continue; 
  517.         if((i+1)*8<Width)
  518.        d=8;
  519.    else
  520.       d=(unsigned)(Width-i*8);
  521.    a=128;
  522.    if(d!=0)
  523.    {
  524.      for(j=0;j<d;j++)
  525.      {
  526. //if the bit is equal to 0 it is background
  527.      if((((int)*(lp+i+k*BPL)) & a) ==0)
  528.        a=a>>1;
  529.      else
  530.      { 
  531. a=a>>1;           
  532. tempx=i*8+j;
  533. a1=((double)k-d_centy)*((double)k-d_centy);
  534. u02+=a1;
  535. a2=a1*(k- d_centy);
  536. u03+=a2;
  537. a3=(tempx- d_centx)*(tempx-d_centx);
  538. u20+=a3;
  539. u30+=a3*(tempx- d_centx); 
  540. a4=(tempx-d_centx)*(k-d_centy);
  541. u11+=a4;
  542. a5=a4*(tempx-d_centx);
  543. u21+=a5;
  544. a6=a4*(k-d_centy);
  545. u12+=a6;  
  546. }
  547. }
  548. }    
  549. }   
  550. //to calculate the scale transform    
  551. a3=u02/coefient;
  552. A1=A1+a3;
  553. u02=0.; 
  554. a3=u20/coefient;
  555. A2=A2+a3;
  556. u20=0.;
  557. a3=u11/coefient;
  558. A3=a3+A3;
  559. u11=0.;
  560. a3=u03/mid;
  561. A4=A4+a3;
  562. u03=0.;
  563. a3=u30/mid;
  564. A5=A5+a3;
  565. u30=0.;
  566. a3=u21/mid;
  567. A6=A6+a3;
  568. u21=0.;
  569. a3=u12/mid;
  570. A7=A7+a3;
  571. u12=0.;
  572. }                     
  573.     u02=A1;
  574.     u20=A2;
  575.     u11=A3;
  576.     u03=A4;
  577.     u30=A5;
  578.     u21=A6;
  579.     u12=A7;   
  580.   
  581.   
  582.  //rotated invariant moment 
  583.     a1=u02+u20; 
  584.     a2=(u20-u02)*(u20-u02)+u11*u11*4;
  585.     a3=(u30- u12*3)*(u30-u12*3)+(u21*3-u03)*(u21*3-u03);
  586.     a4=(u30+u12)*(u30+u12)+(u03+u21)*(u03+u21);
  587.     a5=(u30-u12*3)*(u30+u12)*((u30+u12)*(u30+u12)-(u21+u03)*(u21+u03)*3)
  588.      +(u21*3-u03)*(u21+u03)*((u30+u12)*(u30+u12)*3-(u21+u03)*(u21+u03));
  589.     a6=(u20-u02)*((u30+u12)*(u30+u12)-(u21+u03)*(u21+u03))
  590.      +u11*(u30+u12)*(u21+u03)*4;
  591.       
  592.     a7=(u21*3-u03)*(u30+u12)*((u30+u12)*(u30+u12)-(u21+u03)*(u21+u03)*3)
  593.      -(u30-u12*3)*(u21+u03)*((u30+u12)*(u30+u12)*3 -(u21+u03)*(u21+u03));
  594. //calculate the rotate angle 
  595.     u11=2*u11; 
  596.     u12=u20-u02;
  597. l=atan2( u11, u12 );
  598. *protate=l/2;
  599. *pAnew_mon=(double)n;                                                  
  600. //to store the moment 
  601. A1=a1;
  602. *(++pAnew_mon)=A1;
  603. A2=a2;       
  604. *(++pAnew_mon)=A2;
  605. A3=a3; 
  606. *(++pAnew_mon)=A3;
  607. A4=a4;           
  608. *(++pAnew_mon)=A4;
  609. A5=a5;
  610. *(++pAnew_mon)=A5;
  611. A6=a6;           
  612. *(++pAnew_mon)=A6;
  613. A7=a7;           
  614. *(++pAnew_mon)=A7;
  615.     if(bmoment)
  616.     {
  617.         wsprintf(filename1,"%s",(LPSTR)ext1); 
  618. if((ffp=fopen(filename1,"ab"))==NULL)
  619. {
  620. return false;
  621. }
  622. sprintf(Outtext,"rn %-20s%-7ld%-25le%-25le%-25le%-25le%-25le%-25le%-25le%-25le",
  623.   pDoc->m_Dib.arcFileName,white,n,A1,A2,A3,A4,A5,A6,A7);                 
  624. fprintf (ffp,"%s",Outtext);
  625.         fclose(ffp);                     
  626.      } 
  627.      return true;
  628. }                          
  629. void HorzMirror(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  630. {
  631. int x,y;
  632. int nByteWidth=nWidth*3;
  633. if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
  634. for(y=0;y<nHeight;y++)
  635. {
  636. for(x=0;x<nWidth;x++)
  637. {
  638. lpOutput[x*3+y*nByteWidth]=lpInput[(nWidth-1-x)*3+y*nByteWidth];
  639. lpOutput[x*3+1+y*nByteWidth]=lpInput[(nWidth-1-x)*3+1+y*nByteWidth];
  640. lpOutput[x*3+2+y*nByteWidth]=lpInput[(nWidth-1-x)*3+2+y*nByteWidth];
  641. }
  642. Progress(y);
  643. }
  644. }
  645. void VertMirror(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  646. {
  647. int x,y;
  648. int nByteWidth=nWidth*3;
  649. if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
  650. for(y=0;y<nHeight;y++)
  651. {
  652. for(x=0;x<nByteWidth;x++)
  653. {
  654. lpOutput[x+y*nByteWidth]=lpInput[x+(nHeight-y-1)*nByteWidth];
  655. }
  656. Progress(y);
  657. }
  658. }
  659. void CornerMirror(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  660. {
  661. int x,y;
  662. int nByteWidth=nWidth*3;
  663. if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
  664. for(y=0;y<nHeight;y++)
  665. {
  666. for(x=0;x<nWidth;x++)
  667. {
  668. lpOutput[x*3+y*nByteWidth]=lpInput[(nWidth-1-x)*3+(nHeight-y-1)*nByteWidth];
  669. lpOutput[x*3+1+y*nByteWidth]=lpInput[(nWidth-1-x)*3+1+(nHeight-y-1)*nByteWidth];
  670. lpOutput[x*3+2+y*nByteWidth]=lpInput[(nWidth-1-x)*3+2+(nHeight-y-1)*nByteWidth];
  671. }
  672. Progress(y);
  673. }
  674. }
  675. #define Point(x,y) lpPoints[(x)+(y)*nWidth]
  676. #define Point1(x,y) lpPoints1[(x)+(y)*nWidth]
  677. void GetPoints(int nWidth,int nHeight,BYTE *lpBits,BYTE *lpPoints)
  678. {
  679. int x,y,p;
  680. int nByteWidth=nWidth*3;
  681. if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
  682. for(y=0;y<nHeight;y++)
  683. {
  684. for(x=0;x<nWidth;x++)
  685. {
  686. p=x*3+y*nByteWidth;
  687. lpPoints[x+y*nWidth]=(BYTE)(0.299*(float)lpBits[p+2]+0.587*(float)lpBits[p+1]+0.114*(float)lpBits[p]+0.1);
  688. }
  689. }
  690. }
  691. void PutPoints(int nWidth,int nHeight,BYTE *lpBits,BYTE *lpPoints)
  692. {
  693. int nByteWidth=nWidth*3;
  694. if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
  695. int x,y,p,p1;
  696. for(y=0;y<nHeight;y++)
  697. {
  698. for(x=0;x<nWidth;x++)
  699. {
  700. p=x*3+y*nByteWidth;
  701. p1=x+y*nWidth;
  702. lpBits[p]=lpPoints[p1];
  703. lpBits[p+1]=lpPoints[p1];
  704. lpBits[p+2]=lpPoints[p1];
  705. }
  706. }
  707. }
  708. void HistogramEq1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput)
  709. {
  710. int x,y;
  711. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  712. GetPoints(nWidth,nHeight,lpInput,lpPoints);
  713. int r[256],s[256];
  714. ZeroMemory(r,1024);
  715. ZeroMemory(s,1024);
  716. for(y=0;y<nHeight;y++){
  717. for(x=0;x<nWidth;x++){
  718. r[Point(x,y)]++;
  719. }
  720. }
  721. s[0]=r[0];
  722. for(y=1;y<256;y++)
  723. {
  724. s[y]=s[y-1];
  725. s[y]+=r[y];
  726. }
  727. for(y=0;y<nHeight;y++){
  728. for(x=0;x<nWidth;x++){
  729. Point(x,y)=s[Point(x,y)]*255/nWidth/nHeight;
  730. }
  731. }
  732. PutPoints(nWidth,nHeight,lpOutput,lpPoints);
  733. delete lpPoints;
  734. }
  735. //3x3中值滤波
  736. void Med1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  737. {
  738. int x,y;
  739. int nByteWidth=nWidth*3;
  740. if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
  741. BYTE p[9],s;
  742. int i,j;
  743. for(y=1;y<nHeight-1;y++)
  744. {
  745. for(x=3;x<nWidth*3-3;x++)
  746. {
  747. p[0]=lpInput[x-3+(y-1)*nByteWidth];
  748. p[1]=lpInput[x+(y-1)*nByteWidth];
  749. p[2]=lpInput[x+3+(y-1)*nByteWidth];
  750. p[3]=lpInput[x-3+y*nByteWidth];
  751. p[4]=lpInput[x+y*nByteWidth];
  752. p[5]=lpInput[x+3+y*nByteWidth];
  753. p[6]=lpInput[x-3+(y+1)*nByteWidth];
  754. p[7]=lpInput[x+(y+1)*nByteWidth];
  755. p[8]=lpInput[x+3+(y+1)*nByteWidth];
  756. for(j=0;j<5;j++)
  757. {
  758. for(i=j+1;i<9;i++)
  759. {
  760. if (p[j]>p[i])
  761. {
  762. s=p[j];
  763. p[j]=p[i];
  764. p[i]=s;
  765. }
  766. }
  767. }
  768. lpOutput[x+y*nByteWidth]=p[4];
  769. }
  770. Progress(y);
  771. }
  772. }
  773. void Mean1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  774. {
  775. int x,y,x1,y1,p;
  776. // BYTE *lpPoints=new BYTE[nWidth*nHeight];
  777. // GetPoints(nWidth,nHeight,lpInput,lpPoints);
  778. int sr,sg,sb;
  779. int nByteWidth=nWidth*3;
  780. if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
  781. for(y=1;y<nHeight-1;y++)
  782. {
  783. for(x=1;x<nWidth-1;x++)
  784. {
  785. p=x*3+y*nByteWidth;
  786. sb=0;
  787. sg=0;
  788. sr=0;
  789. for(y1=-1;y1<=1;y1++)
  790. for(x1=-1;x1<=1;x1++)
  791. {
  792. sb+=lpInput[(y+y1)*nByteWidth+(x+x1)*3];
  793. sg+=lpInput[(y+y1)*nByteWidth+(x+x1)*3+1];
  794. sr+=lpInput[(y+y1)*nByteWidth+(x+x1)*3+2];
  795. }
  796. lpOutput[p+2]=sr/9;
  797. lpOutput[p+1]=sg/9;
  798. lpOutput[p]=sb/9;
  799. }
  800. Progress(y);
  801. }
  802. // PutPoints(nWidth,nHeight,lpOutput,lpPoints);
  803. // delete lpPoints;
  804. }
  805. #define pi (double)3.14159265359
  806. /*复数定义*/
  807. typedef struct
  808. {
  809. double re;
  810. double im;
  811. }COMPLEX;
  812. /*复数加运算*/
  813. COMPLEX Add(COMPLEX c1, COMPLEX c2)
  814. {
  815. COMPLEX c;
  816. c.re=c1.re+c2.re;
  817. c.im=c1.im+c2.im;
  818. return c;
  819. }
  820. /*复数减运算*/
  821. COMPLEX Sub(COMPLEX c1, COMPLEX c2)
  822. {
  823. COMPLEX c;
  824. c.re=c1.re-c2.re;
  825. c.im=c1.im-c2.im;
  826. return c;
  827. }
  828. /*复数乘运算*/
  829. COMPLEX Mul(COMPLEX c1, COMPLEX c2)
  830. {
  831. COMPLEX c;
  832. c.re=c1.re*c2.re-c1.im*c2.im;
  833. c.im=c1.re*c2.im+c2.re*c1.im;
  834. return c;
  835. }
  836. /*快速付里哀变换
  837. TD为时域值,FD为频域值,power为2的幂数*/
  838. void FFT(COMPLEX * TD, COMPLEX * FD, int power)
  839. {
  840. int count;
  841. int i,j,k,bfsize,p;
  842. double angle;
  843. COMPLEX *W,*X1,*X2,*X;
  844. /*计算付里哀变换点数*/
  845. count=1<<power;
  846. /*分配运算所需存储器*/
  847. W=(COMPLEX *)malloc(sizeof(COMPLEX)*count/2);
  848. X1=(COMPLEX *)malloc(sizeof(COMPLEX)*count);
  849. X2=(COMPLEX *)malloc(sizeof(COMPLEX)*count);
  850. /*计算加权系数*/
  851. for(i=0;i<count/2;i++)
  852. {
  853. angle=-i*pi*2/count;
  854. W[i].re=cos(angle);
  855. W[i].im=sin(angle);
  856. }
  857. /*将时域点写入存储器*/
  858. memcpy(X1,TD,sizeof(COMPLEX)*count);
  859. /*蝶形运算*/
  860. for(k=0;k<power;k++)
  861. {
  862. for(j=0;j<1<<k;j++)
  863. {
  864. bfsize=1<<(power-k);
  865. for(i=0;i<bfsize/2;i++)
  866. {
  867. p=j*bfsize;
  868. X2[i+p]=Add(X1[i+p],X1[i+p+bfsize/2]);
  869. X2[i+p+bfsize/2]=Mul(Sub(X1[i+p],X1[i+p+bfsize/2]),W[i*(1<<k)]);
  870. }
  871. }
  872. X=X1;
  873. X1=X2;
  874. X2=X;
  875. }
  876. /*重新排序*/
  877. for(j=0;j<count;j++)
  878. {
  879. p=0;
  880. for(i=0;i<power;i++)
  881. {
  882. if (j&(1<<i)) p+=1<<(power-i-1);
  883. }
  884. FD[j]=X1[p];
  885. }
  886. /*释放存储器*/
  887. free(W);
  888. free(X1);
  889. free(X2);
  890. }
  891. extern void str(int quotient,char addr[15])
  892. {
  893. int remainder,i,j,k;
  894. char  s1[15];
  895. i=0;
  896. do 
  897. {
  898. remainder=quotient%10;
  899. quotient=quotient/10;
  900. remainder=remainder+48;
  901.         s1[i]=(char) remainder;
  902. i++;
  903. } while(quotient!=0);
  904.     j=0;
  905. for(k=i-1;k>=0;k--)
  906. {
  907. addr[j]=s1[k];
  908. j++;
  909. }
  910. addr[j]=(char) '';
  911.     return;
  912. }
  913. /*快速离散余弦变换,利用快速付里哀变换
  914. f为时域值,F为变换域值,power为2的幂数*/
  915. void DCT(double *f, double *F, int power)
  916. {
  917. int i,count;
  918. COMPLEX *X;
  919. double s;
  920. /*计算离散余弦变换点数*/
  921. count=1<<power;
  922. /*分配运算所需存储器*/
  923. X=(COMPLEX *)malloc(sizeof(COMPLEX)*count*2);
  924. /*延拓*/
  925. memset(X,0,sizeof(COMPLEX)*count*2);
  926. /*将时域点写入存储器*/
  927. for(i=0;i<count;i++)
  928. {
  929. X[i].re=f[i];
  930. }
  931. /*调用快速付里哀变换*/
  932. FFT(X,X,power+1);
  933. /*调整系数*/
  934. s=1/sqrt(count);
  935. F[0]=X[0].re*s;
  936. s*=sqrt(2);
  937. for(i=1;i<count;i++)
  938. {
  939. F[i]=(X[i].re*cos(i*pi/(count*2))+X[i].im*sin(i*pi/(count*2)))*s;
  940. }
  941. /*释放存储器*/
  942. free(X);
  943. }
  944. /*快速沃尔什-哈达玛变换
  945. f为时域值,F为变换域值,power为2的幂数*/
  946. void WALh(double *f, double *W, int power)
  947. {
  948. int count;
  949. int i,j,k,bfsize,p;
  950. double *X1,*X2,*X;
  951. /*计算快速沃尔什变换点数*/
  952. count=1<<power;
  953. /*分配运算所需存储器*/
  954. X1=(double *)malloc(sizeof(double)*count);
  955. X2=(double *)malloc(sizeof(double)*count);
  956. /*将时域点写入存储器*/
  957. memcpy(X1,f,sizeof(double)*count);
  958. /*蝶形运算*/
  959. for(k=0;k<power;k++)
  960. {
  961. for(j=0;j<1<<k;j++)
  962. {
  963. bfsize=1<<(power-k);
  964. for(i=0;i<bfsize/2;i++)
  965. {
  966. p=j*bfsize;
  967. X2[i+p]=X1[i+p]+X1[i+p+bfsize/2];
  968. X2[i+p+bfsize/2]=X1[i+p]-X1[i+p+bfsize/2];
  969. }
  970. }
  971. X=X1;
  972. X1=X2;
  973. X2=X;
  974. }
  975. /*调整系数*/
  976. // for(i=0;i<count;i++)
  977. // {
  978. // W[i]=X1[i]/count;
  979. // }
  980. for(j=0;j<count;j++)
  981. {
  982. p=0;
  983. for(i=0;i<power;i++)
  984. {
  985. if (j&(1<<i)) p+=1<<(power-i-1);
  986. }
  987. W[j]=X1[p]/count;
  988. }
  989. /*释放存储器*/
  990. free(X1);
  991. free(X2);
  992. }
  993. void Fourier1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  994. {
  995. int w=1,h=1,wp=0,hp=0;
  996. while(w*2<=nWidth)
  997. {
  998. w*=2;
  999. wp++;
  1000. }
  1001. while(h*2<=nHeight)
  1002. {
  1003. h*=2;
  1004. hp++;
  1005. }
  1006. int x,y;
  1007. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1008. GetPoints(nWidth,nHeight,lpInput,lpPoints);
  1009. COMPLEX *TD=new COMPLEX[w*h];
  1010. COMPLEX *FD=new COMPLEX[w*h];
  1011. for(y=0;y<h;y++)
  1012. {
  1013. for(x=0;x<w;x++)
  1014. {
  1015. TD[x+w*y].re=Point(x,y);
  1016. TD[x+w*y].im=0;
  1017. }
  1018. }
  1019. for(y=0;y<h;y++)
  1020. {
  1021. FFT(&TD[w*y],&FD[w*y],wp);
  1022. // Progress(y*nHeight/2/h);
  1023. }
  1024. for(y=0;y<h;y++)
  1025. {
  1026. for(x=0;x<w;x++)
  1027. {
  1028. TD[y+h*x]=FD[x+w*y];
  1029. // TD[x+w*y]=FD[x*h+y];
  1030. }
  1031. }
  1032. for(x=0;x<w;x++)
  1033. {
  1034. FFT(&TD[x*h],&FD[x*h],hp);
  1035. Progress(x*nHeight/2/w+nHeight/2);
  1036. }
  1037. memset(lpPoints,0,nWidth*nHeight);
  1038. double m;
  1039. for(y=0;y<h;y++)
  1040. {
  1041. for(x=0;x<w;x++)
  1042. {
  1043. m=sqrt(FD[x*h+y].re*FD[x*h+y].re+FD[x*h+y].im*FD[x*h+y].im)/100;
  1044. if (m>255) m=255;
  1045. Point((x<w/2?x+w/2:x-w/2),nHeight-1-(y<h/2?y+h/2:y-h/2))=(BYTE)(m);
  1046. }
  1047. }
  1048. delete TD;
  1049. delete FD;
  1050. PutPoints(nWidth,nHeight,lpOutput,lpPoints);
  1051. delete lpPoints;
  1052. }
  1053. void Walsh1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  1054. {
  1055. int w=1,h=1,wp=0,hp=0;
  1056. while(w*2<=nWidth)
  1057. {
  1058. w*=2;
  1059. wp++;
  1060. }
  1061. while(h*2<=nHeight)
  1062. {
  1063. h*=2;
  1064. hp++;
  1065. }
  1066. int x,y;
  1067. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1068. GetPoints(nWidth,nHeight,lpInput,lpPoints);
  1069. double *f=new double[w*h];
  1070. double *W=new double[w*h];
  1071. for(y=0;y<h;y++)
  1072. {
  1073. for(x=0;x<w;x++)
  1074. {
  1075. f[x+y*w]=Point(x,y);
  1076. }
  1077. }
  1078. for(y=0;y<h;y++)
  1079. {
  1080. WALh(f+w*y,W+w*y,wp);
  1081. Progress(y*nHeight/2/h);
  1082. }
  1083. for(y=0;y<h;y++)
  1084. {
  1085. for(x=0;x<w;x++)
  1086. {
  1087. f[x*h+y]=W[x+w*y];
  1088. }
  1089. }
  1090. for(x=0;x<w;x++)
  1091. {
  1092. WALh(f+x*h,W+x*h,hp);
  1093. // Progress(x*nHeight/2/w+nHeight/2);
  1094. }
  1095. double a;
  1096. memset(lpPoints,0,nWidth*nHeight);
  1097. for(y=0;y<h;y++)
  1098. {
  1099. for(x=0;x<w;x++)
  1100. {
  1101. a=fabs(W[x*h+y]*1000);
  1102. if (a>255) a=255;
  1103. Point(x,nHeight-y-1)=(BYTE)a;
  1104. }
  1105. }
  1106. delete f;
  1107. delete W;
  1108. PutPoints(nWidth,nHeight,lpOutput,lpPoints);
  1109. delete lpPoints;
  1110. }
  1111. void Dct1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  1112. {
  1113. int w=1,h=1,wp=0,hp=0;
  1114. while(w*2<=nWidth)
  1115. {
  1116. w*=2;
  1117. wp++;
  1118. }
  1119. while(h*2<=nHeight)
  1120. {
  1121. h*=2;
  1122. hp++;
  1123. }
  1124. int x,y;
  1125. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1126. GetPoints(nWidth,nHeight,lpInput,lpPoints);
  1127. double *f=new double[w*h];
  1128. double *W=new double[w*h];
  1129. for(y=0;y<h;y++)
  1130. {
  1131. for(x=0;x<w;x++)
  1132. {
  1133. f[x+y*w]=Point(x,y);
  1134. }
  1135. }
  1136. for(y=0;y<h;y++)
  1137. {
  1138. DCT(&f[w*y],&W[w*y],wp);
  1139. // Progress(y*nHeight/2/h);
  1140. }
  1141. for(y=0;y<h;y++)
  1142. {
  1143. for(x=0;x<w;x++)
  1144. {
  1145. f[x*h+y]=W[x+w*y];
  1146. }
  1147. }
  1148. for(x=0;x<w;x++)
  1149. {
  1150. DCT(&f[x*h],&W[x*h],hp);
  1151. Progress(x*nHeight/2/w+nHeight/2);
  1152. }
  1153. double a;
  1154. memset(lpPoints,0,nWidth*nHeight);
  1155. for(y=0;y<h;y++)
  1156. {
  1157. for(x=0;x<w;x++)
  1158. {
  1159. a=fabs(W[x*h+y]);
  1160. if (a>255) a=255;
  1161. Point(x,nHeight-y-1)=(BYTE)(a);
  1162. }
  1163. }
  1164. delete f;
  1165. delete W;
  1166. PutPoints(nWidth,nHeight,lpOutput,lpPoints);
  1167. delete lpPoints;
  1168. }
  1169. int Conv2(int nWidth,int nHeight,BYTE *lpOutput,BYTE *lpInput,double mask[],int windowX,int windowY);
  1170. int Laplacian(int nWidth,int nHeight,BYTE *lpOutput,double *lpInput);
  1171. int Zerocross(int nWidth,int nHeight,BYTE *lpOutput,double *lpInput,double thresh);
  1172. int LoG(int nWidth,int nHeight,BYTE *lpOutput,BYTE *lpInput,double thresh,double sigma);
  1173. #define In(x,y) lpInput[(x)+(y)*nWidth]
  1174. #define Out(x,y) lpOutput[(x)+(y)*nWidth]
  1175. #define Mediate(x,y) lpMediate[(x)+(y)*nWidth]
  1176. #include "NumberDlg.h"
  1177. double GetNumber(const char *prompt,double number,double max)
  1178. {
  1179. CNumberDlg dlg;
  1180. dlg.m_Prompt=prompt;
  1181. dlg.m_Number=number;
  1182. dlg.DoModal();
  1183. if (dlg.m_Number>max) dlg.m_Number=max;
  1184. return dlg.m_Number;
  1185. }  
  1186. void Gauss1(int nWidth,int nHeight,BYTE *lpIn,BYTE *lpOut,void (* Progress)(int Pos))
  1187. {
  1188. double sigma=GetNumber("输入高斯模糊半径:",1,10);
  1189. int x,y,xx,xk,yk;
  1190. BYTE *lpInput=new BYTE[nWidth*nHeight];
  1191. BYTE *lpOutput=new BYTE[nWidth*nHeight];
  1192. GetPoints(nWidth,nHeight,lpIn,lpInput);
  1193. int radius,window; //window of the converlutin kernel(window=2*radius+1)
  1194. double dev_inv=0.5/(sigma*sigma);  //1/(2*sigma^2)
  1195. radius = (int)ceil(3*sigma);
  1196. window = radius*2+1;
  1197. //fast algorithm
  1198. memcpy(lpOutput,lpInput,nWidth*nHeight);
  1199. double* lpMediate=new double[nWidth*nHeight];
  1200. double* mask=new double[window];
  1201. double sum=0;
  1202. double temp;
  1203. double weight;//sum of weight of mask at edge of the image
  1204. //generate mask
  1205. for(x=0;x<radius;x++)
  1206. {
  1207. xx=(x-radius)*(x-radius);
  1208. mask[x]=exp(-xx*dev_inv);
  1209. mask[window-1-x]=mask[x];
  1210. sum+=2*mask[x];
  1211. }
  1212. mask[radius]=1;
  1213. sum+=1;
  1214. for(x=0;x<window;x++)
  1215. {
  1216. mask[x]/=sum;
  1217. }
  1218. //row process
  1219. for(y=0;y<nHeight;y++)
  1220. {
  1221. for(x=radius;x<nWidth-radius;x++)
  1222. {
  1223. temp=0;
  1224. for(xk=-radius;xk<radius+1;xk++)
  1225. temp+=In(x+xk,y)*mask[xk+radius];
  1226. Mediate(x,y)=temp;
  1227. }
  1228. for(x=0;x<radius;x++)
  1229. {
  1230. temp=0;
  1231. weight=0;
  1232. for(xk=-x;xk<radius+1;xk++)
  1233. {
  1234. temp+=In(x+xk,y)*mask[xk+radius];
  1235. weight+=mask[xk+radius];
  1236. }
  1237. Mediate(x,y)=temp/weight;
  1238. }
  1239. for(x=nWidth-radius;x<nWidth;x++)
  1240. {
  1241. temp=0;
  1242. weight=0;
  1243. for(xk=-radius;xk<nWidth-x;xk++)
  1244. {
  1245. temp+=In(x+xk,y)*mask[xk+radius];
  1246. weight+=mask[xk+radius];
  1247. }
  1248. Mediate(x,y)=temp/weight;
  1249. }
  1250. Progress(y/2);
  1251. }
  1252. //column process
  1253. double* Column = new double[nHeight];
  1254. for(x=0;x<nWidth;x++)
  1255. {
  1256. for(y=radius;y<nHeight-radius;y++)
  1257. {
  1258. temp=0;
  1259. for(yk=-radius;yk<radius+1;yk++)
  1260. temp+=Mediate(x,y+yk)*mask[yk+radius];
  1261. Column[y]=temp;
  1262. }
  1263. for(y=0;y<radius;y++)
  1264. {
  1265. temp=0;
  1266. weight=0;
  1267. for(yk=-y;yk<radius+1;yk++)
  1268. {
  1269. temp+=Mediate(x,y+yk)*mask[yk+radius];
  1270. weight+=mask[yk+radius];
  1271. }
  1272. Column[y]=temp/weight;
  1273. }
  1274.         for(y=nHeight-radius;y<nHeight;y++)
  1275. {
  1276. temp=0;
  1277. weight=0;
  1278. for(yk=-radius;yk<nHeight-y;yk++)
  1279. {
  1280. temp+=Mediate(x,y+yk)*mask[yk+radius];
  1281. weight+=mask[yk+radius];
  1282. }
  1283. Column[y]=temp/weight;
  1284. }
  1285. for(y=0;y<nHeight;y++)
  1286. {
  1287. Out(x,y)=(int)Column[y];
  1288. }
  1289. Progress(nHeight/2+x*nHeight/2/nWidth);
  1290. }
  1291. delete []Column;
  1292. delete []mask;
  1293. //    Laplacian(nWidth,nHeight,lpOutput,lpMediate);
  1294. delete []lpMediate;
  1295. //general method(hide)
  1296. PutPoints(nWidth,nHeight,lpOut,lpOutput);
  1297. delete lpInput;
  1298. delete lpOutput;
  1299. }
  1300. int Conv2(int nWidth,int nHeight,double *lpOutput,BYTE *lpInput,double mask[],int windowX,int windowY)
  1301. {
  1302. int x,y,xk,yk;
  1303. int radiusX=windowX/2;
  1304. int radiusY=windowY/2;
  1305. double temp;
  1306.     for(y=radiusY;y<nHeight-radiusY;y++)
  1307. {
  1308. for(x=radiusX;x<nWidth-radiusX;x++)
  1309. {
  1310. temp=0;
  1311. for(xk=-radiusX;xk<radiusX+1;xk++)
  1312. for(yk=-radiusY;yk<radiusY+1;yk++)
  1313. temp+=In(x+xk,y+yk)*mask[xk+radiusX+(yk+radiusY)*windowX];
  1314. Out(x,y)=temp;
  1315. }
  1316. }    
  1317. return 0;
  1318. }
  1319. int Zerocross(int nWidth,int nHeight,BYTE *lpOutput,double *lpInput,double thresh)
  1320. {
  1321. int x,y;
  1322. //zerocross cal
  1323. for(y=1;y<nHeight-1;y++)
  1324. {
  1325. for(x=1;x<nWidth-1;x++)
  1326. {
  1327. if(In(x,y)<0 && In(x+1,y)>0 &&
  1328. fabs(In(x,y)-In(x+1,y))>thresh)
  1329. {
  1330. Out(x,y)=255;
  1331. }
  1332. else if(In(x-1,y)>0 && In(x,y)<0 &&
  1333. fabs(In(x-1,y)-In(x,y))>thresh)
  1334. {
  1335. Out(x,y)=255;
  1336. }
  1337. else if(In(x,y)<0 && In(x,y+1)>0 &&
  1338. fabs(In(x,y)-In(x,y+1))>thresh)
  1339. {
  1340. Out(x,y)=255;
  1341. }
  1342. else if(In(x,y-1)>0 && In(x,y)<0 &&
  1343. fabs(In(x,y)-In(x,y-1))>thresh)
  1344. {
  1345. Out(x,y)=255;
  1346. }
  1347. /* if((In(x,y)<0 && In(x+1,y)>0)||
  1348.    (In(x,y)<0 && In(x,y+1)>0)||
  1349.    (In(x,y)>0 && In(x+1,y)<0)||
  1350.    (In(x,y)>0 && In(x,y+1)<0))
  1351. {
  1352. Out(x,y)=255;
  1353. }
  1354. */ else if(In(x,y)==0)
  1355. {
  1356. if(In(x-1,y)<0 && In(x+1,y)>0 &&
  1357.    fabs(In(x-1,y)-In(x+1,y))>2*thresh)
  1358. {
  1359. Out(x,y)=255;
  1360. }
  1361.     else if(In(x-1,y)>0 && In(x+1,y)<0 &&
  1362.     fabs(In(x-1,y)-In(x+1,y))>2*thresh)
  1363. {
  1364.     Out(x,y)=255;
  1365. }
  1366.     else if(In(x,y-1)>0 && In(x,y+1)<0 &&
  1367.      fabs(In(x,y-1)-In(x,y+1))>2*thresh)
  1368. {
  1369.     Out(x,y)=255;
  1370. }
  1371.     else if(In(x,y+1)>0 && In(x,y-1)<0 &&
  1372.     fabs(In(x,y+1)-In(x,y-1))>2*thresh)
  1373. {
  1374.     Out(x,y)=255;
  1375. }
  1376. else 
  1377. {
  1378.     Out(x,y)=0;
  1379. }
  1380. }
  1381. else 
  1382. {
  1383. Out(x,y)=0;
  1384. }
  1385. }
  1386. }
  1387. return 0;
  1388. }
  1389. void LoG(int nWidth,int nHeight,BYTE *lpIn,BYTE *lpOut,void (* Progress)(int Pos))
  1390. {
  1391. BYTE *lpInput=new BYTE[nWidth*nHeight];
  1392. BYTE *lpOutput=new BYTE[nWidth*nHeight];
  1393. GetPoints(nWidth,nHeight,lpIn,lpInput);
  1394. double thresh=0,sigma=1;
  1395.     int x,y,xx,yy;
  1396. int radius,window; //window of the converlutin kernel(window=2*radius+1)
  1397. double dev_inv=0.5/(sigma*sigma);  //1/(2*sigma^2)
  1398. radius = (int)ceil(3*sigma);
  1399. window = radius*2+1;
  1400.     //generate mask of convolution (matlab code)
  1401. //std2 = std*std;
  1402.     //h1 = exp(-(x.*x + y.*y)/(2*std2));
  1403.     
  1404. double* mask = new double [window*window];
  1405. double sum=0;
  1406. double std2=2*sigma*sigma;
  1407.     for(y=0;y<radius;y++)
  1408. {
  1409. for(x=0;x<radius;x++)
  1410. {
  1411. yy=(y-radius)*(y-radius);
  1412. xx=(x-radius)*(x-radius);
  1413. mask[x+y*window]=exp(-(xx+yy)*dev_inv);
  1414. // mask[window-1-x+y*window]=mask[x+y*window];
  1415. // mask[window-1-x+(window-1-y)*window]=mask[x+y*window];
  1416. // mask[x+(window-1-y)*window]=mask[x+y*window];
  1417. sum=sum+4*mask[x+y*window];
  1418. }
  1419. }
  1420. x=radius;
  1421. for(y=0;y<radius;y++)
  1422. {
  1423. yy=(y-radius)*(y-radius);
  1424. mask[x+y*window]=exp(-yy*dev_inv);
  1425. // mask[x+(window-1-y)*window]=mask[x+y*window];
  1426. sum=sum+2*mask[x+y*window];
  1427. }
  1428. y=radius;
  1429. for(x=0;x<radius;x++)
  1430. {
  1431. xx=(x-radius)*(x-radius);
  1432. mask[x+y*window]=exp(-xx*dev_inv);
  1433. // mask[window-1-x+y*window]=mask[x+y*window];
  1434. sum=sum+2*mask[x+y*window];
  1435. }
  1436. mask[radius+radius*window]=1;
  1437. sum=sum+mask[radius+radius*window];
  1438. //h = h1.*(x.*x + y.*y - 2*std2)/(2*pi*(std^6));
  1439. double denominator=2*3.14159265*pow(sigma,6)*sum;
  1440. sum=0;
  1441. for(x=0;x<radius;x++)
  1442. {
  1443. for(y=0;y<radius;y++)
  1444. {
  1445. yy=(y-radius)*(y-radius);
  1446. xx=(x-radius)*(x-radius);
  1447. mask[x+y*window]=mask[x+y*window]*(xx+yy-2*std2)/denominator;
  1448. // mask[window-1-x+y*window]=mask[x+y*window];
  1449. // mask[window-1-x+(window-1-y)*window]=mask[x+y*window];
  1450. // mask[x+(window-1-y)*window]=mask[x+y*window];
  1451. sum=sum+4*mask[x+y*window];
  1452. }
  1453. }
  1454. x=radius;
  1455. for(y=0;y<radius;y++)
  1456. {
  1457. yy=(y-radius)*(y-radius);
  1458. mask[x+y*window]=mask[x+y*window]*(yy-2*std2)/denominator;
  1459. // mask[x+(window-1-y)*window]=mask[x+y*window];
  1460. sum=sum+2*mask[x+y*window];
  1461. }
  1462. y=radius;
  1463. for(x=0;x<radius;x++)
  1464. {
  1465. xx=(x-radius)*(x-radius);
  1466. mask[x+y*window]=mask[x+y*window]*(xx-2*std2)/denominator;
  1467. // mask[window-1-x+y*window]=mask[x+y*window];
  1468. sum=sum+2*mask[x+y*window];
  1469. }
  1470. mask[radius+radius*window]=mask[radius+radius*window]*(-2*std2)/denominator;
  1471. sum=sum+mask[radius+radius*window];
  1472. //h = h - sum(h(:))/prod(size(h)); % make the filter sum to zero
  1473. double average=sum/(window*window);
  1474. for(x=0;x<radius;x++)
  1475. {
  1476. for(y=0;y<radius;y++)
  1477. {
  1478. mask[x+y*window]=mask[x+y*window]-average;
  1479. mask[window-1-x+y*window]=mask[x+y*window];
  1480. mask[window-1-x+(window-1-y)*window]=mask[x+y*window];
  1481. mask[x+(window-1-y)*window]=mask[x+y*window];
  1482. }
  1483. }
  1484. x=radius;
  1485. for(y=0;y<radius;y++)
  1486. {
  1487. mask[x+y*window]=mask[x+y*window]-average;
  1488. mask[x+(window-1-y)*window]=mask[x+y*window];
  1489. }
  1490. y=radius;
  1491. for(x=0;x<radius;x++)
  1492. {
  1493. mask[x+y*window]=mask[x+y*window]-average;
  1494. mask[window-1-x+y*window]=mask[x+y*window];
  1495. }
  1496. mask[radius+radius*window]=mask[radius+radius*window]-average;
  1497.     double* lpMediate = new double[nWidth*nHeight];
  1498. //2D convolution
  1499. if(Conv2(nWidth,nHeight,lpMediate,lpInput,mask,window,window))
  1500. {
  1501. TRACE("error in Conv2");
  1502. return;
  1503. };
  1504. //calcaulate the thresh for default
  1505. //  thresh = .75*mean2(abs(b(rr,cc)));
  1506. sum = 0;
  1507.     for(y=radius;y<nHeight-radius;y++)
  1508. {
  1509. for(x=radius;x<nWidth-radius;x++)
  1510. {
  1511. sum = sum + fabs(Mediate(x,y));
  1512. }
  1513. }
  1514. thresh=0.5*sum/((nWidth-2*radius)*(nHeight-2*radius));
  1515. //zerocross cal
  1516.     if(Zerocross(nWidth,nHeight,lpOutput,lpMediate,thresh))
  1517. {
  1518. TRACE("error in Zerocross");
  1519. return;
  1520. }
  1521. delete mask;
  1522. PutPoints(nWidth,nHeight,lpOut,lpOutput);
  1523. delete lpInput;
  1524. delete lpOutput;
  1525. }
  1526. void BiValue1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput)
  1527. {
  1528. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1529. GetPoints(nWidth,nHeight,lpInput,lpPoints);
  1530. double t=GetNumber("请输入阈值",128,255);
  1531. BYTE threshold=(BYTE)t;
  1532. int x,y;
  1533. for(y=0;y<nHeight;y++)
  1534. {
  1535. for(x=0;x<nWidth;x++)
  1536. {
  1537. if (Point(x,y)>threshold) Point(x,y)=255;
  1538. else Point(x,y)=0;
  1539. }
  1540. }
  1541. PutPoints(nWidth,nHeight,lpOutput,lpPoints);
  1542. delete lpPoints;
  1543. }
  1544. void Sobel(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  1545. {
  1546. int x,y,x1,y1,i;
  1547. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1548. BYTE *lpPoints1=new BYTE[nWidth*nHeight];
  1549. memset(lpPoints1,0,nWidth*nHeight);
  1550. GetPoints(nWidth,nHeight,lpInput,lpPoints);
  1551. int d,max;
  1552. static s[8][9]={
  1553. {-1,-2,-1,0,0,0,1,2,1},
  1554. {0,-1,-2,1,0,-1,2,1,0},
  1555. {1,0,-1,2,0,-2,1,0,-1},
  1556. {2,1,0,1,0,-1,0,-1,-2},
  1557. {1,2,1,0,0,0,-1,-2,-1},
  1558. {0,1,2,-1,0,1,-2,-1,0},
  1559. {-1,0,1,-2,0,2,-1,0,1},
  1560. {-2,-1,0,-1,0,1,0,1,2}
  1561. };
  1562. for(y=1;y<nHeight-1;y++)
  1563. {
  1564. for(x=1;x<nWidth-1;x++)
  1565. {
  1566. max=0;
  1567. for(i=0;i<8;i++)
  1568. {
  1569. d=0;
  1570. for(y1=0;y1<3;y1++)
  1571. for(x1=0;x1<3;x1++)
  1572. {
  1573. d+=s[i][x1+y1*3]*Point(x+x1-1,y+y1-1);
  1574. }
  1575. if (d>max) max=d;
  1576. }
  1577. if (max>255) max=255;
  1578. Point1(x,y)=(BYTE)max;
  1579. }
  1580. Progress(y);
  1581. }
  1582. PutPoints(nWidth,nHeight,lpOutput,lpPoints1);
  1583. delete lpPoints;
  1584. delete lpPoints1;
  1585. }
  1586. void Prewitte(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  1587. {
  1588. int x,y,x1,y1,i;
  1589. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1590. BYTE *lpPoints1=new BYTE[nWidth*nHeight];
  1591. memset(lpPoints1,0,nWidth*nHeight);
  1592. GetPoints(nWidth,nHeight,lpInput,lpPoints);
  1593. int d,max;
  1594. static s[8][9]={
  1595. {-1,-1,-1,0,0,0,1,1,1},
  1596. {0,-1,-1,1,0,-1,1,1,0},
  1597. {1,0,-1,1,0,-1,1,0,-1},
  1598. {1,1,0,1,0,-1,0,-1,-1},
  1599. {1,1,1,0,0,0,-1,-1,-1},
  1600. {0,1,1,-1,0,1,-1,-1,0},
  1601. {-1,0,1,-1,0,1,-1,0,1},
  1602. {-1,-1,0,-1,0,1,0,1,1}
  1603. };
  1604. for(y=1;y<nHeight-1;y++)
  1605. {
  1606. for(x=1;x<nWidth-1;x++)
  1607. {
  1608. max=0;
  1609. for(i=0;i<8;i++)
  1610. {
  1611. d=0;
  1612. for(y1=0;y1<3;y1++)
  1613. for(x1=0;x1<3;x1++)
  1614. {
  1615. d+=s[i][x1+y1*3]*Point(x+x1-1,y+y1-1);
  1616. }
  1617. if (d>max) max=d;
  1618. }
  1619. if (max>255) max=255;
  1620. Point1(x,y)=(BYTE)max;
  1621. }
  1622. Progress(y);
  1623. }
  1624. PutPoints(nWidth,nHeight,lpOutput,lpPoints1);
  1625. delete lpPoints;
  1626. delete lpPoints1;
  1627. }
  1628. void Roberts(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  1629. {
  1630. int x,y;
  1631. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1632. BYTE *lpPoints1=new BYTE[nWidth*nHeight];
  1633. memset(lpPoints1,0,nWidth*nHeight);
  1634. GetPoints(nWidth,nHeight,lpInput,lpPoints);
  1635. int d;
  1636. for(y=0;y<nHeight-1;y++)
  1637. {
  1638. for(x=0;x<nWidth-1;x++)
  1639. {
  1640. d=2*(abs(Point(x,y)-Point(x+1,y+1))+abs(Point(x+1,y)-Point(x,y+1)));
  1641. if (d>255) d=255;
  1642. Point1(x,y)=(BYTE)d;
  1643. }
  1644. Progress(y);
  1645. }
  1646. PutPoints(nWidth,nHeight,lpOutput,lpPoints1);
  1647. delete lpPoints;
  1648. delete lpPoints1;
  1649. }
  1650. void PseudoColor1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  1651. {
  1652. int x,y;
  1653. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1654. int nByteWidth=nWidth*3;
  1655. if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
  1656. GetPoints(nWidth,nHeight,lpInput,lpPoints);
  1657. BYTE b,R,G,B;
  1658. for(y=0;y<nHeight;y++)
  1659. {
  1660. for(x=0;x<nWidth;x++)
  1661. {
  1662. b=Point(x,y);
  1663. if (b<64)
  1664. {
  1665. B=255;
  1666. G=4*b;
  1667. R=0;
  1668. }
  1669. else if (b<128)
  1670. {
  1671. B=(127-b)*4;
  1672. G=255;
  1673. R=0;
  1674. }
  1675. else if (b<192)
  1676. {
  1677. B=0;
  1678. G=255;
  1679. R=(b-128)*4;
  1680. }
  1681. else
  1682. {
  1683. B=0;
  1684. G=(255-b)*4;
  1685. R=255;
  1686. }
  1687. lpOutput[x*3+nByteWidth*y]=B;
  1688. lpOutput[x*3+1+nByteWidth*y]=G;
  1689. lpOutput[x*3+2+nByteWidth*y]=R;
  1690. }
  1691. Progress(y);
  1692. }
  1693. delete lpPoints;
  1694. }
  1695. BYTE psf2(BYTE x)
  1696. {
  1697. double x1=x;
  1698. return (BYTE)((5-x1/42.5)*x1);
  1699. }
  1700. void PseudoColor2(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput,void (* Progress)(int Pos))
  1701. {
  1702. int x,y;
  1703. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1704. int nByteWidth=nWidth*3;
  1705. if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
  1706. GetPoints(nWidth,nHeight,lpInput,lpPoints);
  1707. BYTE b,R,G,B;
  1708. for(y=0;y<nHeight;y++)
  1709. {
  1710. for(x=0;x<nWidth;x++)
  1711. {
  1712. b=Point(x,y);
  1713. if (b<85)
  1714. {
  1715. B=psf2(84-b);
  1716. G=psf2(b);
  1717. R=0;
  1718. }
  1719. else if (b<170)
  1720. {
  1721. B=0;
  1722. G=psf2(169-b);
  1723. R=psf2(b-85);
  1724. }
  1725. else
  1726. {
  1727. B=psf2(b-170);
  1728. G=0;
  1729. R=psf2(255-b);
  1730. }
  1731. lpOutput[x*3+nByteWidth*y]=B;
  1732. lpOutput[x*3+1+nByteWidth*y]=G;
  1733. lpOutput[x*3+2+nByteWidth*y]=R;
  1734. }
  1735. Progress(y);
  1736. }
  1737. delete lpPoints;
  1738. }