本文來自http://blog.csdn.net/hellogv/ ,引用必須註明出處!
上次說到了如何在WINCE/WM移植Opencv1.10,這次就說說如何在WM手機上使用裁剪移植後的Open1.10的例子,在opencv上使用OpenSURF(OpenSURF在GoogleCode的地址:http://code.google.com/p/opensurf1/),先來看看本文程式啟動並執行:
左圖為SURF演算法找出的特徵點,右圖為兩個映像相似特徵點的匹配。
本文的代碼可以到http://www.rayfile.com/zh-cn/files/da4d4edc-8af5-11df-9dac-0015c55db73d/這裡下載,代碼裡包含了自己實現的MyHighGUI類,用於轉換/繪製/儲存IplImage映像,也包含了同時支援WINCE/WIN32的第三方BMP操作類庫----DIBSectionCE類(詳見http://www.codeguru.com/cpp/w-p/ce/bitmapsandthegdi/article.php/c3),接下來就貼出部分作業碼:
//*****************************************************************<br />//取得程式當前檔案夾路徑<br />//****************************************************************<br />CString GetCurrentDirectory()<br />{<br />wchar_t pBuf[256];<br />GetModuleFileName(NULL,pBuf,sizeof(pBuf)/sizeof(wchar_t));<br />CString strPath(pBuf);<br />strPath = strPath.Left(strPath.ReverseFind('//') + 1);<br />delete pBuf;<br />return strPath;<br />}</p><p>void CtestDlg::OnBnClickedButton1()<br />{<br />//自訂的HighGUI,詳見MyHighGUI.h<br />MyHighGUI gui;<br />//網上的BMP操作類,支援WINCE/WIN32,地址:http://www.codeguru.com/cpp/w-p/ce/bitmapsandthegdi/article.php/c3<br />CDIBSectionCE ce;<br />//step1:讀取BMP,並轉換為IplImage格式<br />CString bmpPath=GetCurrentDirectory()+L"car1.bmp";<br />ce.Load(bmpPath);<br />int nChannels = ce.GetBitmapInfo()->bmiHeader.biBitCount /8 ;<br />IplImage* img = gui.BMP2Ipl((BYTE*)ce.GetDIBits(),ce.GetWidth(),ce.GetHeight(),nChannels);<br /> ce.DeleteObject();</p><p>//step2:提取圖片中的特徵點<br />IpVec ipts;<br />surfDetDes(img, ipts, false, 3, 4, 2, 0.0004f);</p><p>// step3:畫出特徵點<br />drawIpoints(img, ipts);<br />gui.Show(img,::GetDC(this->m_hWnd),0,0,img->width,img->height);<br />//gui.WriteBmp(L"img33.bmp",(BYTE *)img->imageData,img->imageSize,img->width,img->height);<br /> img=NULL;<br />}</p><p>void CtestDlg::OnBnClickedButton2()<br />{<br />//自訂的HighGUI,詳見MyHighGUI.h<br />MyHighGUI gui;<br />//網上的BMP操作類,支援WINCE/WIN32,地址:http://www.codeguru.com/cpp/w-p/ce/bitmapsandthegdi/article.php/c3<br />CDIBSectionCE ce;<br />//step1:讀取BMP,並轉換為IplImage格式<br />CString bmpPath=GetCurrentDirectory()+L"car1.bmp";<br />ce.Load(bmpPath);<br />int nChannels = ce.GetBitmapInfo()->bmiHeader.biBitCount /8 ;<br />IplImage* img1 = gui.BMP2Ipl((BYTE*)ce.GetDIBits(),ce.GetWidth(),ce.GetHeight(),nChannels);<br />ce.DeleteObject();</p><p>bmpPath=GetCurrentDirectory()+L"car2.bmp";<br />ce.Load(bmpPath);<br />nChannels = ce.GetBitmapInfo()->bmiHeader.biBitCount /8 ;<br />IplImage* img2 = gui.BMP2Ipl((BYTE*)ce.GetDIBits(),ce.GetWidth(),ce.GetHeight(),nChannels);<br />ce.DeleteObject();</p><p>//step2:提取圖片中的特徵點<br /> IpVec ipts1, ipts2;<br /> surfDetDes(img1,ipts1,false,4,4,2,0.0002f);<br /> surfDetDes(img2,ipts2,false,4,4,2,0.0002f);</p><p>//step3:特徵點匹配<br /> IpPairVec matches;<br /> getMatches(ipts1,ipts2,matches);</p><p>//step4:畫出匹配的特徵點,並且連線<br />for (unsigned int i = 0; i < matches.size(); ++i)<br />{<br />drawPoint(img1,matches[i].first);<br />drawPoint(img2,matches[i].second);</p><p>int w = img1->width;<br />cvLine(img1,cvPoint(matches[i].first.x,matches[i].first.y),cvPoint(matches[i].second.x+w,matches[i].second.y), cvScalar(123,123,123),1);<br />cvLine(img2,cvPoint(matches[i].first.x-w,matches[i].first.y),cvPoint(matches[i].second.x,matches[i].second.y), cvScalar(123,123,123),1);<br />}</p><p>//畫到螢幕上<br />if(img1->height>img2->height)<br />{<br />gui.Show(img1,::GetDC(this->m_hWnd),0,0,img1->width,img1->height);<br />gui.Show(img2,::GetDC(this->m_hWnd),img1->width,img1->height-img2->height,img2->width,img2->height);<br />}<br />else<br />{<br />gui.Show(img1,::GetDC(this->m_hWnd),0,img2->height-img1->height,img1->width,img1->height);<br />gui.Show(img2,::GetDC(this->m_hWnd),img1->width,0,img2->width,img2->height);<br />}</p><p>}<br />
使用者可以根據本文的作業碼,在WINCE/WM平台上實現更多Opencv例子,不過,本文程式跑起來很慢(我用的是460MHz的K3方案 WM手機),因為只用標準C的Math做運算處理。在ARM9+DSP或者ARM11等手機上使用Opencv,建議在Opencv的運算部分用上這些手機的專用運算指令,這樣可以大大提高運算速度。