首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >以最大概率从名片中提取地址

以最大概率从名片中提取地址
EN

Stack Overflow用户
提问于 2018-08-12 08:31:43
回答 1查看 2.3K关注 0票数 1

我有一张名片的图片。使用OCR,我可以将此图像转换为文本。现在,我想分开信息,并添加到联系。

通过regex,我可以解析诸如电话、电子邮件、网站之类的信息,但无法将地址与其隔离,因为不同卡的格式不同。。

我正在Android平台上的一个设备上使用firebase工具包。我正在附上OCR的输出。

来自google图像的名片输入图像

OCR的输出是

  1. 第1行= larriS,保险
  2. 第2行= A,遗产,质量,服务
  3. 第3行=韦恩,斯坦斯菲尔德,i,CLCS
  4. 第4行= 1380,里约,兰乔,布雷夫,SE363
  5. 第5行=里约、兰乔、北地中海、87124
  6. 第6行=单元格,505.554.0510
  7. 第7行=电话,505-818-9377
  8. 第8行=传真,888-753.4449
  9. 第9行= WayneJames@me.com

检查了link1link2link3,但是没有从regex中找到地址,所以我尝试通过间接的方式找到它。

如果它有邮政编码,那么尝试通过它查找地址,但是邮政编码也不同。找到一些希望对不同国家使用多重正则表达式,但它不是解决办法,你可以帮助我找到一个方法来提取它。我知道它对市场上所有类型的格式都是100%有效的,但我想最大限度地涵盖这些格式。

下面是可以这样做的参考应用程序

CardCam应用 免费商业读卡器-名片扫描器

卡片读取API,但这些都是付费的

Abbyy CardCam API

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-14 09:07:40

你通过每一行提取信息并识别其中的一些,例如第6-8行被识别,你也可以将9定义为电子邮件。

所以你对1-5线唯一的怀疑。

您不能100%确定如果行符合或不符合任何regexp,因为没有“协议”应该如何在卡上打印地址,所以您可以假设

  1. 最有可能的地址应该是2+,因为在大多数情况下,第一行将有一个公司名称。
  2. 地址的一个部分应该包含预定义的值,例如
    • 布雷夫
    • 圣何塞
    • 街道
    • XX
    • 邮政编码的Zip - regex非常简单
    • 其他关键词

  1. 最有可能的地址将以Zip代码开头。

所以,如果你把所有这些都结合到一个单一的方法中,你就会得到一个算法,它可以预测是否有一个有可能的地址。

根据上面的假设,第4行和第5行更有可能是地址行,因为-第4行从一个看起来像邮政编码的数字开始,-第5行包含了一些类似的状态。

更新

复杂的解决方案可能如下所示:

代码语言:javascript
运行
复制
public static float checkLineForAddress(List<String> testdata) {
        boolean containsZip = false;
        boolean containsState = false;
        boolean containsAddressKeyword = false;
        boolean containsWord = false;
        boolean containsCapitalizedWord = false;
        boolean containsNumber = false;
        boolean containsBuildingNum = false;
        for (String item : testdata) {
            Set<Map.Entry<String, String>> entries = zipRegexps.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                containsZip = containsZip || item.matches(entry.getValue());
                if (containsZip) break;
            }
            containsState = containsState || item.matches("[A-Z]{2}");
            containsBuildingNum = containsBuildingNum || item.contains("/");
            containsWord = containsWord || item.matches("[A-Za-z]+");
            containsCapitalizedWord = containsCapitalizedWord || item.matches("[A-Z]+[a-z]+");
            for (String addressKeyword : addressKeywords) {
                containsAddressKeyword = containsAddressKeyword || item.replace(".", "").equalsIgnoreCase(addressKeyword);
            }
            containsNumber = containsNumber || item.matches("[0-9]+");
        }

        float addressProbability = 0;
        if (containsZip && containsCapitalizedWord && (containsState || containsAddressKeyword)) return 1f;
        if (containsZip && containsWord) addressProbability = 0.5f;
        if (containsCapitalizedWord) addressProbability += 0.1f;
        if (containsAddressKeyword) addressProbability += 0.2f;
        if (containsNumber) addressProbability += 0.05f;
        if (containsBuildingNum) addressProbability += 0.05f;
        if (testdata.size() > 1) addressProbability += 0.05f;
        if (testdata.size() > 2) addressProbability += 0.05f;
        return addressProbability;
    }

我从这里获取了一个邮政编码列表:什么是最终的邮政编码和邮政编码?,变量的init方法:

代码语言:javascript
运行
复制
private static void init() {
        zipRegexps.put("GB", "GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\\d{1,4}");
        zipRegexps.put("JE", "JE\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}");
        zipRegexps.put("GG", "GY\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}");
        zipRegexps.put("IM", "IM\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}");
        zipRegexps.put("US", "\\d{5}([ \\-]\\d{4})?");
        zipRegexps.put("CA", "[ABCEGHJKLMNPRSTVXY]\\d[ABCEGHJ-NPRSTV-Z][ ]?\\d[ABCEGHJ-NPRSTV-Z]\\d");
        zipRegexps.put("DE", "\\d{5}");
        zipRegexps.put("JP", "\\d{3}-\\d{4}");
        zipRegexps.put("FR", "\\d{2}[ ]?\\d{3}");
        zipRegexps.put("AU", "\\d{4}");
        zipRegexps.put("IT", "\\d{5}");
        zipRegexps.put("CH", "\\d{4}");
        zipRegexps.put("AT", "\\d{4}");
        zipRegexps.put("ES", "\\d{5}");
        zipRegexps.put("NL", "\\d{4}[ ]?[A-Z]{2}");
        zipRegexps.put("BE", "\\d{4}");
        zipRegexps.put("DK", "\\d{4}");
        zipRegexps.put("SE", "\\d{3}[ ]?\\d{2}");
        zipRegexps.put("NO", "\\d{4}");
        zipRegexps.put("BR", "\\d{5}[\\-]?\\d{3}");
        zipRegexps.put("PT", "\\d{4}([\\-]\\d{3})?");
        zipRegexps.put("FI", "\\d{5}");
        zipRegexps.put("AX", "22\\d{3}");
        zipRegexps.put("KR", "\\d{3}[\\-]\\d{3}");
        zipRegexps.put("CN", "\\d{6}");
        zipRegexps.put("TW", "\\d{3}(\\d{2})?");
        zipRegexps.put("SG", "\\d{6}");
        zipRegexps.put("DZ", "\\d{5}");
        zipRegexps.put("AD", "AD\\d{3}");
        zipRegexps.put("AR", "([A-HJ-NP-Z])?\\d{4}([A-Z]{3})?");
        zipRegexps.put("AM", "(37)?\\d{4}");
        zipRegexps.put("AZ", "\\d{4}");
        zipRegexps.put("BH", "((1[0-2]|[2-9])\\d{2})?");
        zipRegexps.put("BD", "\\d{4}");
        zipRegexps.put("BB", "(BB\\d{5})?");
        zipRegexps.put("BY", "\\d{6}");
        zipRegexps.put("BM", "[A-Z]{2}[ ]?[A-Z0-9]{2}");
        zipRegexps.put("BA", "\\d{5}");
        zipRegexps.put("IO", "BBND 1ZZ");
        zipRegexps.put("BN", "[A-Z]{2}[ ]?\\d{4}");
        zipRegexps.put("BG", "\\d{4}");
        zipRegexps.put("KH", "\\d{5}");
        zipRegexps.put("CV", "\\d{4}");
        zipRegexps.put("CL", "\\d{7}");
        zipRegexps.put("CR", "\\d{4,5}|\\d{3}-\\d{4}");
        zipRegexps.put("HR", "\\d{5}");
        zipRegexps.put("CY", "\\d{4}");
        zipRegexps.put("CZ", "\\d{3}[ ]?\\d{2}");
        zipRegexps.put("DO", "\\d{5}");
        zipRegexps.put("EC", "([A-Z]\\d{4}[A-Z]|(?:[A-Z]{2})?\\d{6})?");
        zipRegexps.put("EG", "\\d{5}");
        zipRegexps.put("EE", "\\d{5}");
        zipRegexps.put("FO", "\\d{3}");
        zipRegexps.put("GE", "\\d{4}");
        zipRegexps.put("GR", "\\d{3}[ ]?\\d{2}");
        zipRegexps.put("GL", "39\\d{2}");
        zipRegexps.put("GT", "\\d{5}");
        zipRegexps.put("HT", "\\d{4}");
        zipRegexps.put("HN", "(?:\\d{5})?");
        zipRegexps.put("HU", "\\d{4}");
        zipRegexps.put("IS", "\\d{3}");
        zipRegexps.put("IN", "\\d{6}");
        zipRegexps.put("ID", "\\d{5}");
        zipRegexps.put("IL", "\\d{5}");
        zipRegexps.put("JO", "\\d{5}");
        zipRegexps.put("KZ", "\\d{6}");
        zipRegexps.put("KE", "\\d{5}");
        zipRegexps.put("KW", "\\d{5}");
        zipRegexps.put("LA", "\\d{5}");
        zipRegexps.put("LV", "\\d{4}");
        zipRegexps.put("LB", "(\\d{4}([ ]?\\d{4})?)?");
        zipRegexps.put("LI", "(948[5-9])|(949[0-7])");
        zipRegexps.put("LT", "\\d{5}");
        zipRegexps.put("LU", "\\d{4}");
        zipRegexps.put("MK", "\\d{4}");
        zipRegexps.put("MY", "\\d{5}");
        zipRegexps.put("MV", "\\d{5}");
        zipRegexps.put("MT", "[A-Z]{3}[ ]?\\d{2,4}");
        zipRegexps.put("MU", "(\\d{3}[A-Z]{2}\\d{3})?");
        zipRegexps.put("MX", "\\d{5}");
        zipRegexps.put("MD", "\\d{4}");
        zipRegexps.put("MC", "980\\d{2}");
        zipRegexps.put("MA", "\\d{5}");
        zipRegexps.put("NP", "\\d{5}");
        zipRegexps.put("NZ", "\\d{4}");
        zipRegexps.put("NI", "((\\d{4}-)?\\d{3}-\\d{3}(-\\d{1})?)?");
        zipRegexps.put("NG", "(\\d{6})?");
        zipRegexps.put("OM", "(PC )?\\d{3}");
        zipRegexps.put("PK", "\\d{5}");
        zipRegexps.put("PY", "\\d{4}");
        zipRegexps.put("PH", "\\d{4}");
        zipRegexps.put("PL", "\\d{2}-\\d{3}");
        zipRegexps.put("PR", "00[679]\\d{2}([ \\-]\\d{4})?");
        zipRegexps.put("RO", "\\d{6}");
        zipRegexps.put("RU", "\\d{6}");
        zipRegexps.put("SM", "4789\\d");
        zipRegexps.put("SA", "\\d{5}");
        zipRegexps.put("SN", "\\d{5}");
        zipRegexps.put("SK", "\\d{3}[ ]?\\d{2}");
        zipRegexps.put("SI", "\\d{4}");
        zipRegexps.put("ZA", "\\d{4}");
        zipRegexps.put("LK", "\\d{5}");
        zipRegexps.put("TJ", "\\d{6}");
        zipRegexps.put("TH", "\\d{5}");
        zipRegexps.put("TN", "\\d{4}");
        zipRegexps.put("TR", "\\d{5}");
        zipRegexps.put("TM", "\\d{6}");
        zipRegexps.put("UA", "\\d{5}");
        zipRegexps.put("UY", "\\d{5}");
        zipRegexps.put("UZ", "\\d{6}");
        zipRegexps.put("VA", "00120");
        zipRegexps.put("VE", "\\d{4}");
        zipRegexps.put("ZM", "\\d{5}");
        zipRegexps.put("AS", "96799");
        zipRegexps.put("CC", "6799");
        zipRegexps.put("CK", "\\d{4}");
        zipRegexps.put("RS", "\\d{6}");
        zipRegexps.put("ME", "8\\d{4}");
        zipRegexps.put("CS", "\\d{5}");
        zipRegexps.put("YU", "\\d{5}");
        zipRegexps.put("CX", "6798");
        zipRegexps.put("ET", "\\d{4}");
        zipRegexps.put("FK", "FIQQ 1ZZ");
        zipRegexps.put("NF", "2899");
        zipRegexps.put("FM", "(9694[1-4])([ \\-]\\d{4})?");
        zipRegexps.put("GF", "9[78]3\\d{2}");
        zipRegexps.put("GN", "\\d{3}");
        zipRegexps.put("GP", "9[78][01]\\d{2}");
        zipRegexps.put("GS", "SIQQ 1ZZ");
        zipRegexps.put("GU", "969[123]\\d([ \\-]\\d{4})?");
        zipRegexps.put("GW", "\\d{4}");
        zipRegexps.put("HM", "\\d{4}");
        zipRegexps.put("IQ", "\\d{5}");
        zipRegexps.put("KG", "\\d{6}");
        zipRegexps.put("LR", "\\d{4}");
        zipRegexps.put("LS", "\\d{3}");
        zipRegexps.put("MG", "\\d{3}");
        zipRegexps.put("MH", "969[67]\\d([ \\-]\\d{4})?");
        zipRegexps.put("MN", "\\d{6}");
        zipRegexps.put("MP", "9695[012]([ \\-]\\d{4})?");
        zipRegexps.put("MQ", "9[78]2\\d{2}");
        zipRegexps.put("NC", "988\\d{2}");
        zipRegexps.put("NE", "\\d{4}");
        zipRegexps.put("VI", "008(([0-4]\\d)|(5[01]))([ \\-]\\d{4})?");
        zipRegexps.put("PF", "987\\d{2}");
        zipRegexps.put("PG", "\\d{3}");
        zipRegexps.put("PM", "9[78]5\\d{2}");
        zipRegexps.put("PN", "PCRN 1ZZ");
        zipRegexps.put("PW", "96940");
        zipRegexps.put("RE", "9[78]4\\d{2}");
        zipRegexps.put("SH", "(ASCN|STHL) 1ZZ");
        zipRegexps.put("SJ", "\\d{4}");
        zipRegexps.put("SO", "\\d{5}");
        zipRegexps.put("SZ", "[HLMS]\\d{3}");
        zipRegexps.put("TC", "TKCA 1ZZ");
        zipRegexps.put("WF", "986\\d{2}");
        zipRegexps.put("XK", "\\d{5}");
        zipRegexps.put("YT", "976\\d{2}");

        addressKeywords.add("blvd");
        addressKeywords.add("st");
        addressKeywords.add("street");
        addressKeywords.add("lane");
    }

TestData是

代码语言:javascript
运行
复制
List<String> testdata = new ArrayList<>();
testdata.add("1380");
testdata.add("Rio");
testdata.add("Rancho");
testdata.add("Blvd");
testdata.add("SE363");
Log.e("!@#", String.valueOf(checkLineForAddress(testdata)));
testdata = new ArrayList<>();
testdata.add("Rio");
testdata.add("Rancho");
testdata.add("NM");
testdata.add("87124");
Log.e("!@#", String.valueOf(checkLineForAddress(testdata)));
testdata = new ArrayList<>();
testdata.add("Wayne");
testdata.add("Stansfield");
testdata.add("i");
testdata.add("CLCS");
Log.e("!@#", String.valueOf(checkLineForAddress(testdata)));
testdata = new ArrayList<>();
testdata.add("James");
testdata.add("Gordon");
testdata.add("Smith");
Log.e("!@#", String.valueOf(checkLineForAddress(testdata)));
testdata = new ArrayList<>();
testdata.add("5052");
testdata.add("554");
testdata.add("11500");
testdata.add("121151");
Log.e("!@#", String.valueOf(checkLineForAddress(testdata)));
testdata = new ArrayList<>();
testdata.add("Creative");
testdata.add("Director");
Log.e("!@#", String.valueOf(checkLineForAddress(testdata)));

和输出

代码语言:javascript
运行
复制
E/!@#: 1.0
E/!@#: 1.0
E/!@#: 0.70000005
E/!@#: 0.2
E/!@#: 0.15
E/!@#: 0.15

正如你所看到的,第3行是一个70%概率的地址,因为理论上CLCS可以是一个百慕大邮政编码

您可以根据测试数据修改可能性。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51807113

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档