日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

图像处理之基于NCC模板匹配识别

發布時間:2025/7/25 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图像处理之基于NCC模板匹配识别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

圖像處理之基于NCC模板匹配識別


一:基本原理

NCC是一種基于統計學計算兩組樣本數據相關性的算法,其取值范圍為[-1, 1]之間,而對圖像來說,每個像素點都可以看出是RGB數值,這樣整幅圖像就可以看成是一個樣本數據的集合,如果它有一個子集與另外一個樣本數據相互匹配則它的ncc值為1,表示相關性很高,如果是-1則表示完全不相關,基于這個原理,實現圖像基于模板匹配識別算法,其中第一步就是要歸一化數據,數學公式如下:


二:實現步驟

(1)??????獲取模板像素并計算均值與標準方差、像素與均值diff數據樣本

(2)??????根據模板大小,在目標圖像上從左到右,從上到下移動窗口,計

算每移動一個像素之后窗口內像素與模板像素的ncc值,與閾值比較,大于

閾值則記錄位置

(3)??????根據得到位置信息,使用紅色矩形標記出模板匹配識別結果。

(4)??????UI顯示結果

?

三:編程實現

基于JAVA語言完成了整個算法編程實現與演示,其中第一步的代碼如下:

[java] view plaincopy
  • int?tw?=?template.getWidth();??
  • int?th?=?template.getHeight();??
  • int[]?tpixels?=?new?int[tw?*?th];??
  • getRGB(template,?0,?0,?tw,?th,?tpixels);??
  • for(int?i=0;?i<tpixels.length;?i++)??
  • {??
  • ????tpixels[i]?=?(tpixels[i]?>>?16)?&?0xff;??
  • }??
  • double[]?meansdev?=?getPixelsMeansAndDev(tpixels);??
  • double[]?tDiff?=?calculateDiff(tpixels,?meansdev[0]);??
  • int?raidus_width?=?tw?/?2;??
  • int?raidus_height?=?th?/?2;??
  • 第二步的實現代碼如下:

    [java] view plaincopy
  • int[]?windowPixels?=?new?int[tw?*?th];??
  • Arrays.fill(windowPixels,?0);??
  • for?(int?row?=?0;?row?<?height;?row++)?{??
  • ????for?(int?col?=?0;?col?<?width;?col++)?{??
  • ????????//?calculate?the?means?and?dev?for?each?window??
  • ????????if(row?<??raidus_height?||?(row?+?raidus_height)?>=?height)??
  • ????????????continue;??
  • ????????if(col?<?raidus_width?||?(col?+?raidus_width)?>=?width)???
  • ????????????continue;??
  • ????????int?wrow?=?0;??
  • ????????Arrays.fill(windowPixels,?0);??
  • ????????for(int?subrow?=?-raidus_height;?subrow?<=?raidus_height;?subrow++?)??
  • ????????{??
  • ????????????int?wcol?=?0;??
  • ????????????for(int?subcol?=?-raidus_width;?subcol?<=?raidus_width;?subcol++?)??
  • ????????????{??
  • ????????????????if(wrow?>=?th?||?wcol?>=?tw)??
  • ????????????????{??
  • ????????????????????continue;??
  • ????????????????}??
  • ????????????????windowPixels[wrow?*?tw?+?wcol]?=?getPixelValue(width,?col?+?subcol,?row?+?subrow,?inPixels);??
  • ????????????????wcol++;??
  • ????????????}??
  • ????????????wrow++;??
  • ????????}??
  • ????????//?calculate?the?ncc??
  • ????????double[]?_meansDev?=?getPixelsMeansAndDev(windowPixels);??
  • ????????double[]?diff?=?calculateDiff(windowPixels,?_meansDev[0]);??
  • ????????double?ncc?=?calculateNcc(tDiff,?diff,?_meansDev[1],?meansdev[1]);??
  • ????????if(ncc?>?threhold)?{??
  • ????????????Point?mpoint?=?new?Point();??
  • ????????????mpoint.x?=?col;??
  • ????????????mpoint.y??=?row;??
  • ????????????points.add(mpoint);??
  • ????????}??
  • ????}??
  • }??
  • 第三步的實現代碼如下:

    [java] view plaincopy
  • //?draw?matched?template?on?target?image?according?position??
  • setRGB(?dest,?0,?0,?width,?height,?inPixels?);??
  • Graphics2D?g2d?=?dest.createGraphics();??
  • g2d.setPaint(Color.RED);??
  • g2d.setStroke(new?BasicStroke(4));??
  • for(Point?p?:?points)??
  • {??
  • ????g2d.drawRect(p.x?-?raidus_width,?p.y?-?raidus_height,?tw,?th);??
  • }??
  • 其中第二步用到的計算NCC的方法實現如下:

    [java] view plaincopy
  • private?double?calculateNcc(double[]?tDiff,?double[]?diff,?double?dev1,?double?dev2)?{??
  • ????//?TODO?Auto-generated?method?stub??
  • ????double?sum?=?0.0d;??
  • ????double?count?=?diff.length;??
  • ????for(int?i=0;?i<diff.length;?i++)??
  • ????{??
  • ????????sum?+=?((tDiff[i]?*?diff[i])/(dev1?*?dev2));??
  • ????}??
  • ????return?(sum?/?count);??
  • }??
  • UI部分完整源代碼如下:

    [java] view plaincopy
  • package?com.gloomyfish.image.templae.match;??
  • ??
  • import?java.awt.BorderLayout;??
  • import?java.awt.FlowLayout;??
  • import?java.awt.Graphics;??
  • import?java.awt.Graphics2D;??
  • import?java.awt.event.ActionEvent;??
  • import?java.awt.event.ActionListener;??
  • import?java.awt.image.BufferedImage;??
  • import?java.io.IOException;??
  • ??
  • import?javax.imageio.ImageIO;??
  • import?javax.swing.JButton;??
  • import?javax.swing.JComponent;??
  • import?javax.swing.JFrame;??
  • import?javax.swing.JPanel;??
  • ??
  • public?class?DemoUI?extends?JComponent?{??
  • ??????
  • ????/**?
  • ?????*??
  • ?????*/??
  • ????private?static?final?long?serialVersionUID?=?1L;??
  • ????private?BufferedImage?targetImage;??
  • ????private?BufferedImage?template;??
  • ??????
  • ????public?DemoUI()??
  • ????{??
  • ????????super();??
  • ????????java.net.URL?imageURL?=?this.getClass().getResource("words.png");??
  • ????????java.net.URL?templateURL?=?this.getClass().getResource("template.png");??
  • ??????????
  • ????????try?{??
  • ????????????template?=?ImageIO.read(templateURL);??
  • ????????????targetImage?=?ImageIO.read(imageURL);??
  • ????????}?catch?(IOException?e)?{??
  • ????????????e.printStackTrace();??
  • ????????}??
  • ????}??
  • ??????
  • ????public?void?setTarget(BufferedImage?target)?{??
  • ????????this.targetImage?=?target;??
  • ????}??
  • ??
  • ????@Override??
  • ????protected?void?paintComponent(Graphics?g)?{??
  • ????????Graphics2D?g2?=?(Graphics2D)?g;??
  • ????????if(targetImage?!=?null)?{??
  • ????????????g2.drawImage(targetImage,?10,?10,?targetImage.getWidth(),?targetImage.getHeight(),?null);??
  • ????????}??
  • ????????if(template?!=?null)?{??
  • ????????????g2.drawImage(template,?20+targetImage.getWidth(),?10,?template.getWidth(),?template.getHeight(),?null);??
  • ????????}??
  • ????}??
  • ??????
  • ????public?static?void?main(String[]?args)?{??
  • ????????JFrame?f?=?new?JFrame("模板匹配與識別");??
  • ????????JButton?okBtn?=?new?JButton("匹配");??
  • ????????final?DemoUI?ui?=?new?DemoUI();??
  • ????????okBtn.addActionListener(new?ActionListener()?{??
  • ??
  • ????????????@Override??
  • ????????????public?void?actionPerformed(ActionEvent?e)?{??
  • ??????????????????
  • ????????????????ui.process();??
  • ????????????}??
  • ????????});??
  • ??????????
  • ????????JPanel?btnPanel?=?new?JPanel();??
  • ????????btnPanel.setLayout(new?FlowLayout(FlowLayout.RIGHT));??
  • ????????btnPanel.add(okBtn);??
  • ??????????
  • ????????f.getContentPane().add(btnPanel,?BorderLayout.SOUTH);??
  • ????????f.getContentPane().add(ui,?BorderLayout.CENTER);??
  • ????????f.setSize(500,?500);??
  • ????????f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);??
  • ????????f.setVisible(true);??
  • ????}??
  • ??
  • ????protected?void?process()?{??
  • ????????NccTemplateMatchAlg?algo?=?new?NccTemplateMatchAlg(template);??
  • ????????targetImage?=?algo.filter(targetImage,?null);??
  • ????????this.repaint();??
  • ????}??
  • ??
  • }??
  • 四:程序運行效果如下


    其中左邊是目標圖像、右邊為模板圖像

    PS:博客從10月份開始每月都有多篇相關圖像處理文章更新

    歡迎大家繼續關注


    總結

    以上是生活随笔為你收集整理的图像处理之基于NCC模板匹配识别的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。