图像拼接技术Doc.cpp
上传用户:pureled
上传日期:2013-05-27
资源大小:1078k
文件大小:21k
源码类别:

GDI/图象编程

开发平台:

Visual C++

  1. // 图像拼接技术Doc.cpp : implementation of the CMyDoc class
  2. //
  3. #include "stdafx.h"
  4. #include "图像拼接技术.h"
  5. #include "图像拼接技术Doc.h "
  6. #include "windowsx.h"
  7. #include "Start.h"
  8. #include "Other.h"
  9. #include "ZuoBiao.h"
  10. #include "Weizhi.h"
  11. #include "Wuizhi2.h"
  12. #include "Weizhi3.h"
  13. #include "RotateAngle.h"
  14. #include <math.h>
  15. #ifdef _DEBUG
  16. #define new DEBUG_NEW
  17. #define PI 3.1415926535
  18. #define RADIAN(angle) ((angle)*PI/180.0)
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CMyDoc
  24. IMPLEMENT_DYNCREATE(CMyDoc, CDocument)
  25. BEGIN_MESSAGE_MAP(CMyDoc, CDocument)
  26. //{{AFX_MSG_MAP(CMyDoc)
  27. ON_COMMAND(ID_FILE_OTHEROPEN, OnFileOtheropen)
  28. ON_COMMAND(ID_PINJIE, OnPinjie)
  29. ON_COMMAND(ID_SUANFA1, OnSuanfa1)
  30. ON_COMMAND(ID_SUANFA2, OnSuanfa2)
  31. ON_COMMAND(ID_ROTATEPINJIE, OnRotatepinjie)
  32. ON_COMMAND(ID_SUANFA3, OnSuanfa3)
  33. ON_COMMAND(ID_CHUIZHIPINJIE, OnChuizhipinjie)
  34. ON_COMMAND(ID_SAVEBITMAP, OnSavebitmap)
  35. //}}AFX_MSG_MAP
  36. END_MESSAGE_MAP()
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CMyDoc construction/destruction
  39. CMyDoc::CMyDoc()
  40. {
  41. // TODO: add one-time construction code here
  42. }
  43. CMyDoc::~CMyDoc()
  44. {
  45. }
  46. BOOL CMyDoc::OnNewDocument()
  47. {
  48. if (!CDocument::OnNewDocument())
  49. return FALSE;
  50. // TODO: add reinitialization code here
  51. // (SDI documents will reuse this document)
  52. return TRUE;
  53. }
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CMyDoc serialization
  56. void CMyDoc::Serialize(CArchive& ar)
  57. {
  58. if (ar.IsStoring())
  59. {
  60. // TODO: add storing code here
  61. }
  62. else
  63. {
  64. // TODO: add loading code here
  65. }
  66. }
  67. /////////////////////////////////////////////////////////////////////////////
  68. // CMyDoc diagnostics
  69. #ifdef _DEBUG
  70. void CMyDoc::AssertValid() const
  71. {
  72. CDocument::AssertValid();
  73. }
  74. void CMyDoc::Dump(CDumpContext& dc) const
  75. {
  76. CDocument::Dump(dc);
  77. }
  78. #endif //_DEBUG
  79. /////////////////////////////////////////////////////////////////////////////
  80. // CMyDoc commands
  81. BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName) 
  82. {
  83. if (!CDocument::OnOpenDocument(lpszPathName))
  84. return FALSE;
  85. // TODO: Add your specialized creation code here
  86. CFile file;
  87. LONG lBitsSize;
  88. HLOCAL hNew;
  89. if(file.Open(lpszPathName,CFile::modeRead)==NULL)
  90. {
  91. MessageBox(NULL,"打开文件失败!","提示",MB_OK);
  92. return FALSE;
  93. }
  94. file.Read(&lbmpHeader,sizeof(BITMAPFILEHEADER));
  95. if(lbmpHeader.bfType!=(WORD)(('M'<<8)|'B'))
  96. {
  97. MessageBox(NULL,"不是位图文件!","提示",MB_OK);
  98. file.Close();
  99. return FALSE;
  100. }
  101. lBitsSize=lbmpHeader.bfSize;
  102. lbmpInfo=(BITMAPINFO*)GlobalAllocPtr(GHND,lBitsSize-
  103. sizeof(BITMAPFILEHEADER));//开辟空间
  104. file.Read(lbmpInfo,lBitsSize-sizeof(BITMAPFILEHEADER));
  105. if((lbmpInfo->bmiHeader.biBitCount!=8)||(lbmpInfo->bmiHeader.biCompression!=BI_RGB))
  106. {
  107. MessageBox(NULL,"不是256色位图或是压缩的图像","提示",MB_OK);
  108. lbmpInfo=NULL;
  109. file.Close();
  110. return FALSE;
  111. }
  112. size.cx=lbmpInfo->bmiHeader.biWidth;
  113. size.cy=lbmpInfo->bmiHeader.biHeight;
  114. rgbPal=(LPBYTE)lbmpInfo+sizeof(BITMAPINFOHEADER);
  115. lpBits=(LPBYTE)lbmpInfo+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
  116. TrueWidth=(size.cx+3)/4*4;
  117. file.Close();
  118. //获取第一图的位置
  119. Start XY;
  120. XY.DoModal();
  121. m_x=XY.m_x;
  122. m_y=XY.m_y;
  123. //分配内存
  124. hNew=LocalAlloc(LHND,size.cy*TrueWidth);
  125. Lp1=(BYTE*)LocalLock(hNew);
  126. //存放第一幅图像
  127. memcpy(Lp1,lpBits,size.cy*TrueWidth);
  128. return TRUE;
  129. }
  130. void CMyDoc::ShowBitmap(CDC *pDC)
  131. {
  132. ::StretchDIBits(pDC->m_hDC,m_x,m_y,size.cx,size.cy,0,0,
  133. size.cx,size.cy,lpBits,lbmpInfo,DIB_RGB_COLORS,SRCCOPY);
  134. }
  135. void CMyDoc::OnFileOtheropen() 
  136. {
  137. // TODO: Add your command handler code here
  138. CString FilePath;
  139. CFile file;
  140. BITMAPFILEHEADER lbmpHeader;
  141. LONG lBitsSize;
  142. HLOCAL hNew;
  143. CFileDialog dlgOpen(TRUE,".bmp",FilePath,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
  144. "位图文件(*.bmp)|*.bmp||");
  145. if(dlgOpen.DoModal()==IDOK)
  146. FilePath=dlgOpen.GetPathName();
  147. if(file.Open(FilePath,CFile::modeRead)==NULL)
  148. {
  149. MessageBox(NULL,"打开文件失败!","提示",MB_OK);
  150. return;
  151. }
  152. file.Read(&lbmpHeader,sizeof(BITMAPFILEHEADER));
  153. if(lbmpHeader.bfType!=(WORD)(('M'<<8)|'B'))
  154. {
  155. MessageBox(NULL,"不是位图文件!","提示",MB_OK);
  156. file.Close();
  157. return;
  158. }
  159. lBitsSize=lbmpHeader.bfSize;
  160. lbmpInfo2=(BITMAPINFO*)GlobalAllocPtr(GHND,lBitsSize-
  161. sizeof(BITMAPFILEHEADER));
  162. file.Read(lbmpInfo2,lBitsSize-sizeof(BITMAPFILEHEADER));
  163. if((lbmpInfo2->bmiHeader.biBitCount!=8)||(lbmpInfo2->bmiHeader.biCompression!=BI_RGB))
  164. {
  165. MessageBox(NULL,"不是256色位图或是压缩的图像","提示",MB_OK);
  166. lbmpInfo=NULL;
  167. file.Close();
  168. return;
  169. }
  170. size2.cx=lbmpInfo2->bmiHeader.biWidth;
  171. size2.cy=lbmpInfo2->bmiHeader.biHeight;
  172. lpBits2=(LPBYTE)lbmpInfo2+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
  173. TrueWidth2=(size2.cx+3)/4*4;
  174. file.Close();
  175. //获取第二幅图的位置
  176. Other XY;
  177. XY.DoModal();
  178. m2_x=XY.m_x;
  179. m2_y=XY.m_y;
  180.     
  181.     // 分配内存
  182. hNew=LocalAlloc(LHND,size2.cy*TrueWidth2);
  183. Lp2=(BYTE*)LocalLock(hNew);
  184.     //存放第二幅图像
  185. memcpy(Lp2,lpBits2,size2.cy*TrueWidth2);
  186.         
  187. UpdateAllViews(NULL);
  188. }
  189. void CMyDoc::ShowOther(CDC *pDC)
  190. {
  191. ::StretchDIBits(pDC->m_hDC,m2_x,m2_y,size2.cx,size2.cy,0,0,
  192. size2.cx,size2.cy,lpBits2,lbmpInfo2,DIB_RGB_COLORS,SRCCOPY);
  193. }
  194. void CMyDoc::Moban(int a,int b,int c,int d)
  195. {
  196. HLOCAL hNew;
  197. int i;
  198. int j;
  199. m3_x=a;
  200. m3_y=b;
  201.     Height=c;
  202. Width=(d+3)/4*4;
  203. // 分配内存
  204. hNew=LocalAlloc(LHND,Height*Width);
  205. Lp3=(BYTE*)LocalLock(hNew);
  206.         
  207. for (i=0;i<Height;i++)
  208. for (j=0;j<Width;j++)
  209. {
  210. Lp3[i*Width+j]=lpBits2[(size2.cy-m3_y-Height+i)*TrueWidth2+m3_x+j];
  211. }
  212. }
  213. /*void CMyDoc::TemplateMatch()
  214. {
  215. int i;
  216. int j;
  217. int m;
  218. int n;
  219.     //中间结果 
  220.     double dsst;
  221. double dss;
  222. double dst;
  223. //相似性测度
  224. double R;
  225. //最大相似性测度
  226. double maxR;
  227. //最大相似性出现的位置
  228.     int maxWidth;
  229. int maxHeight;
  230. dst=0;
  231. for (n=0;n<Height;n++)
  232. {
  233. for (m=0;m<Width;m++)
  234. {
  235. dst+=(double)DataTemp[n][m];
  236. }
  237. }
  238. maxR=0.0;
  239. for(j=0;j<m_y-Height+1;j++)
  240. {
  241. for(i=0;i<m_x-Width+1;i++)
  242. {
  243. dsst=0;
  244. dss=0;
  245. for(n=0;n<Height;n++)
  246. {
  247. for(m=0;m<Width;m++)
  248. {
  249. dss+=DataMap1[j+n][i+m];
  250. dsst+=DataTemp[n][m];
  251. }
  252. }
  253. //计算相似性
  254. R=dsst/(sqrt(dss)*sqrt(dst));
  255.             //与最大相似性比较
  256. if(R>maxR)
  257. {
  258. maxR=R;
  259. maxWidth=i;
  260. maxHeight=j;
  261. }
  262. }
  263. }
  264.     Match_x=maxWidth;
  265. Match_y=maxHeight;
  266.    
  267. }*/
  268. void CMyDoc::OnPinjie() 
  269. {
  270. // TODO: Add your command handler code here
  271.     //预处理?
  272. HLOCAL hNew;
  273.     int L;
  274. L=size.cx-Match_x+m3_x;
  275. //分配空间
  276.     hNew=LocalAlloc(LHND,size.cy*((2*size.cx-L+3)/4*4));
  277.     NewP=(BYTE*)LocalLock(hNew);
  278.     
  279. //进行拼接  
  280.     for(int j=0;j<size.cy;j++)
  281. for(int i=0;i<TrueWidth;i++)
  282. {
  283.         NewP[j*((2*size.cx-L+3)/4*4)+i]=Lp1[j*TrueWidth+i];
  284. }
  285.     for(int n=0;n<size2.cy;n++)
  286. for(int m=L;m<TrueWidth2;m++)
  287. {
  288. NewP[n*((2*size.cx-L+3)/4*4)+TrueWidth2+m-L]=Lp2[n*TrueWidth2+m];
  289. }
  290. m_bmpHead->bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO)+
  291. 256*sizeof(RGBQUAD)+(DWORD)(size.cy*((2*size.cx-L+3)/4*4)));
  292. m_bmpInfo=(BITMAPINFO*)GlobalAllocPtr(GHND,m_bmpHead->bfSize-sizeof(BITMAPFILEHEADER));
  293. memcpy(m_bmpInfo,lbmpInfo,m_bmpHead->bfSize-sizeof(BITMAPFILEHEADER));
  294. m_bmpInfo->bmiHeader.biWidth=(2*size.cx-L+3)/4*4;
  295. m_bmpInfo->bmiHeader.biHeight=size.cy;
  296. m_bmpInfo->bmiHeader.biSizeImage=size.cy*((2*size.cx-L+3)/4*4);
  297.         //释放内存
  298.    
  299. UpdateAllViews(NULL);
  300. }
  301. void CMyDoc::ShowNew(CDC *pDC)
  302. {   
  303. ::StretchDIBits(pDC->m_hDC,0,500,m_bmpInfo->bmiHeader.biWidth,m_bmpInfo->bmiHeader.biHeight,0,0,
  304. m_bmpInfo->bmiHeader.biWidth,m_bmpInfo->bmiHeader.biHeight,NewP,m_bmpInfo,DIB_RGB_COLORS,SRCCOPY);
  305. }
  306. void CMyDoc::OnSuanfa1() 
  307. {
  308. // TODO: Add your command handler code here
  309.     int a1,a2,a3,a4;
  310.     CZuoBiao XY;
  311. XY.DoModal();
  312. a1=XY.mx;
  313. a2=XY.my;
  314. x1=XY.mx;
  315. y1=XY.my;
  316. a3=XY.h;
  317. a4=XY.w;
  318. // 更改光标形状
  319. BeginWaitCursor();
  320. //获取模板图像
  321.     Moban(a1,a2,a3,a4);
  322. int i;
  323. int j;
  324. int m;
  325. int n;
  326.     //中间结果 
  327.     double dsst;
  328. double dss;
  329. double dst;
  330. //相似性测度
  331. double R;
  332. //最大相似性测度
  333. double maxR;
  334. //最大相似性出现的位置
  335.     int maxWidth;
  336. int maxHeight;
  337. dst=0;
  338. for (n=0;n<Height;n++)
  339. {
  340. for (m=0;m<Width;m++)
  341. {
  342. dst+=(double)Lp3[n*Width+m]*Lp3[n*Width+m];
  343. }
  344. }
  345. maxR=0.0;
  346. for(j=0;j<size.cy-Height+1;j++)
  347. {
  348. for(i=0;i<TrueWidth-Width+1;i++)
  349. {
  350. dsst=0;
  351. dss=0;
  352. for(n=0;n<Height;n++)
  353. {
  354. for(m=0;m<Width;m++)
  355. {
  356. dss+=Lp1[(j+n)*TrueWidth+i+m]*Lp1[(j+n)*TrueWidth+i+m];
  357. dsst+=Lp3[n*Width+m]*Lp1[(j+n)*TrueWidth+i+m];
  358. }
  359. }
  360. //计算相似性
  361. R=dsst/(sqrt(dss)*sqrt(dst));
  362.             //与最大相似性比较
  363. if(R>maxR)
  364. {
  365. maxR=R;
  366. maxWidth=i;
  367. maxHeight=size.cy-Height-j;
  368. }
  369. }
  370. }
  371.     Match_x=maxWidth;
  372. Match_y=maxHeight;
  373. Weizhi d;
  374. d.match_x=Match_x;
  375. d.match_y=Match_y;
  376. d.DoModal();
  377. // 恢复光标形状
  378. EndWaitCursor();
  379. UpdateAllViews(NULL);
  380. }
  381. void CMyDoc::OnSuanfa2() 
  382. {
  383. // TODO: Add your command handler code here
  384. //定义旋转变量
  385.     //float srcX1,srcY1,srcX2,srcY2,srcX3,srcY3,srcX4,srcY4;
  386. //float dstX1,dstY1,dstX2,dstY2,dstX3,dstY3,dstX4,dstY4;
  387. float sina,cosa;
  388. //float num1,num2;
  389. float RotateAngle;
  390. //int Wnew,Hnew;
  391. int k;
  392. int x0,y0,x2,y2;
  393.     float x1,y1,x,y;
  394. double zj;
  395.    
  396.     int a1,a2,a3,a4;
  397.     CZuoBiao XY;
  398. XY.DoModal();
  399. a1=XY.mx;
  400. a2=XY.my;
  401. a3=XY.h;
  402. a4=XY.w;
  403. // 更改光标形状
  404. BeginWaitCursor();
  405. //获取模板图像
  406.     Moban(a1,a2,a3,a4);
  407. int i;
  408. int j;
  409. int n;
  410. int m;
  411.     //中间结果 
  412.     double dsst;
  413. double dss;
  414. double dst;
  415. //相似性测度
  416. double R;
  417. //最大相似性测度
  418. double maxR;
  419. double Max;
  420. //最大相似性出现的位置
  421.     int maxWidth;
  422. int maxHeight;
  423. int matchWidth;
  424. int matchHeight;
  425. dst=0;
  426. for (n=0;n<Height;n++)
  427. {
  428. for (m=0;m<Width;m++)
  429. {
  430. dst+=(double)Lp3[n*Width+m]*Lp3[n*Width+m];
  431. }
  432. }
  433. maxR=0.0;
  434. Max=0.0;
  435.     //以0。1度步进来旋转
  436. for (k=1;k<=30;k++)
  437. {
  438. RotateAngle=(float)RADIAN(k);
  439.         cosa=(float)cos((double)RotateAngle);
  440. sina=(float)sin((double)RotateAngle);
  441. for(j=50;j<size.cy-Height+1;j++)
  442. {
  443.      for(i=50;i<TrueWidth-Width+1;i++)
  444. {
  445.      dsst=0;
  446.      dss=0;
  447.       for(n=0;n<Height;n++)
  448. {
  449.      for(m=0;m<Width;m++)
  450. {
  451. x0=j+n;
  452. y0=i+m;
  453. //x1=x0*cosa-y0*sina+num1;
  454. //y1=x0*sina-y0*cosa+num2;
  455. x1=(x0-i)*cosa-(y0-j)*sina+i;
  456. y1=(x0-i)*sina+(y0-j)*cosa+j;
  457.                         x2=(int)(x1*10/10);
  458. y2=(int)(y1*18/10);
  459. x=x1-x2;
  460. y=y1-y2;
  461. /*zj=(Lp1[x2*TrueWidth+y2+1]-Lp1[x2*TrueWidth+y2])*y+
  462. (Lp1[(x2+1)*TrueWidth+y2]-Lp1[x2*TrueWidth+y2])*x+
  463. (Lp1[(x2+1)*TrueWidth+y2+1]+Lp1[x2*TrueWidth+y2]-
  464.                              Lp1[x2*TrueWidth+y2+1]-Lp1[(x2+1)*TrueWidth+y2])*x*y+
  465.                              Lp1[x2*TrueWidth+y2];*/
  466. zj=Lp1[x2*TrueWidth+y2];
  467. dss+=zj*zj;
  468. dsst+=Lp3[n*Width+m]*zj;
  469. }
  470. }
  471. //计算相似性
  472.      R=dsst/(sqrt(dss)*sqrt(dst));
  473.     //与最大相似性比较
  474.      if(R>maxR)
  475. {
  476.      maxR=R;
  477.      maxWidth=i;
  478.       maxHeight=size.cy-Height-j;
  479. }
  480. }
  481. }
  482. if(maxR>Max)
  483. {
  484. Max=maxR;
  485. matchWidth=maxWidth;
  486. matchHeight=maxHeight;
  487. matchAngle=(float)(k);
  488. }
  489. }
  490. //获得最佳匹配位置
  491.         Match_x=maxWidth;
  492.      Match_y=maxHeight;
  493.         MatchRotateAngle=matchAngle; 
  494.       Wuizhi2 e;
  495.      e.match2_x=Match_x;
  496.      e.match2_y=Match_y;
  497. e.angle=MatchRotateAngle;
  498.      e.DoModal();
  499. // 恢复光标形状
  500. EndWaitCursor();
  501.      UpdateAllViews(NULL);
  502. }
  503.                               
  504. void CMyDoc::OnRotatepinjie() 
  505. {
  506. // TODO: Add your command handler code here
  507.     float srcX1,srcY1,srcX2,srcY2,srcX3,srcY3,srcX4,srcY4;
  508. float dstX1,dstY1,dstX2,dstY2,dstX3,dstY3,dstX4,dstY4;
  509. float sina,cosa;
  510. float num1,num2;
  511. float Rotateangle;
  512. int Wnew,Hnew,TrueWnew;
  513. int i,j,i0,j0;
  514. int k,l;
  515. int L;
  516. int value;
  517. int a;
  518. int bb;
  519. // float a,b;
  520.     HLOCAL htemp;
  521. HLOCAL yuantu;
  522. HLOCAL hNew;
  523. LPBYTE lpPtr;
  524. LPBYTE lpsrc; 
  525.                   
  526. RotateAngle A;
  527. A.DoModal();
  528.     bb=A.Angle;
  529. Rotateangle=float(360-bb); //360-MatchRotateAngle;
  530.     switch (bb)
  531. {   case  1: value=5; a=0;break;
  532. case  2: value=7; a=0;break;
  533. case  4: value=15;a=0;break;
  534. case  3: value=12;a=0;break;
  535.         case  5: value=20;a=0;break;
  536. case  6: value=26;a=0;break;
  537. case  7: value=28;a=0;break;
  538. case  8: value=32;a=0;break;
  539. case  9: value=37;a=0;break;
  540. case 10: value=41;a=0;break;
  541. case 11: value=44;a=0;break;
  542. case 12: value=49;a=0;break;
  543. case 13: value=52;a=0;break;
  544. case 14: value=54;a=0;break;
  545. case 15: value=56;a=0;break;
  546. case 16: value=60;a=0;break;
  547. case 17: value=65;a=0;break;
  548. case 18: value=70;a=0;break;
  549. case 19: value=72;a=0;break;
  550. case 20: value=74;a=0;break;
  551. case 21: value=77;a=0;break;
  552. case 22: value=79;a=0;break;
  553. case 23: value=82;a=0;break;
  554. case 24: value=85;a=0;break;
  555. case 25: value=89;a=0;break;
  556. case 26: value=92;a=0;break;
  557. case 27: value=95;a=0;break;
  558. case 28: value=98;a=0;break;
  559. case 29: value=102;a=0;break;
  560. case 30: value=105;a=3;break;
  561. }
  562.     cosa=(float)cos((double)RADIAN(Rotateangle));
  563. sina=(float)sin((double)RADIAN(Rotateangle));
  564.   /*  cosa=(float)(((Match_x-Match3_x)*(x1-x2)+(Match_y-Match3_x)*(y1-y2))/((x1-x2)*(x1-x2)+
  565.      (y1-y2)*(y1-y2)));
  566. sina=(float)(((Match_x-Match3_x)*(y1-y2)-(x1-x2)*(Match_y-Match3_x))/((x1-x2)*(x1-x2)+
  567.          (y1-y2)*(y1-y2)));*/
  568. // a=acos(cosa);
  569. // b=asin(sina);//旋转2度是7,5度是20,30度是104,10度是41,20度是79,30度是104
  570. //原图的4个角点的坐标
  571.     srcX1=(float)(-(TrueWidth-1)/2);
  572.     srcY1=(float)( (size.cy-1)/2);
  573.     srcX2=(float)( (TrueWidth-1)/2);
  574.     srcY2=(float)( (size.cy-1)/2);
  575.     srcX3=(float)(-(TrueWidth-1)/2);
  576.     srcY3=(float)(-(size.cy-1)/2);
  577.     srcX4=(float)( (TrueWidth-1)/2);
  578.     srcY4=(float)(-(size.cy-1)/2);
  579.    
  580.     //新图4个角点的坐标
  581. dstX1= cosa*srcX1+sina*srcY1;
  582. dstY1=-sina*srcX1+cosa*srcY1;
  583.     dstX2= cosa*srcX2+sina*srcY2;
  584.     dstY2=-sina*srcX2+cosa*srcY2;
  585.     dstX3= cosa*srcX3+sina*srcY3;
  586.     dstY3=-sina*srcX3+cosa*srcY3;
  587. dstX4= cosa*srcX4+sina*srcY4;
  588. dstY4=-sina*srcX4+cosa*srcY4;
  589.     //新图的高和宽
  590.     Wnew=(int)(max(fabs(dstX4-dstX1),fabs(dstX3-dstX2))+0.5);
  591. Hnew=(int)(max(fabs(dstY4-dstY1),fabs(dstY3-dstY2))+0.5);
  592. //真实宽度
  593.     TrueWnew=(Wnew+3)/4*4;
  594.     num1=(float)(-0.5*(Wnew-1)*cosa-0.5*(Hnew-1)*sina+0.5*(TrueWidth-1));
  595.     num2=(float)( 0.5*(Wnew-1)*sina-0.5*(Hnew-1)*cosa+0.5*(size.cy-1));
  596.     //分配空间
  597.     htemp=LocalAlloc(LHND,Hnew*TrueWnew);
  598.     lpPtr=(BYTE*)LocalLock(htemp);
  599.     
  600. //内存中的象素都是白色
  601. //memcpy(lpPtr,BYTE(255),Hnew*TrueWnew);
  602. for(i=0;i<Hnew;i++)
  603. {
  604. for(j=0;j<Wnew;j++)
  605. {
  606.             //计算在原图中的坐标 
  607. i0=(int)(-((float)j)*sina+((float)i)*cosa+num2+0.5);
  608. j0=(int)( ((float)j)*cosa+((float)i)*sina+num1+0.5);
  609.             
  610.     //判断是否在原图范围内
  611. if((j0>=0)&&(j0<TrueWidth)&&(i0>=0)&&(i0<size.cy))
  612. {
  613. //复制图象
  614. lpPtr[TrueWnew*(Hnew-1-i)+j]=Lp1[TrueWidth*(size.cy-1-i0)+j0];
  615. }
  616. else
  617. {
  618. //对于图中没有的图象,直接赋为255
  619. lpPtr[TrueWnew*(Hnew-1-i)+j]=255;
  620. }
  621. }
  622. }
  623.       // 分配内存
  624.     yuantu=LocalAlloc(LHND,size2.cy*TrueWidth2);
  625.     lpsrc=(BYTE*)LocalLock(yuantu);
  626.         for (k=0;k<size2.cy;k++)
  627.      for (l=0;l<TrueWidth2;l++)
  628. {
  629.      lpsrc[k*TrueWidth2+l]=lpPtr[(Hnew-value-size2.cy+k)*TrueWnew+value+l];
  630. }
  631.        //旋转2度是7,5度是20,30度是104,10度是41,20度是79,30度是104
  632.      //L=size.cx-Match_x+m3_x;
  633.         L=128;
  634.      //分配空间
  635.         hNew=LocalAlloc(LHND,size2.cy*((2*size2.cx-L+3)/4*4));
  636.         NewP=(BYTE*)LocalLock(hNew);
  637.     
  638.     //进行拼接  
  639.         for(int p=0;p<size2.cy;p++)
  640.    for(int q=0;q<TrueWidth2;q++)
  641.    {
  642.           NewP[p*((2*size2.cx-L+3)/4*4)+q]=lpsrc[p*TrueWidth2+q];
  643.    }
  644.         for(int n=0;n<size2.cy;n++)
  645.      for(int m=L;m<TrueWidth2;m++)
  646. {
  647.     NewP[n*((2*size2.cx-L+3)/4*4)+TrueWidth2+m-L]=Lp2[(n+a)*TrueWidth2+m];
  648. }
  649. //开辟空间
  650. m_bmpHead=(BITMAPFILEHEADER*)GlobalAllocPtr(GHND,sizeof(BITMAPFILEHEADER));
  651. memcpy(m_bmpHead,&lbmpHeader,sizeof(BITMAPFILEHEADER));
  652. m_bmpHead->bfOffBits=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO)+256*sizeof(RGBQUAD));
  653. m_bmpHead->bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO)+
  654. 256*sizeof(RGBQUAD)+(DWORD)(size2.cy*((2*size2.cx-L+3)/4*4)));
  655. m_bmpInfo=(BITMAPINFO*)GlobalAllocPtr(GHND,m_bmpHead->bfSize-sizeof(BITMAPFILEHEADER));
  656.       memcpy(m_bmpInfo,lbmpInfo,m_bmpHead->bfSize-sizeof(BITMAPFILEHEADER));
  657. m_bmpInfo->bmiHeader.biWidth=(2*size2.cx-L+3)/4*4;
  658. m_bmpInfo->bmiHeader.biHeight=size2.cy;
  659. m_bmpInfo->bmiHeader.biSizeImage=size2.cy*((2*size2.cx-L+3)/4*4);
  660.                                              
  661. // lpBits=(LPBYTE)lbmpInfo+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
  662. // memcpy(lpBits,NewP,lbmpInfo->bmiHeader.biSizeImage);
  663.      //   size.cx=lbmpInfo->bmiHeader.biWidth;
  664. // size.cy=lbmpInfo->bmiHeader.biHeight;
  665.         //释放内存
  666.    
  667. UpdateAllViews(NULL);
  668. }
  669.      
  670. void CMyDoc::OnSuanfa3() 
  671. {
  672. // TODO: Add your command handler code here
  673.     int a1,a2,a3,a4;
  674.     CZuoBiao XY;
  675. XY.DoModal();
  676. a1=XY.mx;
  677. a2=XY.my;
  678. x2=XY.mx;
  679. y2=XY.my;
  680. a3=XY.h;
  681. a4=XY.w;
  682. // 更改光标形状
  683. BeginWaitCursor();
  684. //获取模板图像
  685.     Moban(a1,a2,a3,a4);
  686. int i;
  687. int j;
  688. int m;
  689. int n;
  690.     //中间结果 
  691.     double dsst;
  692. double dss;
  693. double dst;
  694. //相似性测度
  695. double R;
  696. //最大相似性测度
  697. double maxR;
  698. //最大相似性出现的位置
  699.     int maxWidth;
  700. int maxHeight;
  701. dst=0;
  702. for (n=0;n<Height;n++)
  703. {
  704. for (m=0;m<Width;m++)
  705. {
  706. dst+=(double)Lp3[n*Width+m]*Lp3[n*Width+m];
  707. }
  708. }
  709. maxR=0.0;
  710. for(j=0;j<size.cy-Height+1;j++)
  711. {
  712. for(i=0;i<TrueWidth-Width+1;i++)
  713. {
  714. dsst=0;
  715. dss=0;
  716. for(n=0;n<Height;n++)
  717. {
  718. for(m=0;m<Width;m++)
  719. {
  720. dss+=Lp1[(j+n)*TrueWidth+i+m]*Lp1[(j+n)*TrueWidth+i+m];
  721. dsst+=Lp3[n*Width+m]*Lp1[(j+n)*TrueWidth+i+m];
  722. }
  723. }
  724. //计算相似性
  725. R=dsst/(sqrt(dss)*sqrt(dst));
  726.             //与最大相似性比较
  727. if(R>maxR)
  728. {
  729. maxR=R;
  730. maxWidth=i;
  731. maxHeight=size.cy-Height-j;
  732. }
  733. }
  734. }
  735.     Match3_x=maxWidth;
  736. Match3_y=maxHeight;
  737. Weizhi3 f;
  738. f.match3_x=Match3_x;
  739. f.match3_y=Match3_y;
  740. f.DoModal();
  741. // 恢复光标形状
  742. EndWaitCursor();
  743. UpdateAllViews(NULL);
  744. }
  745. void CMyDoc::OnChuizhipinjie() 
  746. {
  747. // TODO: Add your command handler code here
  748. //预处理?
  749. HLOCAL hNew;
  750.     int L;
  751. L=size.cy-Match_y+m3_y;
  752. //分配空间
  753.     hNew=LocalAlloc(LHND,TrueWidth*(2*size.cy-L));
  754.     NewP=(BYTE*)LocalLock(hNew);
  755.     
  756. //进行拼接  
  757.     for(int j=0;j<size.cy;j++)
  758. for(int i=0;i<TrueWidth;i++)
  759. {
  760.         NewP[j*TrueWidth+i]=Lp2[j*TrueWidth+i];
  761. }
  762.     for(int n=L;n<size.cy;n++)
  763. for(int m=0;m<TrueWidth;m++)
  764. {
  765. NewP[(n+size.cy-L)*TrueWidth+m]=Lp1[n*TrueWidth+m];
  766. }
  767. m_bmpHead->bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO)+
  768. 256*sizeof(RGBQUAD)+(DWORD)(TrueWidth*(2*size.cy-L)));
  769. m_bmpInfo=(BITMAPINFO*)GlobalAllocPtr(GHND,m_bmpHead->bfSize-sizeof(BITMAPFILEHEADER));
  770. memcpy(m_bmpInfo,lbmpInfo,m_bmpHead->bfSize-sizeof(BITMAPFILEHEADER));
  771. m_bmpInfo->bmiHeader.biWidth=TrueWidth;
  772. m_bmpInfo->bmiHeader.biHeight=2*size.cy-L;
  773. m_bmpInfo->bmiHeader.biSizeImage=TrueWidth*(2*size.cy-L);
  774.         //释放内存
  775.    
  776. UpdateAllViews(NULL);
  777. }
  778. /*void CMyDoc::DeleteContents() 
  779. {
  780. // TODO: Add your specialized code here and/or call the base class
  781. int liCount=m_oalines.GetSize;
  782. int liPos;
  783. if(liCount)
  784. {
  785. for (liPos=0;liPos<liCount;liPos++)
  786. delete m_oaLines[liPos];
  787. m_oaLines.RemoveAll();
  788. }
  789.         
  790. CDocument::DeleteContents();
  791. }*/
  792. //DEL BOOL CMyDoc::OnSaveDocument(LPCTSTR lpszPathName) 
  793. //DEL {
  794. //DEL  // TODO: Add your specialized code here and/or call the base class
  795. //DEL   CFile fp;
  796. //DEL  fp.Open(lpszPathName,CFile::modeWrite|CFile::modeCreate);
  797. //DEL  fp.Write((LPSTR)&lbmpHeader,sizeof(BITMAPFILEHEADER));
  798. //DEL  fp.Write(lpBits,lbmpHeader.bfSize-sizeof(BITMAPFILEHEADER));
  799. //DEL  fp.Close();
  800. //DEL 
  801. //DEL 
  802. //DEL  SetModifiedFlag(FALSE);
  803. //DEL  return TRUE;
  804. //DEL 
  805. //DEL  //return CDocument::OnSaveDocument(lpszPathName);
  806. //DEL }
  807. void CMyDoc::SaveBitmap()
  808.   CFile fp;
  809.   CFileDialog dlg(NULL,"BMP","*.bmp");
  810.   if(dlg.DoModal()==IDOK)
  811.   {
  812.       fp.Open(dlg.GetPathName(),CFile::modeWrite|CFile::modeCreate);
  813.     fp.Write(m_bmpHead,sizeof(BITMAPFILEHEADER));
  814.       fp.Write(m_bmpInfo,sizeof(BITMAPINFO));
  815.   fp.Write(rgbPal,256*sizeof(RGBQUAD));
  816.   fp.Write(NewP,m_bmpHead->bfSize-sizeof(BITMAPFILEHEADER));
  817.   }
  818.   else
  819.   return;   
  820.   fp.Close();
  821. }
  822. void CMyDoc::OnSavebitmap() 
  823. {
  824. // TODO: Add your command handler code here
  825. SaveBitmap();
  826. }
  827. BOOL CMyDoc::OnSaveDocument(LPCTSTR lpszPathName) 
  828. {
  829. // TODO: Add your specialized code here and/or call the base class
  830. return CDocument::OnSaveDocument(lpszPathName);
  831. }