《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 模擬設(shè)計(jì) > 解決方案 > 移動(dòng)設(shè)備上使用opencv 1.10做圖像識(shí)別的例子

移動(dòng)設(shè)備上使用opencv 1.10做圖像識(shí)別的例子

2010-12-06

上次說(shuō)到了如何在WINCE/WM移植Opencv1.10,這次就說(shuō)說(shuō)如何在WM手機(jī)上使用裁剪移植后的Open1.10的例子,在opencv上使用OpenSURF(OpenSURF在GoogleCode的地址:http://code.google.com/p/opensurf1/),先來(lái)看看本文程序運(yùn)行的截圖: 

左圖為SURF算法找出的特征點(diǎn),右圖為兩個(gè)圖像相似特征點(diǎn)的匹配。

      本文的代碼可以到http://www.rayfile.com/zh-cn/files/da4d4edc-8af5-11df-9dac-0015c55db73d/這里下載,代碼里包含了自己實(shí)現(xiàn)的MyHighGUI類(lèi),用于轉(zhuǎn)換/繪制/保存IplImage圖像,也包含了同時(shí)支持WINCE/WIN32的第三方BMP操作類(lèi)庫(kù)----DIBSectionCE類(lèi)(詳見(jiàn)http://www.codeguru.com/cpp/w-p/ce/bitmapsandthegdi/article.php/c3),接下來(lái)就貼出部分操作代碼:

view plaincopy to clipboardprint?
//*****************************************************************  
//取得程序當(dāng)前文件夾路徑  
//****************************************************************  
CString GetCurrentDirectory()    
{    
    wchar_t pBuf[256];    
    GetModuleFileName(NULL,pBuf,sizeof(pBuf)/sizeof(wchar_t));    
    CString strPath(pBuf);    
    strPath = strPath.Left(strPath.ReverseFind(''\\'') + 1);    
    delete pBuf;  
    return strPath;  
}  
 
void CtestDlg::OnBnClickedButton1()  
{  
    //自定義的HighGUI,詳見(jiàn)MyHighGUI.h  
    MyHighGUI gui;  
    //網(wǎng)上的BMP操作類(lèi),支持WINCE/WIN32,地址:http://www.codeguru.com/cpp/w-p/ce/bitmapsandthegdi/article.php/c3   
    CDIBSectionCE ce;  
    //step1:讀取BMP,并轉(zhuǎn)換為IplImage格式  
    CString bmpPath=GetCurrentDirectory()+L"car1.bmp";  
    ce.Load(bmpPath);  
    int nChannels = ce.GetBitmapInfo()->bmiHeader.biBitCount /8 ;      
    IplImage* img = gui.BMP2Ipl((BYTE*)ce.GetDIBits(),ce.GetWidth(),ce.GetHeight(),nChannels);  
    ce.DeleteObject();  
 
    //step2:提取圖片中的特征點(diǎn)  
    IpVec ipts;  
    surfDetDes(img, ipts, false, 3, 4, 2, 0.0004f);  
 
    // step3:畫(huà)出特征點(diǎn)    
    drawIpoints(img, ipts);  
    gui.Show(img,::GetDC(this->m_hWnd),0,0,img->width,img->height);  
    //gui.WriteBmp(L"img33.bmp",(BYTE *)img->imageData,img->imageSize,img->width,img->height);  
     img=NULL;  
}  
 
void CtestDlg::OnBnClickedButton2()  
{  
    //自定義的HighGUI,詳見(jiàn)MyHighGUI.h  
    MyHighGUI gui;  
    //網(wǎng)上的BMP操作類(lèi),支持WINCE/WIN32,地址:http://www.codeguru.com/cpp/w-p/ce/bitmapsandthegdi/article.php/c3   
    CDIBSectionCE ce;  
    //step1:讀取BMP,并轉(zhuǎn)換為IplImage格式  
    CString bmpPath=GetCurrentDirectory()+L"car1.bmp";  
    ce.Load(bmpPath);  
    int nChannels = ce.GetBitmapInfo()->bmiHeader.biBitCount /8 ;      
    IplImage* img1 = gui.BMP2Ipl((BYTE*)ce.GetDIBits(),ce.GetWidth(),ce.GetHeight(),nChannels);  
    ce.DeleteObject();  
 
    bmpPath=GetCurrentDirectory()+L"car2.bmp";  
    ce.Load(bmpPath);  
    nChannels = ce.GetBitmapInfo()->bmiHeader.biBitCount /8 ;  
    IplImage* img2 = gui.BMP2Ipl((BYTE*)ce.GetDIBits(),ce.GetWidth(),ce.GetHeight(),nChannels);  
    ce.DeleteObject();  
 
    //step2:提取圖片中的特征點(diǎn)  
    IpVec ipts1, ipts2;  
    surfDetDes(img1,ipts1,false,4,4,2,0.0002f);  
    surfDetDes(img2,ipts2,false,4,4,2,0.0002f);  
 
    //step3:特征點(diǎn)匹配  
    IpPairVec matches;  
    getMatches(ipts1,ipts2,matches);  
 
    //step4:畫(huà)出匹配的特征點(diǎn),并且連線  
    for (unsigned int i = 0; i < matches.size(); ++i)  
    {  
        drawPoint(img1,matches[i].first);  
        drawPoint(img2,matches[i].second);  
        
        int w = img1->width;  
        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);  
        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);    
    }  
 
    //畫(huà)到屏幕上  
    if(img1->height>img2->height)  
    {     
        gui.Show(img1,::GetDC(this->m_hWnd),0,0,img1->width,img1->height);  
        gui.Show(img2,::GetDC(this->m_hWnd),img1->width,img1->height-img2->height,img2->width,img2->height);  
    }  
    else 
    {  
        gui.Show(img1,::GetDC(this->m_hWnd),0,img2->height-img1->height,img1->width,img1->height);  
        gui.Show(img2,::GetDC(this->m_hWnd),img1->width,0,img2->width,img2->height);  
    }  
 

//*****************************************************************
//取得程序當(dāng)前文件夾路徑
//****************************************************************
CString GetCurrentDirectory() 

 wchar_t pBuf[256]; 
 GetModuleFileName(NULL,pBuf,sizeof(pBuf)/sizeof(wchar_t)); 
 CString strPath(pBuf); 
 strPath = strPath.Left(strPath.ReverseFind(''\\'') + 1); 
 delete pBuf;
 return strPath;
}

void CtestDlg::OnBnClickedButton1()
{
 //自定義的HighGUI,詳見(jiàn)MyHighGUI.h
 MyHighGUI gui;
 //網(wǎng)上的BMP操作類(lèi),支持WINCE/WIN32,地址:http://www.codeguru.com/cpp/w-p/ce/bitmapsandthegdi/article.php/c3
 CDIBSectionCE ce;
 //step1:讀取BMP,并轉(zhuǎn)換為IplImage格式
 CString bmpPath=GetCurrentDirectory()+L"car1.bmp";
 ce.Load(bmpPath);
 int nChannels = ce.GetBitmapInfo()->bmiHeader.biBitCount /8 ; 
 IplImage* img = gui.BMP2Ipl((BYTE*)ce.GetDIBits(),ce.GetWidth(),ce.GetHeight(),nChannels);
    ce.DeleteObject();

 //step2:提取圖片中的特征點(diǎn)
 IpVec ipts;
 surfDetDes(img, ipts, false, 3, 4, 2, 0.0004f);

 // step3:畫(huà)出特征點(diǎn) 
 drawIpoints(img, ipts);
 gui.Show(img,::GetDC(this->m_hWnd),0,0,img->width,img->height);
 //gui.WriteBmp(L"img33.bmp",(BYTE *)img->imageData,img->imageSize,img->width,img->height);
  img=NULL;
}

void CtestDlg::OnBnClickedButton2()
{
 //自定義的HighGUI,詳見(jiàn)MyHighGUI.h
 MyHighGUI gui;
 //網(wǎng)上的BMP操作類(lèi),支持WINCE/WIN32,地址:http://www.codeguru.com/cpp/w-p/ce/bitmapsandthegdi/article.php/c3
 CDIBSectionCE ce;
 //step1:讀取BMP,并轉(zhuǎn)換為IplImage格式
 CString bmpPath=GetCurrentDirectory()+L"car1.bmp";
 ce.Load(bmpPath);
 int nChannels = ce.GetBitmapInfo()->bmiHeader.biBitCount /8 ; 
 IplImage* img1 = gui.BMP2Ipl((BYTE*)ce.GetDIBits(),ce.GetWidth(),ce.GetHeight(),nChannels);
 ce.DeleteObject();

 bmpPath=GetCurrentDirectory()+L"car2.bmp";
 ce.Load(bmpPath);
 nChannels = ce.GetBitmapInfo()->bmiHeader.biBitCount /8 ;
 IplImage* img2 = gui.BMP2Ipl((BYTE*)ce.GetDIBits(),ce.GetWidth(),ce.GetHeight(),nChannels);
 ce.DeleteObject();

 //step2:提取圖片中的特征點(diǎn)
    IpVec ipts1, ipts2;
    surfDetDes(img1,ipts1,false,4,4,2,0.0002f);
    surfDetDes(img2,ipts2,false,4,4,2,0.0002f);

 //step3:特征點(diǎn)匹配
    IpPairVec matches;
    getMatches(ipts1,ipts2,matches);

 //step4:畫(huà)出匹配的特征點(diǎn),并且連線
 for (unsigned int i = 0; i < matches.size(); ++i)
 {
  drawPoint(img1,matches[i].first);
  drawPoint(img2,matches[i].second);
  
  int w = img1->width;
  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);
  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); 
 }

 //畫(huà)到屏幕上
 if(img1->height>img2->height)
 { 
  gui.Show(img1,::GetDC(this->m_hWnd),0,0,img1->width,img1->height);
  gui.Show(img2,::GetDC(this->m_hWnd),img1->width,img1->height-img2->height,img2->width,img2->height);
 }
 else
 {
  gui.Show(img1,::GetDC(this->m_hWnd),0,img2->height-img1->height,img1->width,img1->height);
  gui.Show(img2,::GetDC(this->m_hWnd),img1->width,0,img2->width,img2->height);
 }

}
 

用戶可以根據(jù)本文的操作代碼,在WINCE/WM平臺(tái)上實(shí)現(xiàn)更多Opencv例子,不過(guò),本文程序跑起來(lái)很慢(我用的是460MHz的K3方案 WM手機(jī)),因?yàn)橹挥脴?biāo)準(zhǔn)C的Math做運(yùn)算處理。在ARM9+DSP或者ARM11等手機(jī)上使用Opencv,建議在Opencv的運(yùn)算部分用上這些手機(jī)的專(zhuān)用運(yùn)算指令,這樣可以大大提高運(yùn)算速度。

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,請(qǐng)及時(shí)通過(guò)電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。