最具影响力的数字化技术在线社区

168大数据

 找回密码
 立即注册

QQ登录

只需一步,快速开始

1 2 3 4 5
打印 上一主题 下一主题
开启左侧

58同城电话号码识别核心算法

[复制链接]
跳转到指定楼层
楼主
发表于 2014-7-13 12:14:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多数据大咖,获取更多知识干货,轻松玩转大数据

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
算法描述
基于要识别的图像生成01二维数组pixarr
将所有的模板读入内存
将所有的特征模板读入内存
将pixarr扫描一遍,去掉孤立点。(孤立点就是指其附近都是0的1点)
找到首次出现1的那一行,记为top,以后就在(top--->top+18)行的范围内识别
row=top  col=0
while(true)
  while(col列没出现1&&col<width)
    col++
  if(col==width)
   break
  以(top,col)为起点,沿着右和下的方向匹配每一个模板,找到吻合率最大的那个模板template0
  那么这块区域所代表的字符就应该是模板template0对应的字符
  if(该字符为'-'并且匹配率不等于1)
     表明匹配有误,往后倒退一列,基于特征模板进行匹配,为保险起见,最多只扫描三列
     将当前得到的字符修改为基于特征模板匹配得到的字符
     记录下该字符
     清理当前区域,为下一步迭代做准备
  else
     记录下该字符
     width0=模板template0的宽度
     以(top,col)为起点,沿着右和下的方向对比模板template0,将template0对应位置处的1置为0
     在(top,col)--->(top+18,col+width0-1)rectangle范围内以深度优先搜寻的方式递归遍历,每次找到一块连通区域,考察该区域
           如果该区域的最右边不超过rectangle右边框,把该区域所有1置为0


ShibiesimpleGraphical.java

  • package zhanlianyzm;
  • import java.awt.image.BufferedImage;
  • import java.io.File;
  • import java.io.IOException;
  • import javax.imageio.ImageIO;
  • public class ShibiesimpleGraphical {
  •         static int[][] pixarr = null;
  •         static boolean[][] vistedarr = null;
  •         static int[] dx = new int[8], dy = new int[8];// 方向数组
  •         static {
  •                 dx[0] = 0;
  •                 dy[0] = -1;
  •                 dx[1] = -1;
  •                 dy[1] = -1;
  •                 dx[2] = -1;
  •                 dy[2] = 0;
  •                 dx[3] = -1;
  •                 dy[3] = 1;
  •                 dx[4] = 0;
  •                 dy[4] = 1;
  •                 dx[5] = 1;
  •                 dy[5] = 1;
  •                 dx[6] = 1;
  •                 dy[6] = 0;
  •                 dx[7] = 1;
  •                 dy[7] = -1;
  •         }
  •         static void resetvistedarr() {
  •                 for (int row = 0; row < vistedarr.length; row++)
  •                         for (int col = 0; col < vistedarr[0].length; col++)
  •                                 vistedarr[row][col] = false;
  •         }
  •         static void makematrix(String imgfile) {
  •                 int plex = -1;
  •                 try {
  •                         BufferedImage img = ImageIO.read(new File(imgfile));
  •                         int width = img.getWidth(null);
  •                         int height = img.getHeight(null);
  •                         pixarr = new int[height][width];
  •                         System.out.println("width=" + width + " height=" + height);
  •                         for (int y = 0; y < height; y++) {
  •                                 for (int x = 0; x < width; x++) {
  •                                         plex = img.getRGB(x, y);
  •                                         if (plex == -1)
  •                                                 plex = 0;
  •                                         else
  •                                                 plex = 1;
  •                                         pixarr[y][x] = plex;
  •                                 }
  •                         }
  •                 } catch (IOException e) {
  •                         // TODO Auto-generated catch block
  •                         e.printStackTrace();
  •                 }
  •                 vistedarr = new boolean[pixarr.length][pixarr[0].length];
  •         }
  •         static int getfirst1row(int[][] a) {// 返回首次出现1的行下标,返回-1表示a中没有1
  •                 for (int i = 0; i < a.length; i++)
  •                         for (int j = 0; j < a[0].length; j++) {
  •                                 if (a[j] == 1)
  •                                         return i;
  •                         }
  •                 return -1;
  •         }
  •         static void displaymatrix(int[][] a) {
  •                 for (int row = 0; row < a.length; row++) {
  •                         for (int col = 0; col < a[0].length; col++)
  •                                 System.out.print(a[row][col] + " ");
  •                         System.out.println();
  •                 }
  •         }
  •         public static void shibie(String imgfile) {
  •                 makematrix(imgfile);// 基于图片生成01二维数组
  •                 displaymatrix(pixarr);
  •                 Template[] templatearr = MakeTemplate.maketemplate();// 将所有的模板读入内存,保存在templatearr中
  •                 int[][] matrix = templatearr[9].getMatrix();
  •                 // displaymatrix(matrix);
  •                 Templatefeature[] templatefeaturearr = MakeTemplatefeature
  •                                 .maketemplatefeature();
  •                 filteroutlier(pixarr); // 考察pixarr整体范围,过滤孤立点
  •                 int top = getfirst1row(pixarr); // 找到首次出现1的那一行
  •                 if (top == -1)
  •                         return;
  •                 int row = top, col = 0;
  •                 StringBuilder builder = new StringBuilder();
  •                 int debug = 0;
  •                 while (true) {
  •                         if (debug == 6)
  •                                 System.out.println();
  •                         debug++;
  •             boolean featurematch=false;
  •                         while (col < pixarr[0].length && !have1(col))
  •                                 col++;
  •                         if (col == pixarr[0].length)
  •                                 break;
  •                         int max = 0, ps = 0;
  •                         for (int i = 0; i < templatearr.length; i++) {// 以(top,col)为起点,循环匹配每一个模板
  •                                 int Consistent_rate = match(top, col, templatearr);
  •                                 if (Consistent_rate > max) {
  •                                         max = Consistent_rate;
  •                                         ps = i;
  •                                         // System.out.println("max:" + max);
  •                                 }
  •                         }
  •                         System.out.println("ch=" + templatearr[ps].getCh());
  •                         char ch = templatearr[ps].getCh();
  •                         if (ch == '-' && max != 100) {
  •                                 String result = null;
  •                                 for (int i = 0; i < templatefeaturearr.length; i++) {// 以(top,col-1)为起点,循环匹配每一个特征模板模板
  •                                         result = featurematch(top, col - 1, templatefeaturearr);// "12,53"
  •                                         if (result != null) {
  •                                                 ch = templatefeaturearr.getCh();
  •                                                 int firstfeaturepoint_row = templatefeaturearr
  •                                                                 .getFeatureps()[0][0];// 0
  •                                                 int firstfeaturepoint_col = templatefeaturearr
  •                                                                 .getFeatureps()[0][1];// 5
  •                                                 int orow = templatefeaturearr.getOrow(); // 5
  •                                                                                                                                         // firstfeaturepoint_row在ch模板中的相对位置
  •                                                 int ocol = templatefeaturearr.getOcol(); // 5
  •                                                                                                                                         // firstfeaturepoint_col在ch模板中的相对位置
  •                                                 String[] strarr = result.split("\\,");
  •                                                 int feature_startrow = Integer.parseInt(strarr[0]);
  •                                                 int feature_startcol = Integer.parseInt(strarr[1]);
  •                                                 int template_startrow = feature_startrow
  •                                                                 + firstfeaturepoint_row - orow;
  •                                                 int template_startcol = feature_startcol
  •                                                                 + firstfeaturepoint_col - ocol;
  •                                                 System.out.println(template_startrow + ","+ template_startcol);
  •                                                 Template template = null;
  •                                                 for (int im = 0; im < templatearr.length; im++) { // 寻找ch模板
  •                                                         template = templatearr[im];
  •                                                         if (template.getCh() == ch)
  •                                                                 break;
  •                                                 }
  •                                                 int width0=template.getWidth();
  •                                                 cleared(template_startrow, template_startcol, template.getMatrix(), ch); // 以(top,col)为起点,对比模板template0,将template0对应位置处的1置为0
  •                                                 filternoise(pixarr, template_startrow, template_startcol, template_startrow + 18, col + width0 - 1); // 扫描局部范围,过滤噪音
  •                                                 resetvistedarr();
  •                                                 System.out.println("过滤噪音后=========================================================================");
  •                                                 displaymatrix(pixarr);
  •                                                 featurematch=true;
  •                                                 break;
  •                                         }//end if (result != null)
  •                                 }//end for(int i = 0
  •                                 if (result == null)
  •                                         break;
  •                         }
  •                         builder.append(ch);// 当前阶段吻合率最大的模板是templatearr[ps],记下它所对应的字符
  •            if(featurematch)
  •                    continue;
  •                         int width0 = templatearr[ps].getWidth();
  •                         if (ch == '1')
  •                                 System.out.println();
  •                         displaymatrix(pixarr);
  •                         cleared(top, col, templatearr[ps].getMatrix(), ch); // 以(top,col)为起点,对比模板template0,将template0对应位置处的1置为0
  •                         System.out.println("=================================================================================");
  •                         System.out.println();
  •                         displaymatrix(pixarr);
  •                         // filteroutlier(pixarr, top, col, top + 18, col + width0 - 1); //
  •                         // 扫描局部范围,过滤孤立点
  •                         filternoise(pixarr, top, col, top + 18, col + width0 - 1); // 扫描局部范围,过滤噪音
  •                         resetvistedarr();
  •                         System.out.println("过滤噪音后=========================================================================");
  •                         displaymatrix(pixarr);
  •                 }
  •                 System.out.println(builder.toString());
  •         }
  •         private static String featurematch(int top, int col,
  •                         Templatefeature templatefeature) {// 按特征模板匹配,如果成功,则返回特征模板矩阵当时所处位置
  •                 int startcol = col;
  •                 int[][] pixmatrix = templatefeature.getMatrix();
  •                 int[][] featureps = templatefeature.getFeatureps();
  •                 int h = pixmatrix.length;
  •                 for (int x = col; x < col + 2; x++) {// 为保险起见,最多只扫描两列
  •                         for (int y = top; y <= top + 18 - h; y++) {
  •                                 if (scanmatch(y, x, pixmatrix, featureps))
  •                                         return y + "," + x;
  •                         }
  •                 }
  •                 return null;
  •         }
  •         private static boolean scanmatch(int y, int x, int[][] pixmatrix,
  •                         int[][] featureps) {// 从(y,x)起对比pixarr和pixmatrix,重点考察featureps所表示的点是否匹配
  •                 for (int p = 0; p < featureps.length; p++) {
  •                         int row = featureps[p][0];// 行
  •                         int col = featureps[p][1];// 列
  •                         if (pixmatrix[row][col] != pixarr[row + y][col + x])
  •                                 return false;
  •                 }
  •                 return true;
  •         }
  •         static int localtop = 0, localleft = 0, localbottom = 0, localright = 0;
  •         private static void filternoise(int[][] pixarr, int top, int left,int bottom, int right) {// 扫描局部范围,过滤噪音
  •                 for (int row = top; row <= bottom; row++)
  •                         for (int col = left; col <= right; col++) {
  •                                 if (pixarr[row][col] == 1) {
  •                                         if (vistedarr[row][col])
  •                                                 continue;
  •                                         localtop = row;
  •                                         localleft = col;
  •                                         localbottom = row;
  •                                         localright = col;
  •                                         int localtop0 = localtop, localleft0 = localleft;
  •                                         int localbottom0 = localbottom, localright0 = localright;
  •                                         dfsTraversal(row, col, top, left, bottom);// 以(row,col)点为起点,在该局部范围内,找到一块连通区域
  •                                         /*
  •                                          * if(localtop==localtop0&&localleft0==localleft&&localbottom0==localbottom&&localright0==localright)
  •                                          * continue;
  •                                          */
  •                                         if (localright <= right) {// 如果该区域的最右边不超过rectangle右边框,把该区域所有1置为0
  •                                                 for (int y = localtop; y <= localbottom; y++)
  •                                                         for (int x = localleft; x <= localright; x++)
  •                                                                 pixarr[y][x] = 0;
  •                                         }
  •                                 }
  •                         }
  •         }
  •         private static void dfsTraversal(int row, int col, int top, int left,
  •                         int bottom) {// 以(row,col)点为起点,深度优先遍历找到一块连通区域
  •                 for (int i = 0; i < dx.length; i++) {// 分别往5个方向测探,上边的方向之前已经扫描处理过了,可以不必再考虑
  •                         int row_1 = row + dy;
  •                         int col_1 = col + dx;
  •                         // if(row_1 <top || row > bottom || col_1 < left)
  •                         // continue;
  •                         if (vistedarr[row_1][col_1])
  •                                 continue;
  •                         vistedarr[row_1][col_1] = true;
  •                         if (pixarr[row_1][col_1] == 1) {
  •                                 if (row_1 > localbottom)
  •                                         localbottom = row_1;
  •                                 if (col_1 < localleft)
  •                                         localleft = col_1;
  •                                 if (col_1 > localright)
  •                                         localright = col_1;
  •                                 dfsTraversal(row_1, col_1, top, left, bottom);
  •                         }
  •                 }
  •         }
  •         private static void filteroutlier(int[][] pixarr) {
  •                 filteroutlier(pixarr, 0, 0, pixarr.length - 1, pixarr[0].length - 1);
  •         }
  •         private static void filteroutlier(int[][] pixarr, int top, int left,
  •                         int bottom, int right) {// 扫描pixarr局部,去掉孤立点
  •                 for (int row = top; row <= bottom; row++)
  •                         for (int col = left; col <= right; col++) {
  •                                 changepoint(pixarr, top, left, bottom, right, row, col);
  •                         }
  •         }
  •         private static void changepoint(int[][] pixarr, int top, int left,
  •                         int bottom, int right, int row, int col) {
  •                 if (pixarr[row][col] == 0)
  •                         return;
  •                 boolean have1 = false;
  •                 for (int i = 0; i < dx.length; i++) {// 测探八个方向存在1否?
  •                         int row_1 = row + dy;
  •                         int col_1 = col + dx;
  •                         if (row_1 >= top && row <= bottom && col_1 >= left
  •                                         && col_1 <= right) {
  •                                 if (pixarr[row_1][col_1] == 1) {
  •                                         have1 = true;
  •                                         break;
  •                                 }
  •                         }
  •                 }
  •                 if (!have1)
  •                         pixarr[row][col] = 0;
  •         }
  •         private static void cleared(int top, int left, int[][] matrix, char ch) {// 以(top,left)为起点,对比矩阵matrix,将matrix为1的点与pixarr对应位置处的数值置为0
  •                 for (int row = 0; row < matrix.length; row++)
  •                         for (int col = 0; col < matrix[0].length; col++) {
  •                                 if (ch == '8'
  •                                                 && ((row == 18 && col == 7) || (row == 12 && col == 9)))
  •                                         System.out.println();
  •                                 if (matrix[row][col] == 1)
  •                                         pixarr[row + top][col + left] = 0;
  •                         }
  •         }
  •         private static int match(int top, int left, Template template) {// 以(top,left)为起点,匹配模板template,返回吻合率
  •                 int[][] matrix = template.getMatrix();
  •                 double sum = 0.0;
  •                 for (int row = 0; row < matrix.length; row++)
  •                         for (int col = 0; col < matrix[0].length; col++) {
  •                                 if (matrix[row][col] == pixarr[top + row][left + col])
  •                                         sum++;
  •                         }
  •                 // System.out.println("sum="+sum);
  •                 return (int) (sum * 100 / (matrix.length * matrix[0].length));
  •         }
  •         private static boolean have1(int col) {//
  •                 int sum = 0;
  •                 int firstrow = 0;
  •                 for (int row = 0; row < pixarr.length; row++)
  •                         if (pixarr[row][col] == 1) { // return true;
  •                                 if (firstrow == 0)
  •                                         firstrow = row;
  •                                 sum++;
  •                         }
  •                 if (sum == 0)
  •                         return false;
  •                 else {
  •                         if (sum == 1 && firstrow > 9) {
  •                                 pixarr[firstrow][col] = 0;
  •                                 return false;
  •                         }
  •                         return true;
  •                 }
  •         }
  •         public static void main(String[] args) {
  •                 String imgfile = "D:/58同城/8.gif";
  •                 shibie(imgfile);
  •         }
  • }


[color=rgb(51, 102, 153) !important]复制代码




楼主热帖
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 赞 踩

168大数据 - 论坛版权1.本主题所有言论和图片纯属网友个人见解,与本站立场无关
2.本站所有主题由网友自行投稿发布。若为首发或独家,该帖子作者与168大数据享有帖子相关版权。
3.其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和168大数据的同意,并添加本文出处。
4.本站所收集的部分公开资料来源于网络,转载目的在于传递价值及用于交流学习,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
5.任何通过此网页连接而得到的资讯、产品及服务,本站概不负责,亦不负任何法律责任。
6.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源,若标注有误或遗漏而侵犯到任何版权问题,请尽快告知,本站将及时删除。
7.168大数据管理员和版主有权不事先通知发贴者而删除本文。

沙发
发表于 2014-7-13 12:46:57 | 只看该作者
写的真的很不错
板凳
发表于 2014-7-15 18:13:31 | 只看该作者
路过,支持一下啦
地板
发表于 2014-7-15 21:09:35 | 只看该作者
写的真的很不错
5#
发表于 2014-7-15 21:46:16 | 只看该作者
过来看看的
6#
发表于 2014-7-16 13:50:47 | 只看该作者
有竞争才有进步嘛
7#
发表于 2014-7-16 14:39:34 | 只看该作者
帮帮顶顶!!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

关于我们|小黑屋|Archiver|168大数据 ( 京ICP备14035423号|申请友情链接

GMT+8, 2024-5-8 09:32

Powered by BI168大数据社区

© 2012-2014 168大数据

快速回复 返回顶部 返回列表