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

一:基本原理

NCC是一种基于统计学计算两组样本数据相关性的算法,其取值范围为[-1, 1]之间,而对图像来说,每个像素点都可以看出是RGB数值,这样整幅图像就可以看成是一个样本数据的集合,如果它有一个子集与另外一个样本数据相互匹配则它的ncc值为1,表示相关性很高,如果是-1则表示完全不相关,基于这个原理,实现图像基于模板匹配识别算法,其中第一步就是要归一化数据,数学公式如下:

二:实现步骤

(1)      获取模板像素并计算均值与标准方差、像素与均值diff数据样本

(2)      根据模板大小,在目标图像上从左到右,从上到下移动窗口,计

算每移动一个像素之后窗口内像素与模板像素的ncc值,与阈值比较,大于

阈值则记录位置

(3)      根据得到位置信息,使用红色矩形标记出模板匹配识别结果。

(4)      UI显示结果

三:编程实现

基于JAVA语言完成了整个算法编程实现与演示,其中第一步的代码如下:

[java] view plaincopy
  1. int tw = template.getWidth();
  2. int th = template.getHeight();
  3. int[] tpixels = new int[tw * th];
  4. getRGB(template, 0, 0, tw, th, tpixels);
  5. for(int i=0; i<tpixels.length; i++)
  6. {
  7. tpixels[i] = (tpixels[i] >> 16) & 0xff;
  8. }
  9. double[] meansdev = getPixelsMeansAndDev(tpixels);
  10. double[] tDiff = calculateDiff(tpixels, meansdev[0]);
  11. int raidus_width = tw / 2;
  12. int raidus_height = th / 2;

第二步的实现代码如下:

[java] view plaincopy
  1. int[] windowPixels = new int[tw * th];
  2. Arrays.fill(windowPixels, 0);
  3. for (int row = 0; row < height; row++) {
  4. for (int col = 0; col < width; col++) {
  5. // calculate the means and dev for each window
  6. if(row <  raidus_height || (row + raidus_height) >= height)
  7. continue;
  8. if(col < raidus_width || (col + raidus_width) >= width)
  9. continue;
  10. int wrow = 0;
  11. Arrays.fill(windowPixels, 0);
  12. for(int subrow = -raidus_height; subrow <= raidus_height; subrow++ )
  13. {
  14. int wcol = 0;
  15. for(int subcol = -raidus_width; subcol <= raidus_width; subcol++ )
  16. {
  17. if(wrow >= th || wcol >= tw)
  18. {
  19. continue;
  20. }
  21. windowPixels[wrow * tw + wcol] = getPixelValue(width, col + subcol, row + subrow, inPixels);
  22. wcol++;
  23. }
  24. wrow++;
  25. }
  26. // calculate the ncc
  27. double[] _meansDev = getPixelsMeansAndDev(windowPixels);
  28. double[] diff = calculateDiff(windowPixels, _meansDev[0]);
  29. double ncc = calculateNcc(tDiff, diff, _meansDev[1], meansdev[1]);
  30. if(ncc > threhold) {
  31. Point mpoint = new Point();
  32. mpoint.x = col;
  33. mpoint.y  = row;
  34. points.add(mpoint);
  35. }
  36. }
  37. }

第三步的实现代码如下:

[java] view plaincopy
  1. // draw matched template on target image according position
  2. setRGB( dest, 0, 0, width, height, inPixels );
  3. Graphics2D g2d = dest.createGraphics();
  4. g2d.setPaint(Color.RED);
  5. g2d.setStroke(new BasicStroke(4));
  6. for(Point p : points)
  7. {
  8. g2d.drawRect(p.x - raidus_width, p.y - raidus_height, tw, th);
  9. }

其中第二步用到的计算NCC的方法实现如下:

[java] view plaincopy
  1. private double calculateNcc(double[] tDiff, double[] diff, double dev1, double dev2) {
  2. // TODO Auto-generated method stub
  3. double sum = 0.0d;
  4. double count = diff.length;
  5. for(int i=0; i<diff.length; i++)
  6. {
  7. sum += ((tDiff[i] * diff[i])/(dev1 * dev2));
  8. }
  9. return (sum / count);
  10. }

UI部分完整源代码如下:

[java] view plaincopy
  1. package com.gloomyfish.image.templae.match;
  2. import java.awt.BorderLayout;
  3. import java.awt.FlowLayout;
  4. import java.awt.Graphics;
  5. import java.awt.Graphics2D;
  6. import java.awt.event.ActionEvent;
  7. import java.awt.event.ActionListener;
  8. import java.awt.image.BufferedImage;
  9. import java.io.IOException;
  10. import javax.imageio.ImageIO;
  11. import javax.swing.JButton;
  12. import javax.swing.JComponent;
  13. import javax.swing.JFrame;
  14. import javax.swing.JPanel;
  15. public class DemoUI extends JComponent {
  16. /**
  17. *
  18. */
  19. private static final long serialVersionUID = 1L;
  20. private BufferedImage targetImage;
  21. private BufferedImage template;
  22. public DemoUI()
  23. {
  24. super();
  25. java.net.URL imageURL = this.getClass().getResource("words.png");
  26. java.net.URL templateURL = this.getClass().getResource("template.png");
  27. try {
  28. template = ImageIO.read(templateURL);
  29. targetImage = ImageIO.read(imageURL);
  30. } catch (IOException e) {
  31. e.printStackTrace();
  32. }
  33. }
  34. public void setTarget(BufferedImage target) {
  35. this.targetImage = target;
  36. }
  37. @Override
  38. protected void paintComponent(Graphics g) {
  39. Graphics2D g2 = (Graphics2D) g;
  40. if(targetImage != null) {
  41. g2.drawImage(targetImage, 10, 10, targetImage.getWidth(), targetImage.getHeight(), null);
  42. }
  43. if(template != null) {
  44. g2.drawImage(template, 20+targetImage.getWidth(), 10, template.getWidth(), template.getHeight(), null);
  45. }
  46. }
  47. public static void main(String[] args) {
  48. JFrame f = new JFrame("模板匹配与识别");
  49. JButton okBtn = new JButton("匹配");
  50. final DemoUI ui = new DemoUI();
  51. okBtn.addActionListener(new ActionListener() {
  52. @Override
  53. public void actionPerformed(ActionEvent e) {
  54. ui.process();
  55. }
  56. });
  57. JPanel btnPanel = new JPanel();
  58. btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
  59. btnPanel.add(okBtn);
  60. f.getContentPane().add(btnPanel, BorderLayout.SOUTH);
  61. f.getContentPane().add(ui, BorderLayout.CENTER);
  62. f.setSize(500, 500);
  63. f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  64. f.setVisible(true);
  65. }
  66. protected void process() {
  67. NccTemplateMatchAlg algo = new NccTemplateMatchAlg(template);
  68. targetImage = algo.filter(targetImage, null);
  69. this.repaint();
  70. }
  71. }

四:程序运行效果如下


其中左边是目标图像、右边为模板图像

PS:博客从10月份开始每月都有多篇相关图像处理文章更新

欢迎大家继续关注

图像处理之基于NCC模板匹配识别相关推荐

  1. matlab 图像模板匹配,基于MATLAB模板匹配的车牌识别系统

    一.课题名称[Q1321814823] 基于MATLAB模板匹配的车牌识别系统 二.课题背景 随着汽车数量的增加,城市交通状况日益受到人们的重视,如何进行有效的交通管理更是成为了人们关注的焦点.针对此 ...

  2. OpenCV与图像处理学习十六——模板匹配

    OpenCV与图像处理学习十六--模板匹配 一.模板匹配介绍 二.代码应用 一.模板匹配介绍 模板匹配是一种最原始.最基本的模式识别方法,研究某一特定目标的图像位于图像的什么地方,进而对图像进行定位. ...

  3. OpenCV模板匹配识别图片中的数字

    OpenCV模板匹配识别图片中的数字 前言 本博客主要实现利用OpenCV的模板匹配识别图像中的数字,然后把识别出来的数字输出到txt文件中,如果识别失败则输出"读取失败". 操作 ...

  4. 【数字图像处理与应用】模板匹配

    [数字图像处理与应用]模板匹配 题目 模板匹配原理 Matlab代码实现 算法介绍 显示图像的匹配结果 (最匹配的一个) MATLAB实现 运行结果 图像的相关值结果: 在原图像上绘制检测到的目标位置 ...

  5. 【字符识别】基于matlab模板匹配(区域生长法)字母+数字识别【含Matlab源码 1214期】

    ⛄一.手写大写字母识别技术简介 0 引言 在高校教学过程中,考试是最为普遍的一种教学评估.综合练习的教学手段,随着科技进步,考试阅卷的方式也发生了巨大的变革.传统的阅卷方式主要以人工阅卷为主, 存在效 ...

  6. 基于OCR模板匹配的手写英文字母数字识别matlab仿真

    目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 OCR技术中使用模板匹配法时首先要建立标准的模板字符库,接着将待识别字符图像与模板字符库中字符进行匹 ...

  7. 基于Matlab模板匹配方法的车牌识别系统设计

    本系统针对家庭小型车蓝底白字车牌进行识别 背景 近年来,随着交通现代化的发展要求,汽车牌照自动识别技术已经越来越受到人们的重视.车牌自动识别技术中车牌定位.字符切割.字符识别及后处理是其关键技术.由于 ...

  8. 数字图像处理:基于MATLAB的车牌识别项目

    学过了数字图像处理,就进行一个综合性强的小项目来巩固一下知识吧.前阵子编写调试了一套基于MATLAB的车牌识别的项目的代码.今天又重新改进了一下代码,识别的效果好一点了,也精简了一些代码.这里没有使用 ...

  9. OpenCV中使用模板匹配识别空闲的货架空间

    但是点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 假设你是一名在超市工作的员工,被要求在商店里四处走动,检查需要 ...

最新文章

  1. 使用cv2.Sobel()、cv2.Scharr()、cv2.Laplacian()寻找图像的梯度、边缘
  2. 【c语言】蓝桥杯算法训练 1的个数
  3. ida so 不root_十字符病毒,杀不死的小强,一次云服务器沦陷实录
  4. 如何在一天内被Google和百度收录
  5. linux dump命令 异机,Oracle 11.2.0.4 从单实例,使用RMAN 异机恢复到RAC
  6. postgresql 客户端_一款功能强大的数据库客户端:DataGrip
  7. 孜然导航系统 v2.3
  8. 一步步学习微软InfoPath2010和SP2010--第二章节--表单需求:使用决策矩阵(3)--你的SP版本...
  9. vue 图片被背景色覆盖_如何使用纯css3打造有点意思的故障艺术(附React/Vue加强组件版)...
  10. 【bzoj 2541】 [Ctsc2000]冰原探险(BFS)
  11. Acrobat Pro DC 教程,如何在 PDF 中添加和组织页面?
  12. mysql的int11是指什么_MYSQL中的int(11)到底代表什么意思?
  13. 如何采集企业信息公示系统
  14. Linux daemontools安装及使用
  15. PSM模型(价格敏感测试模型)
  16. 程序员在囧途之垃圾创业团队 .
  17. win7修改默认字体成xp宋体教程
  18. 读一个文本文件总是出现乱码怎么办
  19. wrapper.and的用法
  20. eslint 如何单独给一行取消eslint检查

热门文章

  1. linux 下screen命令
  2. Ubuntu下RMI Server 抛出java.rmi.ConnectException: Connection refused to host: 127.0.0.1解决办法
  3. Perl内置及特殊变量
  4. leetcode算法题--Integer to Roman
  5. javascript写贪吃蛇
  6. 用计算机计算线性卷积的基本规则,实验三_线性卷积与圆周卷积的计算.doc
  7. 采购订单模板_电子信息制造业解决方案,电子工业采购监管、管理、降本可控化...
  8. linux常用命令linux自动挂载WinXP系统下的分区
  9. Linux 用qmake快速生成makefile
  10. EJB实体Bean怎样和数据库中表关联?