【影象處理】C++實現模板匹配
阿新 • • 發佈:2019-02-12
////////////////////////////////////////////////////////////////////////// //預先判斷——3*3十字中心——區域是否相似,如果相似,則再匹配判斷。這樣可以減少判斷次數。 //前提:模板大於9*9 BOOL Judgement(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth); //預先判斷 /* //模板匹配: //複製影象上的一塊模板大小的區域,與模板進行匹配,返回目標物的型別的資料;(點,則返回ShapePoint) //引數:BYTE *pTempDataBuf —— 從影象上覆制模板大小的塊 BYTE *pTemplateBuf —— 模板資料 int nTempHeight —— 模板高 int nTempWidth —— 模板寬 int LeftDev —— 模板中邊界與目標點的左偏量 int RightDev—— 模板中邊界與目標點的右偏量 */ //用來判斷是否匹配成功 BOOL TemplateMatch_SSD(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth);//畫素差平方和匹配 BOOL TemplateMatch_CC(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth);//互相關匹配 BOOL TemplateMatch_NCC(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth);//歸一化互相關匹配
//畫素差平方和匹配 BOOL CTemplateMatching::TemplateMatch_SSD(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth) { int m,n; double dSSD = 0;//差平方和 unsigned char tempDatapixel;//畫素值 unsigned char templatepixel; for (m=0; m<nTemplateHeight; m++) { for(n=0; n<nTemplateWidth; n++) { tempDatapixel = pTempDataBuf[TPos(m,n)];//模板塊畫素 templatepixel = pTemplateBuf[TPos(m,n)];//模板畫素 dSSD += (double)(tempDatapixel - templatepixel)*(tempDatapixel - templatepixel); //模板塊與模板裡,所有畫素值的平方和 } } if (dSSD < 100) //SSD測度的臨界值 return 1; else return 0; } //互相關匹配 BOOL CTemplateMatching::TemplateMatch_CC(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth) { int m,n; double dSigmaST = 0;//中間結果——pTempDataBuf與pTemplateBuf乘積和 double dSigmaS = 0; //中間結果——pTempDataBuf平方和 double dSigmaT = 0; //中間結果——pTemplateBuf平方和 double R = 0;//相似性測度 unsigned char tempDatapixel;//畫素值 unsigned char templatepixel; for (m=0; m<nTemplateHeight; m++) { for(n=0; n<nTemplateWidth; n++) { tempDatapixel = pTempDataBuf[TPos(m,n)];//模板塊畫素 templatepixel = pTemplateBuf[TPos(m,n)];//模板畫素 dSigmaS += (double)tempDatapixel*tempDatapixel; //模板塊裡,所有畫素值的平方和 dSigmaT += (double)templatepixel*templatepixel; //模板裡,所有畫素值的平方和 dSigmaST += (double)tempDatapixel*templatepixel; //模板塊與模板裡,所有畫素值的平方和 } } R = dSigmaST/(sqrt(dSigmaT)*sqrt(dSigmaS));//相似性測度公式 if (R > 0.85) //相似性測度的臨界值 return 1; else return 0; } //歸一化互相關匹配 BOOL CTemplateMatching::TemplateMatch_NCC(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth) { int m,n; double dSumST = 0;//中間結果——(Sxy - S')*(Txy - T')之和 double dSumS = 0; //中間結果——(Sxy - S')平方和 double dSumT = 0; //中間結果——(Txy - T')平方和 double dSPixelSum = 0; double dTPixelSum = 0; double dNCC = 0;//歸一化相似測度 unsigned char tempDatapixel;//畫素值 unsigned char templatepixel; unsigned char AveraryDatapixel; //pTempDataBuf平均值 unsigned char AveraryTemplatepixel;//pTemplateBuf平均值 for (m=0; m<nTemplateHeight; m++) { for(n=0; n<nTemplateWidth; n++) { tempDatapixel = pTempDataBuf[TPos(m,n)];//模板塊畫素 templatepixel = pTemplateBuf[TPos(m,n)];//模板畫素 dSPixelSum += tempDatapixel; dTPixelSum += templatepixel; } } AveraryDatapixel = (unsigned char)dSPixelSum/(nTemplateHeight*nTemplateWidth); AveraryTemplatepixel = (unsigned char)dTPixelSum/(nTemplateHeight*nTemplateWidth); for (m=0; m<nTemplateHeight; m++) { for(n=0; n<nTemplateWidth; n++) { tempDatapixel = pTempDataBuf[TPos(m,n)];//模板塊畫素 templatepixel = pTemplateBuf[TPos(m,n)];//模板畫素 dSumS += (double)(tempDatapixel - AveraryDatapixel)*(tempDatapixel - AveraryDatapixel); dSumT += (double)(templatepixel - AveraryTemplatepixel)*(templatepixel - AveraryTemplatepixel); dSumST += (double)(tempDatapixel - AveraryDatapixel)*(templatepixel - AveraryTemplatepixel); } } dNCC = dSumST/(sqrt(dSumS)*sqrt(dSumT)); ////歸一化相似測度公式 if (dNCC > 0.85) //相似性測度的臨界值 return 1; else return 0; } ////////////////////////////////////////////////////////////////////////// /* //預先判斷——3*3十字中心——區域是否相似,如果相似,則再匹配判斷。這樣可以減少判斷次數。 //前提:模板大於9*9 */ BOOL CTemplateMatching::Judgement(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth) { int m,n; double dSum = 0; int H = 0;//寬高都分成四份,一份的高度 int W = 0;//一份的寬度 H = nTemplateHeight/4; W = nTemplateWidth/4; //第一個3*3(上) for (m=H-1;m<H+2;m++) { for (n=2*W-1;n<2*W+2;n++) { if (pTempDataBuf[TPos(m,n)] == pTemplateBuf[TPos(m,n)]) dSum++; } } //第二個3*3(左) for (m=2*H-1;m<2*H+2;m++) { for (n=W-1;n<W+2;n++) { if (pTempDataBuf[TPos(m,n)] == pTemplateBuf[TPos(m,n)]) dSum++; } } //第三個3*3(中) for (m=2*H-1;m<2*H+2;m++) { for (n=2*W-1;n<2*W+2;n++) { if (pTempDataBuf[TPos(m,n)] == pTemplateBuf[TPos(m,n)]) dSum++; } } //第四個3*3(右) for (m=2*H-1;m<2*H+2;m++) { for (n=3*W-1;n<3*W+2;n++) { if (pTempDataBuf[TPos(m,n)] == pTemplateBuf[TPos(m,n)]) dSum++; } } //第五個3*3(下) for (m=3*H-1;m<3*H+2;m++) { for (n=2*W-1;n<2*W+2;n++) { if (pTempDataBuf[TPos(m,n)] == pTemplateBuf[TPos(m,n)]) dSum++; } } //判斷條件,達到要求,則表示預匹配準確,反之,預匹配失敗,進行下個模板匹配 if (dSum >= (5-1)*9) //全部個數3*3*5 return 1; else return 0; }