击中击不中变换

来源:互联网 发布:iphone5susb共享网络 编辑:程序博客网 时间:2024/04/19 20:48

击中击不中变换

标签: nulldeletecommand扩展工具测试
 4881人阅读 评论(1) 收藏 举报
 分类:

  击中击不中变换:形态学中用来检测形状的一个基本工具;检测不应该只限于形状,还有大小;我这里只写了二值图像的,对于灰度图还没试过;

  它的原理就是使用腐蚀;如果要在一幅图像A上找到B形状的目标,我们要做的是:

首先,建立一个比B大的模板W;使用此模板对图像A进行腐蚀,得到图像假设为Process1;

其次,用B减去W,从而得到V模板(W-B);使用V模板对图像A的补集进行腐蚀,得到图像假设为Process2;

然后,Process1与Process2取交集;得到的结果就是B的位置。这里的位置可能不是B的中心位置,要视W-B时对齐的位置而异;

  其实很简单,两次腐蚀,然后交集,结果就出来了;下面把我的处理的图像贴出来,见下。为了方便起见,本次处理我没有使用模板图像,代之以模板数据,当然了代码很乱;可能的话直接使用一幅模板图像会更好,更通用。关于代码,一会也贴下面,没有新建类,直接在一个函数中给处理了;

 

处理图像

 

处理后,形状检测的结果是一个点,但是太小了,我这里给加粗了!

 

形状检测

 

本次测试没有使用三角形,椭圆等,其实本质上都一样。。。。。。

 

关于代码,因为没有加新类,所以把那个函数放出来:

[cpp] view plaincopy
  1. void CMyDIPView::OnMophoHit()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.     CMyDIPDoc* pDoc = GetDocument();  
  5.     unsigned char *lpSrc=NULL,*lpDest=NULL,*lpDest1=NULL,*lpDest2=NULL;  
  6.     int i,j;  
  7.       
  8.     int nWidth=21,nHeight=21;  
  9.       
  10.     int nWidthExtend=5,nHeightExtend=5;    //搜索窗口扩展象素  
  11.     int *pTemplet=NULL,*pTemplet1=NULL;  
  12.       
  13.     ASSERT_VALID(pDoc);  
  14.     if(pDoc->m_hDIB == NULL)  
  15.         return ;  
  16.     LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->m_hDIB);  
  17.     LPSTR lpDIBBits=::FindDIBBits (lpDIB);  
  18.     int cxDIB = (int) ::DIBWidth(lpDIB);         // Size of DIB - x  
  19.     int cyDIB = (int) ::DIBHeight(lpDIB);        // Size of DIB - y  
  20.     long lLineBytes = WIDTHBYTES(cxDIB * 8);     // 计算图像每行的字节数  
  21.   
  22.     CExpend ce;  
  23.     ce.SetSrcImage(lpDIBBits);  
  24.     ce.SetWidthHeight(cxDIB,cyDIB);  
  25.       
  26.     pTemplet=new int[nWidth*nHeight];  
  27.   
  28.     for(i=0;i<nWidth*nHeight;i++)  
  29.     {  
  30.         pTemplet[i]=1;  
  31.     }  
  32.           
  33.     ce.SetTemplet(pTemplet,nWidth,nHeight);  
  34.   
  35.     ce.Process(false);  
  36.     lpDest=(unsigned char*)ce.GetDestImage();  
  37.     //第一次腐蚀的结果,保存起来  
  38.     lpDest1=new unsigned char [cxDIB*cyDIB];  
  39.     memcpy(lpDest1,lpDest,cxDIB*cyDIB);  
  40.   
  41.     for(i = 0; i < cyDIB; i++)  
  42.     {  
  43.         // 每列  
  44.         for(j = 0; j < cxDIB; j++)  
  45.         {  
  46.             // 指向DIB第i行,第j个象素的指针  
  47.             lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;  
  48.             *lpSrc=lpDest[i*lLineBytes+j];  
  49.         }  
  50.     }  
  51.   
  52.       
  53.   
  54.     //第二次腐蚀  
  55.     //先对图像进行反转,也就是求补  
  56.       
  57.     for(i = 0; i < cyDIB; i++)  
  58.     {  
  59.         // 每列  
  60.         for(j = 0; j < cxDIB; j++)  
  61.         {  
  62.             // 指向DIB第i行,第j个象素的指针  
  63.             lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;  
  64.             *lpSrc=255-*lpSrc;  
  65.         }  
  66.     }  
  67.   
  68.   
  69.     int nW,nH;  
  70.       
  71.     pTemplet1=new int[(nWidth+nWidthExtend*2)*(nHeight+nHeightExtend*2)];  
  72.   
  73.     for(i=0;i<(nWidth+nWidthExtend*2)*(nHeight+nHeightExtend*2);i++)  
  74.     {  
  75.         nH=i/(nWidth+nWidthExtend*2);    //求得矩阵坐标  
  76.         nW=i%(nWidth+nWidthExtend*2);  
  77.           
  78.         if(abs(nW-(nWidth+nWidthExtend*2)/2)>nWidthExtend||  
  79.             abs(nH-(nHeight+nHeightExtend*2)/2)>nHeightExtend)  
  80.         {//扩展象素部分  
  81.             pTemplet1[i]=1;  
  82.         }  
  83.         else  
  84.             pTemplet1[i]=0;  
  85.     }  
  86.       
  87.     pTemplet1[(nWidth+nWidthExtend*2)*(nHeight+nHeightExtend*2)/2]=1;  
  88.           
  89.     ce.SetTemplet(pTemplet1,(nWidth+nWidthExtend*2),(nHeight+nHeightExtend*2));  
  90.   
  91.     ce.Process(false);  
  92.     lpDest=(unsigned char*)ce.GetDestImage();  
  93.     /* 
  94.     // 每行 
  95.     for(i = 0; i < cyDIB; i++) 
  96.     { 
  97.         // 每列 
  98.         for(j = 0; j < cxDIB; j++) 
  99.         { 
  100.             // 指向DIB第i行,第j个象素的指针 
  101.             lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j; 
  102.             *lpSrc=lpDest[i*lLineBytes+j]; 
  103.         } 
  104.     }*/  
  105.   
  106.     //第二次腐蚀的结果,保存起来  
  107.     lpDest2=new unsigned char [cxDIB*cyDIB];  
  108.     memcpy(lpDest2,lpDest,cxDIB*cyDIB);  
  109.   
  110.   
  111.     //把二次结果取交集  
  112.       
  113.     //显示击中的结果  
  114.     // 每行  
  115.     for(i = 0; i < cyDIB; i++)  
  116.     {  
  117.         // 每列  
  118.         for(j = 0; j < cxDIB; j++)  
  119.         {  
  120.             // 指向DIB第i行,第j个象素的指针  
  121.                 lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;  
  122.                 if(lpDest1[i*lLineBytes+j]==0&&lpDest2[i*lLineBytes+j]==0)  
  123.                     *lpSrc=0;  
  124.                 else  
  125.                     *lpSrc=255;  
  126.         }  
  127.     }  
  128.       
  129.     ::GlobalUnlock((HGLOBAL) pDoc->m_hDIB);  
  130.     Invalidate(TRUE);  
  131.   
  132.     if(lpDest1)  
  133.     {  
  134.         delete []lpDest1;  
  135.         lpDest1=NULL;  
  136.     }  
  137.       
  138.     if(lpDest2)  
  139.     {  
  140.         delete []lpDest2;  
  141.         lpDest2=NULL;  
  142.     }  
  143.   
  144.     if(pTemplet)  
  145.     {  
  146.         delete []pTemplet;  
  147.         pTemplet=NULL;  
  148.     }  
  149.   
  150.     if(pTemplet1)  
  151.     {  
  152.         delete []pTemplet1;  
  153.         pTemplet1=NULL;  
  154.     }  
  155.   
  156. }  

 

好了,就到这里了,大家新年快乐!

  

0 0
原创粉丝点击