DIB.cpp
Upload User: hongxinly
Upload Date: 2022-06-13
Package Size: 2588k
Code Size: 21k
Category:

Special Effects

Development Platform:

Visual C++

  1. // DIB.cpp
  2. #include "ShowDIB.h"
  3. #include "ShowDIBDoc.h"
  4. #include "ShowDIBView.h"
  5. #include "stdafx.h"
  6. #include "DIB.h"
  7. #include"math.h"
  8. #include"afxwin.h"
  9. #include"stdlib.h"
  10. #define PI (double)3.14159265359
  11. CDib::CDib()
  12. {
  13. // Set the Dib pointer to
  14. // NULL so we know if it's
  15. // been loaded.
  16. m_pDib = NULL;
  17. m_pWordData = NULL;
  18. }
  19. CDib::~CDib()
  20. {
  21. // If a Dib has been loaded,
  22. // delete the memory.
  23. if( m_pDib != NULL )
  24. delete [] m_pDib;
  25. if( m_pWordData != NULL )
  26. delete [] m_pWordData;
  27. }
  28. BOOL CDib::Load( const char *pszFilename )
  29. {
  30. CFile cf;
  31. int i,j;
  32. // Attempt to open the Dib file for reading.
  33. if( !cf.Open( pszFilename, CFile::modeRead ) )
  34. return( FALSE );
  35. // Get the size of the file and store
  36. // in a local variable. Subtract the
  37. // size of the BITMAPFILEHEADER structure
  38. // since we won't keep that in memory.
  39. DWORD dwDibSize;
  40. dwDibSize =
  41. cf.GetLength() - sizeof( BITMAPFILEHEADER );
  42. // Attempt to allocate the Dib memory.
  43. unsigned char *pDib;
  44. pDib = new unsigned char [dwDibSize];
  45. if( pDib == NULL )
  46. return( FALSE );
  47. BITMAPFILEHEADER BFH;
  48. // Read in the Dib header and data.
  49. try{
  50. // Did we read in the entire BITMAPFILEHEADER?
  51. if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
  52. != sizeof( BITMAPFILEHEADER ) ||
  53. // Is the type 'MB'?
  54. BFH.bfType != 'MB' ||
  55. // Did we read in the remaining data?
  56. cf.Read( pDib, dwDibSize ) != dwDibSize ){
  57. // Delete the memory if we had any
  58. // errors and return FALSE.
  59. delete [] pDib;
  60. return( FALSE );
  61. }
  62. }
  63. // If we catch an exception, delete the
  64. // exception, the temporary Dib memory,
  65. // and return FALSE.
  66. catch( CFileException *e ){
  67. e->Delete();
  68. delete [] pDib;
  69. return( FALSE );
  70. }
  71. cf.Close();
  72. // If we got to this point, the Dib has been
  73. // loaded. If a Dib was already loaded into
  74. // this class, we must now delete it.
  75. if( m_pDib != NULL )
  76. delete m_pDib;
  77. // Store the local Dib data pointer and
  78. // Dib size variables in the class member
  79. // variables.
  80. m_pDib = pDib;
  81. m_dwDibSize = dwDibSize;
  82. // Pointer our BITMAPINFOHEADER and RGBQUAD
  83. // variables to the correct place in the Dib data.
  84. m_pBIH = (BITMAPINFOHEADER *) m_pDib;
  85. m_pPalette =
  86. (RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];
  87. // Calculate the number of palette entries.
  88. m_nPaletteEntries = 1 << m_pBIH->biBitCount;
  89. if( m_pBIH->biBitCount > 8 )
  90. m_nPaletteEntries = 0;
  91. else if( m_pBIH->biClrUsed != 0 )
  92. m_nPaletteEntries = m_pBIH->biClrUsed;
  93. // Point m_pDibBits to the actual Dib bits data.
  94. m_pDibBits =
  95. &m_pDib[sizeof(BITMAPINFOHEADER)+m_nPaletteEntries*sizeof(RGBQUAD)];
  96. // If we have a valid palette, delete it.
  97. if( m_Palette.GetSafeHandle() != NULL )
  98. m_Palette.DeleteObject();
  99. // If there are palette entries, we'll need
  100. // to create a LOGPALETTE then create the
  101. // CPalette palette.
  102. if( m_nPaletteEntries != 0 ){
  103. // Allocate the LOGPALETTE structure.
  104. LOGPALETTE *pLogPal = (LOGPALETTE *) new char
  105. [sizeof(LOGPALETTE)+
  106. m_nPaletteEntries*sizeof(PALETTEENTRY)];
  107. if( pLogPal != NULL ){
  108. // Set the LOGPALETTE to version 0x300
  109. // and store the number of palette
  110. // entries.
  111. pLogPal->palVersion = 0x300;
  112. pLogPal->palNumEntries = m_nPaletteEntries;
  113. // Store the RGB values into each
  114. // PALETTEENTRY element.
  115. for( int i=0; i<m_nPaletteEntries; i++ ){
  116. pLogPal->palPalEntry[i].peRed =
  117. m_pPalette[i].rgbRed;
  118. pLogPal->palPalEntry[i].peGreen =
  119. m_pPalette[i].rgbGreen;
  120. pLogPal->palPalEntry[i].peBlue =
  121. m_pPalette[i].rgbBlue;
  122. }
  123. // Create the CPalette object and
  124. // delete the LOGPALETTE memory.
  125. m_Palette.CreatePalette( pLogPal );
  126. delete [] pLogPal;
  127. }
  128. }
  129. m_BitCount = 8;
  130. m_nWidth = m_pBIH->biWidth;
  131. m_nHeight = m_pBIH->biHeight;
  132.   m_nWidth_Step = 4*(!!(m_nWidth%4)); // if m_nWidth%4 == 0, we get 0, otherwise we get 4;
  133. m_nWidth_Step += (m_nWidth>>2)<<2;
  134. if (m_pBIH->biBitCount == 24)
  135. {
  136. MessageBox(NULL,"请自行编写转化为灰度图像的程序","说明",MB_OK);
  137. }
  138. temp =new int [m_nHeight*m_nWidth];
  139. tmp_Height = m_nHeight;
  140. tmp_Width = m_nWidth;
  141. for (i=0;i<m_nHeight;++i)
  142. {
  143. for (j=0;j<m_nWidth;++j)
  144. {
  145. temp[i*m_nWidth_Step+j] = m_pDibBits[i*m_nWidth_Step+j];
  146. }
  147. }
  148. return( TRUE );
  149. }
  150. BOOL CDib::Save( const char *pszFilename )
  151. {
  152. // If we have no data, we can't save.
  153. if( m_pDib == NULL )
  154. return( FALSE );
  155. CFile cf;
  156. // Attempt to create the file.
  157. if( !cf.Open( pszFilename,
  158. CFile::modeCreate | CFile::modeWrite ) )
  159. return( FALSE );
  160. // Write the data.
  161. try{
  162. // First, create a BITMAPFILEHEADER
  163. // with the correct data.
  164. BITMAPFILEHEADER BFH;
  165. memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
  166. BFH.bfType = 'MB';
  167. BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
  168. BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
  169. sizeof( BITMAPINFOHEADER ) +
  170. m_nPaletteEntries * sizeof( RGBQUAD );
  171. // Write the BITMAPFILEHEADER and the
  172. // Dib data.
  173. cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
  174. cf.Write( m_pDib, m_dwDibSize );
  175. }
  176. // If we get an exception, delete the exception and
  177. // return FALSE.
  178. catch( CFileException *e ){
  179. e->Delete();
  180. return( FALSE );
  181. }
  182. return( TRUE );
  183. }
  184. BOOL CDib::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight, int Style )
  185. {
  186.   long i,j;
  187.   // If we have not data we can't draw.
  188.   if( m_pDib == NULL )
  189. return( FALSE );
  190.   // if this is an 16/12 bit image, 
  191.   // we should map the 16/12 data to 8 bit
  192.   long vWidth = (4 - m_pBIH->biWidth % 4) % 4 + m_pBIH->biWidth;
  193.  
  194. if ( m_BitCount != 8)
  195. {
  196. for (i = 0; i< m_pBIH->biHeight; i++)
  197.   for (j = 0; j < m_pBIH->biWidth; j++)
  198.   {
  199.   *(m_pDibBits+i*vWidth+j) = (m_pWordData[i*m_pBIH->biWidth+j] >> (m_BitCount-8));
  200.   }
  201.   }
  202.   // Check for the default values of -1
  203. // in the width and height arguments. If
  204.   // we find -1 in either, we'll set them
  205.   // to the value that's in the BITMAPINFOHEADER.
  206.   if( nWidth == -1 )
  207.   nWidth = m_pBIH->biWidth;
  208. if( nHeight == -1 )
  209.   nHeight = m_pBIH->biHeight;
  210.  
  211. if (Style)   // non_zero: Use StretchDIBits to draw the Dib.
  212.   {
  213.   StretchDIBits( pDC->m_hDC, nX, nY,
  214.   nWidth, nHeight,
  215.   0, 0,
  216.   m_pBIH->biWidth, m_pBIH->biHeight,
  217.   m_pDibBits,
  218.   (BITMAPINFO *) m_pBIH,
  219. BI_RGB, SRCCOPY );
  220.   }
  221.   else 
  222. {
  223. SetDIBitsToDevice( pDC->m_hDC, nX, nY,
  224.   m_pBIH->biWidth, m_pBIH->biHeight,
  225. 0, 0,
  226.   0, m_pBIH->biHeight,//nHeight,
  227.   m_pDibBits,
  228.   (BITMAPINFO *) m_pBIH,
  229.   BI_RGB);
  230.   }
  231. return( TRUE );
  232. }
  233. BOOL CDib::SetPalette( CDC *pDC )
  234. {
  235. // If we have not data we
  236. // won't want to set the palette.
  237. if( m_pDib == NULL )
  238. return( FALSE );
  239. // Check to see if we have a palette
  240. // handle. For Dibs greater than 8 bits,
  241. // this will be NULL.
  242. if( m_Palette.GetSafeHandle() == NULL )
  243. return( TRUE );
  244. // Select the palette, realize the palette,
  245. // then finally restore the old palette.
  246. CPalette *pOldPalette;
  247. pOldPalette = pDC->SelectPalette( &m_Palette, FALSE );
  248. pDC->RealizePalette();
  249. pDC->SelectPalette( pOldPalette, FALSE );
  250. return( TRUE );
  251. }
  252. // 一个特别简单的二值化程序以128为界划分
  253. bool CDib::ConvertToTwoValue()
  254. {
  255. // DWORD size;
  256. unsigned char *p;
  257. p = m_pDibBits;
  258. int i,j;
  259. for (i=0;i<m_nHeight;++i)
  260. {
  261. for (j=0;j<m_nWidth;++j)
  262. {
  263. if(p[i*m_nWidth_Step+j]<128)
  264. p[i*m_nWidth_Step+j] = 0;
  265. else
  266. p[i*m_nWidth_Step+j] = 255;
  267. }
  268. }
  269. return true;
  270. }
  271. // 将彩色图像转化为灰度图像
  272. void CDib::RGB2GRAY()
  273. {
  274. }
  275. /*************************求最大值*************************
  276. ***********************************************************/
  277. int CDib::GetMax()
  278. {
  279. int Max = 0;
  280. unsigned char *p;
  281.     
  282. p = m_pDibBits;
  283. int i,j;
  284. for (i=0;i<m_nHeight;++i)
  285. {
  286. for (j=0;j<m_nWidth;++j)
  287. {
  288. if(p[i*m_nWidth_Step+j]>Max)
  289. Max = p[i*m_nWidth_Step+j];
  290. }
  291. }
  292. return Max;
  293. }
  294. /************************求最小值*************************
  295. **********************************************************/
  296. int CDib::GetMin()
  297. {
  298. int Min = 0;
  299. unsigned char *p;
  300.     
  301. p = m_pDibBits;
  302. int i,j;
  303. for (i=0;i<m_nHeight;++i)
  304. {
  305. for (j=0;j<m_nWidth;++j)
  306. {
  307. if(p[i*m_nWidth_Step+j]<Min)
  308. Min = p[i*m_nWidth_Step+j];
  309. }
  310. }
  311. return Min;
  312. }
  313. /************************求平均值************************
  314. *********************************************************/
  315. float CDib::GetAve()
  316. {
  317. float Ave = 0;
  318. long sum=0,num=0;
  319. unsigned char *p;
  320.     
  321. p = m_pDibBits;
  322. int i,j;
  323. for (i=0;i<m_nHeight;++i)
  324. {
  325. for (j=0;j<m_nWidth;++j)
  326. {
  327. sum += p[i*m_nWidth_Step+j];
  328. num ++;
  329. }
  330. }
  331. Ave =(float) sum /(float)num;
  332. return Ave;
  333. }
  334. //图象反转
  335. void CDib::Reverse()
  336. {
  337. unsigned char *p;
  338. p = m_pDibBits;
  339. int i,j;
  340. for (i=0;i<m_nHeight;++i)
  341. {
  342. for (j=0;j<m_nWidth;++j)
  343. {
  344. p[i*m_nWidth_Step+j] = 255 -p[i*m_nWidth_Step+j];
  345. }
  346. }
  347. }
  348. /*********************灰度线性变换***************************
  349. *执行的变换是分段线性变换,参数(Ax,Ay),(Bx,By)是分段点的坐标*
  350. *************************************************************/
  351. void CDib::Pointlinear()
  352. {
  353. unsigned char *p;
  354. p = m_pDibBits;
  355. float Ax=50,Ay=10,Bx=200,By=245;//参数,通过调节这四个值可以得到不同的拉伸效果
  356. int Tran[256];//变换表
  357. float i,j;
  358. for(i=0;i<256;i++)
  359. {
  360. if((0<=i)&&(i<Ax))
  361. Tran[(int)i]=(int)(i*Ay/Ax);
  362. else if((Ax<=i)&&(i<Bx))
  363. Tran[(int)i]=(int)(i*(By-Ay)/(Bx-Ax)+(Ax*By-Ay*Bx)/(Ax-Bx));
  364. else if((Bx<=i)&&(i<256))
  365. Tran[(int)i]=(int)(i*(255-By)/(255-Bx)+255*(By-Bx)/(255-Bx));
  366. }
  367. for (i=0;i<m_nHeight;++i)
  368. {
  369. for (j=0;j<m_nWidth;++j)
  370. {
  371. p[(int)i*m_nWidth_Step+(int)j] = Tran[p[(int)i*m_nWidth_Step+(int)j]];
  372. }
  373. }
  374. }
  375. /******************统计直方图************************
  376. * 统计图像的直方图,并且把它画出来 *
  377. *****************************************************/
  378. void CDib::Histogram()
  379. {
  380. unsigned char *p;
  381. float histogram[256],max;
  382. p = m_pDibBits;
  383. int i,j,rk;
  384. for(i=0;i<256;i++)
  385. histogram[i]=0;
  386. for (i=0;i<m_nHeight;++i)
  387. {
  388. for (j=0;j<m_nWidth;++j)
  389. {
  390. rk=p[i*m_nWidth_Step+j];
  391. histogram[rk] ++;//个数统计
  392. }
  393. }
  394. max=histogram[0];
  395. for(i=0;i<256;i++)
  396. if(histogram[i]>max)
  397. max=histogram[i];//统计直方图最大值
  398. for(i=0;i<256;i++)
  399. histogram[i]=(m_nHeight-1)*histogram[i]/max;//归一化处理,显示时保持最高的一列高度恒定
  400. int NOP=0;
  401. for(j=0;j<256;j++)
  402. {
  403. for(i=m_nHeight;i>0;i--)
  404. {
  405. if(i<(int)histogram[j])p[i*m_nWidth_Step+j]=0;
  406. else p[i*m_nWidth_Step+j]=255;//显示,想出这个方法的邹磊同学很NB
  407. }
  408. }
  409. }
  410. /**********************直方图均衡************************
  411. *********************************************************/
  412. void CDib::HistEqua()
  413. {
  414. unsigned char *p;
  415. float histogram[256];
  416. p = m_pDibBits;
  417. int i,j,rk;
  418. for(rk=0;rk<256;rk++)
  419. histogram[rk]=0;
  420. for (i=0;i<m_nHeight;++i)
  421. {
  422. for (j=0;j<m_nWidth;++j)
  423. {
  424. rk=p[i*m_nWidth_Step+j];
  425. histogram[rk] ++;//个数统计
  426. }
  427. }
  428. for(i=0;i<256;i++)
  429. histogram[i]=histogram[i]/(256*256);//转化为概率
  430. float Pr[256];
  431. int T[256];
  432. Pr[0]=histogram[0];
  433. T[0]=(int)(Pr[0]*256);
  434. for(i=1;i<256;i++)
  435. {
  436. Pr[i]=Pr[i-1]+histogram[i];
  437. T[i]=(int)(Pr[i]*256);
  438. }
  439. for (i=0;i<m_nHeight;++i)
  440. {
  441. for (j=0;j<m_nWidth;++j)
  442. {
  443. p[i*m_nWidth_Step+j] =T[p[i*m_nWidth_Step+j]];
  444. }
  445. }
  446. }
  447. //平移变换
  448. void CDib::GeomTrans()
  449. {
  450. }
  451. //缩放变换
  452. void CDib::GeomZoom()
  453. {
  454. }
  455. /*******************旋转变换*************************
  456. * 将图象逆时针旋转Degrees角,Degrees是可变参量 *
  457. *****************************************************/
  458. int * CDib::GeomRota()
  459. {
  460. unsigned char *p;
  461. p = m_pDibBits;
  462. double Degrees=60+0;//旋转的角度
  463. double radians = (Degrees/90.0)*(PI/2);//从度转化为弧度
  464. float cosine = (float)cos(radians);
  465. float sine = (float)sin(radians);
  466. //计算旋转后的图像的宽和长
  467. int h = (int)(m_nHeight*fabs(cosine)+m_nWidth*fabs(sine));
  468. int w = (int)(m_nHeight*fabs(sine)+m_nWidth*fabs(cosine));
  469. // if(q!=NULL)
  470. // delete[] q;////////////////////////////////////////////////为什么只要用了DELETE就不正常?
  471. q=new int [w*h+2];
  472. int y,x,sx,sy;
  473. float sourcex,sourcey,x1,y1;
  474. int NOP=0;
  475. for(y=0;y<h;y++)
  476. {
  477. for(x=0;x<w;x++)
  478. {
  479. if(0<=Degrees&&Degrees<90)
  480. {
  481. x1=x-m_nHeight*sine;
  482. y1=(float)y;
  483. }
  484. else if(90<=Degrees&&Degrees<180)
  485. {
  486. x1=(float)(x-w);
  487. y1=y+m_nWidth*cosine;
  488. }
  489. else if(180<=Degrees&&Degrees<270)
  490. {
  491. x1=x+m_nHeight*cosine;
  492. y1=(float)(y-h);
  493. }
  494. else if(180<=Degrees&&Degrees<=360)
  495. {
  496. x1=(float)x;
  497. y1=y+m_nHeight*sine;
  498. }
  499. else 
  500. MessageBox(NULL,"请输入0-360°的角度值","警告",MB_OK);
  501. /***********当使用双线性内插时***********************************************************************
  502. sourcex =x1*cosine+y1*sine;
  503. sourcey =y1*cosine-x1*sine;
  504. sx=(int)ceil(sourcex);
  505. sy=(int)ceil(sourcey);
  506. float dx=sourcex-sx;
  507. float dy=sourcey-sy;
  508. if(sx>=0&&sx<m_nWidth&&sy>=0&&sy<m_nHeight)
  509. {
  510. q[y*w+x+2]=(int)(dx*dy*p[sy*m_nWidth_Step+sx]+dx*(1-dy)*p[(sy+1)*m_nWidth_Step+sx]
  511. +(1-dx)*dy*p[sy*m_nWidth_Step+sx+1]+(1-dx)*(1-dy)*p[(sy+1)*m_nWidth_Step+sx+1]);
  512. }
  513. else q[y*w+x+2]=0;
  514. *******************************************************************************************************/
  515. /***********当不使用双线性内插时***********************************************************************/
  516. sourcex =x1*cosine+y1*sine;
  517. sourcey =y1*cosine-x1*sine;
  518. sx=(int)ceil(sourcex);
  519. sy=(int)ceil(sourcey);
  520. if(sx>=0&&sx<m_nWidth&&sy>=0&&sy<m_nHeight)
  521. {
  522. q[y*w+x+2]=p[sy*m_nWidth_Step+sx];
  523. }
  524. else q[y*w+x+2]=0;
  525. }
  526. }
  527. q[0]=w;
  528. q[1]=h;
  529. return q;
  530. }
  531. //复数
  532. typedef struct
  533. {
  534. double re;
  535. double im;
  536. }COMPLEX;
  537. //复数加法
  538. COMPLEX Add(COMPLEX c1, COMPLEX c2)
  539. {
  540. COMPLEX c;
  541. c.re=c1.re+c2.re;
  542. c.im=c1.im+c2.im;
  543. return c;
  544. }
  545. //复数减法
  546. COMPLEX Sub(COMPLEX c1, COMPLEX c2)
  547. {
  548. COMPLEX c;
  549. c.re=c1.re-c2.re;
  550. c.im=c1.im-c2.im;
  551. return c;
  552. }
  553. //复数乘法
  554. COMPLEX Mul(COMPLEX c1, COMPLEX c2)
  555. {
  556. COMPLEX c;
  557. c.re=c1.re*c2.re-c1.im*c2.im;
  558. c.im=c1.re*c2.im+c2.re*c1.im;
  559. return c;
  560. }
  561. //FFT变换
  562. void DOFFT(COMPLEX * TD, COMPLEX * FD, int power)
  563. {
  564. int count;
  565. int i,j,k,bfsize,p;
  566. double angle;
  567. COMPLEX *W,*X1,*X2,*X;
  568. /*计算傅立叶变换点数*/
  569. count=1<<power;
  570. /*分配运算所需存储器*/
  571. W=(COMPLEX *)malloc(sizeof(COMPLEX)*count/2);
  572. X1=(COMPLEX *)malloc(sizeof(COMPLEX)*count);
  573. X2=(COMPLEX *)malloc(sizeof(COMPLEX)*count);
  574. /*计算加权系数*/
  575. for(i=0;i<count/2;i++)
  576. {
  577. angle=-i*PI*2/count;
  578. W[i].re=cos(angle);
  579. W[i].im=sin(angle);
  580. }
  581. /*将时域点写入存储器*/
  582. memcpy(X1,TD,sizeof(COMPLEX)*count);
  583. /*蝶形运算*/
  584. for(k=0;k<power;k++)
  585. {
  586. for(j=0;j<1<<k;j++)
  587. {
  588. bfsize=1<<(power-k);
  589. for(i=0;i<bfsize/2;i++)
  590. {
  591. p=j*bfsize;
  592. X2[i+p]=Add(X1[i+p],X1[i+p+bfsize/2]);
  593. X2[i+p+bfsize/2]=Mul(Sub(X1[i+p],X1[i+p+bfsize/2]),W[i*(1<<k)]);
  594. }
  595. }
  596. X=X1;
  597. X1=X2;
  598. X2=X;
  599. }
  600. /*重新排序*/
  601. for(j=0;j<count;j++)
  602. {
  603. p=0;
  604. for(i=0;i<power;i++)
  605. {
  606. if (j&(1<<i)) p+=1<<(power-i-1);
  607. }
  608. FD[j]=X1[p];
  609. }
  610. /*释放存储器*/
  611. free(W);
  612. free(X1);
  613. free(X2);
  614. }
  615. /**************************FFT*************************
  616. ******************************************************/
  617. void CDib::FFT()
  618. {
  619. unsigned char *p;
  620. p = m_pDibBits;
  621. int i,j;
  622. for (i=0;i<m_nHeight;++i)
  623. {
  624. for (j=0;j<m_nWidth;++j)
  625. {
  626. p[i*m_nWidth_Step+j] =p[i*m_nWidth_Step+j];
  627. }
  628. }
  629. int w=1,h=1,wp=0,hp=0;
  630. while(w*2<=m_nWidth)
  631. {
  632. w*=2;
  633. wp++;
  634. }
  635. while(h*2<=m_nHeight)
  636. {
  637. h*=2;
  638. hp++;
  639. }
  640. COMPLEX *TD=new COMPLEX[w*h];
  641. COMPLEX *FD=new COMPLEX[w*h];
  642. int x,y;
  643. for(y=0;y<h;y++)
  644. {
  645. for(x=0;x<w;x++)
  646. {
  647. TD[x+w*y].re=p[x+w*y];
  648. TD[x+w*y].im=0;
  649. }
  650. }
  651. for(y=0;y<h;y++)
  652. {
  653. DOFFT(&TD[w*y],&FD[w*y],wp);
  654. }
  655. for(y=0;y<h;y++)
  656. {
  657. for(x=0;x<w;x++)
  658. {
  659. TD[y+h*x]=FD[x+w*y];
  660. }
  661. }
  662. for(x=0;x<w;x++)
  663. {
  664. DOFFT(&TD[x*h],&FD[x*h],hp);
  665. }
  666. for(y=0;y<h;y++)
  667. {
  668. for(x=0;x<w;x++)
  669. {
  670. p[x+w*y]=(int)sqrt(FD[x*h+y].re*FD[x*h+y].re+FD[x*h+y].im*FD[x*h+y].im)/100;
  671. if (p[x+w*y]>255) p[x+w*y]=255;
  672. }
  673. }
  674. }
  675. void DODCT(double *f, double *F, int power)
  676. {
  677. int i,count;
  678. COMPLEX *X;
  679. double s;
  680. /*计算离散余弦变换点数*/
  681. count=1<<power;
  682. /*分配运算所需存储器*/
  683. X=(COMPLEX *)malloc(sizeof(COMPLEX)*count*2);
  684. /*延拓*/
  685. memset(X,0,sizeof(COMPLEX)*count*2);
  686. /*将时域点写入存储器*/
  687. for(i=0;i<count;i++)
  688. {
  689. X[i].re=f[i];
  690. }
  691. /*调用快速傅立叶变换*/
  692. DOFFT(X,X,power+1);
  693. /*调整系数*/
  694. s=1/sqrt(count);
  695. F[0]=X[0].re*s;
  696. s*=sqrt(2);
  697. for(i=1;i<count;i++)
  698. {
  699. F[i]=(X[i].re*cos(i*PI/(count*2))+X[i].im*sin(i*PI/(count*2)))*s;
  700. }
  701. /*释放存储器*/
  702. free(X);
  703. }
  704. /****************************DCT*****************************
  705. ************************************************************/
  706. void CDib::DCT()
  707. {
  708. unsigned char *p;
  709. p = m_pDibBits;
  710. int w=1,h=1,wp=0,hp=0;
  711. while(w*2<=m_nWidth)
  712. {
  713. w*=2;
  714. wp++;
  715. }
  716. while(h*2<=m_nHeight)
  717. {
  718. h*=2;
  719. hp++;
  720. }
  721. int x,y;
  722. double *f=new double[w*h];
  723. double *W=new double[w*h];
  724. for(y=0;y<h;y++)
  725. {
  726. for(x=0;x<w;x++)
  727. {
  728. f[x+y*w]=p[x+w*y];
  729. }
  730. }
  731. for(y=0;y<h;y++)
  732. {
  733. DODCT(&f[w*y],&W[w*y],wp);
  734. }
  735. for(y=0;y<h;y++)
  736. {
  737. for(x=0;x<w;x++)
  738. {
  739. f[x*h+y]=W[x+w*y];
  740. }
  741. }
  742. for(x=0;x<w;x++)
  743. {
  744. DODCT(&f[x*h],&W[x*h],hp);
  745. }
  746. double a;
  747. for(y=0;y<h;y++)
  748. {
  749. for(x=0;x<w;x++)
  750. {
  751. p[x+w*y]=(int)fabs(W[x*h+y]);
  752. if (a>255) a=255;
  753. }
  754. }
  755. }
  756. void CDib::Walsh()
  757. {
  758. }
  759. void CDib::Wavelet()
  760. {
  761. }
  762. //均值滤波
  763. void CDib::EnhaAverF()
  764. {
  765. unsigned char *p;
  766. int ave[256*256];
  767. int some[3*3];
  768. float sum;
  769. p = m_pDibBits;
  770. int i,j,k,l;
  771. for (i=0;i<m_nHeight;++i)
  772. {
  773. for (j=0;j<m_nWidth;++j)
  774. {
  775. for(k=0;k<3;k++)
  776. for(l=0;l<3;l++)
  777. some[k*3+l]=p[(i+k-1)*m_nWidth_Step+j+l-1];
  778. sum=0;
  779. for(l=0;l<3;l++)
  780. for(k=0;k<3;k++)
  781. sum+=some[k*3+l];
  782. ave[i*m_nWidth_Step+j]=(int)(sum/9);
  783. }
  784. }
  785. for (i=0;i<m_nHeight;++i)
  786. {
  787. for (j=0;j<m_nWidth;++j)
  788. {
  789. p[i*m_nWidth_Step+j] =ave[i*m_nWidth_Step+j];
  790. }
  791. }
  792. }
  793. /****************************中值滤波***************************
  794. ***************************************************************/
  795. void CDib::EnhaMidianF()
  796. {
  797. unsigned char *p;
  798. int *mid;
  799. mid=new int [m_nHeight*m_nWidth];
  800. int some[3*3],tmp;
  801. p = m_pDibBits;
  802. int i,j,k,l;
  803. for (i=0;i<m_nHeight;++i)
  804. {
  805. for (j=0;j<m_nWidth;++j)
  806. {
  807. for(k=0;k<3;k++)
  808. for(l=0;l<3;l++)
  809. some[k*3+l]=p[(i+k-1)*m_nWidth_Step+j+l-1];
  810. for(l=0;l<9;l++)
  811. for(k=0;k<8;k++)
  812. {
  813. if(some[k]<some[k+1])
  814. {
  815. tmp=some[k];
  816. some[k]=some[k+1];
  817. some[k+1]=tmp;
  818. }
  819. }
  820. mid[i*m_nWidth_Step+j]=some[4];
  821. }
  822. }
  823. for (i=0;i<m_nHeight;++i)
  824. {
  825. for (j=0;j<m_nWidth;++j)
  826. {
  827. p[i*m_nWidth_Step+j] =mid[i*m_nWidth_Step+j];
  828. }
  829. }
  830. }
  831. /*************************Sobel**********************
  832. ****************************************************/
  833. void CDib::Sobel()
  834. {
  835. unsigned char *p;
  836. int S[256*256];
  837. p = m_pDibBits;
  838. int i,j;
  839. for (i=1;i<m_nHeight-1;++i)
  840. {
  841. for (j=1;j<m_nWidth-1;++j)
  842. {
  843. S[i*m_nWidth_Step+j]=2*p[(i+1)*m_nWidth_Step+j]-2*p[(i-1)*m_nWidth_Step+j]
  844. +p[(i+1)*m_nWidth_Step+j-1]-p[(i-1)*m_nWidth_Step+j-1]+p[(i+1)*m_nWidth_Step+j+1]-p[(i-1)*m_nWidth_Step+j+1];
  845. }
  846. }
  847. for (i=1;i<m_nHeight-1;++i)
  848. {
  849. for (j=1;j<m_nWidth-1;++j)
  850. {
  851. p[i*m_nWidth_Step+j] =S[i*m_nWidth_Step+j];
  852. if(p[i*m_nWidth_Step+j]>255)p[i*m_nWidth_Step+j]=255;
  853. if(p[i*m_nWidth_Step+j]<0)p[i*m_nWidth_Step+j]=0;
  854. }
  855. }
  856. }
  857. /***********************Laplace*************************
  858. *******************************************************/
  859. void CDib::Laplace()
  860. {
  861. unsigned char *p;
  862. int L[256*256];
  863. p = m_pDibBits;
  864. int i,j;
  865. for (i=1;i<m_nHeight-1;++i)
  866. {
  867. for (j=1;j<m_nWidth-1;++j)
  868. {
  869. L[i*m_nWidth_Step+j]=4*p[i*m_nWidth_Step+j]-p[(i-1)*m_nWidth_Step+j]
  870. -p[(i+1)*m_nWidth_Step+j]-p[i*m_nWidth_Step+j-1]-p[i*m_nWidth_Step+j+1];
  871. }
  872. }
  873. for (i=1;i<m_nHeight-1;++i)
  874. {
  875. for (j=1;j<m_nWidth-1;++j)
  876. {
  877. p[i*m_nWidth_Step+j] =L[i*m_nWidth_Step+j];
  878. if(p[i*m_nWidth_Step+j]>255)p[i*m_nWidth_Step+j]=255;
  879. if(p[i*m_nWidth_Step+j]<0)p[i*m_nWidth_Step+j]=0;
  880. }
  881. }
  882. }
  883. /*********************随机噪声**********************
  884. ***************************************************/
  885. void CDib::RandomNoise()
  886. {
  887. unsigned char *p;
  888. p = m_pDibBits;
  889. int i,j,k,N=256*3,Noise;
  890. for(k=0;k<N;k++)
  891. {
  892. i=rand()%m_nHeight;
  893. j=rand()%m_nWidth;
  894. Noise=rand()%512;
  895. p[i*m_nWidth_Step+j] += Noise-256;
  896. }
  897. }
  898. /*********************盐椒噪声*********************
  899. **************************************************/
  900. void CDib::SaltNoise()
  901. {
  902. unsigned char *p;
  903. p = m_pDibBits;
  904. int i,j,k,N=256*3,Noise;
  905. for(k=0;k<N;k++)
  906. {
  907. i=rand()%m_nHeight;
  908. j=rand()%m_nWidth;
  909. Noise=rand()%2;
  910. if(Noise==0)
  911. p[i*m_nWidth_Step+j] =0;
  912. else p[i*m_nWidth_Step+j] =255;
  913. }
  914. }
  915. //逆滤波恢复
  916. void CDib::RestoreInverse()
  917. {
  918. }
  919. //维纳滤波恢复
  920. void CDib::RestoreWiener()
  921. {
  922. }
  923. /************************图像重建************************
  924. ********************************************************/
  925. void CDib::Reconstruction()
  926. {
  927. unsigned char *p;
  928. p=m_pDibBits;
  929. int i,j;
  930. for (i=0;i<m_nHeight;++i)
  931. {
  932. for (j=0;j<m_nWidth;++j)
  933. {
  934. p[i*m_nWidth_Step+j] =temp[i*m_nWidth_Step+j];
  935. }
  936. }
  937. }
  938. void CDib::Huffman()
  939. {
  940. }
  941. void CDib::Runlength()
  942. {
  943. }
  944. void CDib::Algorithem()
  945. {
  946. }
  947. void CDib::LZW()
  948. {
  949. }
  950. void CDib::JPEG()
  951. {
  952. }