最近做验证码识别,原本用MATLAB已经实现的整个识别模型,不过代码要部署在Linux服务器上还是需要用另外的语言实现,于是决定用Python + OpenCV来实现。

bwlabel函数的作用是检测二值图像中连通域的个数及为每个连通域标记后的矩阵。

关于连通域检测算法我是参考的http://blog.sina.com.cn/s/blog_ad81d4310102vmll.html 这篇文章中的基于行程的标记 方法,以及传统的Two-Pass方法。

传统的Two-pass方法中关于连通域标记的规则如下:

1.逐行扫描图像上的点,检查每个点是否是前景点,如果不是,继续扫描;

2.检查该前景点的左边的点和上边的点

如果有一个为前景点,则为当前扫描点标记和此点相同编号;

如果两个都是前景点,则选择标号小的,为当前扫描点标记编号;这里注意如果两个都是前景点且标号不同,需要把标号小的点设为标号大的点的父节点,以方便第二遍扫描的时候用并查集算法(参考 利用不相交集实现等价元素的聚类 )合并;

如果都不是,则赋值目前标号label,label++(label初始值为零);

3.再次扫描图像,利用并查集算法合并联通的不同的label的区域。

第一二步就是一个二重循环遍历矩阵,对矩阵中每个元素的上邻元素和左邻元素进行判断来标记该元素,并扩充等价对列表。这两步都比较好理解。

经过标记后会得到一个标记后的矩阵和一个等价对列表。最后一步是将等价值列表合并成具有相同标记的标记集合,比如[(1,2),(1,5),(2,3),(4,6),(7,8)],那么需要把这幅等价值表转换成[(1,2,3,5),(4,6),(7,8)]这三个区域,最后通过这个新的表去重新遍历标记后的矩阵,将其他标记值修改为最小的标记值,这样最后就能得到一个标记了的连通域矩阵。

下面在仿照上面博客中的对等价值的处理。这篇博客中是用 C++ 来实现广度优先搜索,由于其中用到指针去改变栈的大小,这样能实现循环的时候边界长度随着栈的大小变化而动态的变化。

在java中这样在循环中动态改变列表的值数量是会报异常的,python中这样做的时候循环的边界大小不会随着列表的大小改变而改变。

参照博客中的算法,思路如下:

每个元素看做是无向图中的点,等价对看作是一条连通路径,所以先用等价对列表初始化一个连通矩阵 data。
创建一个列表 labelFlag 标记每个点是否被访问了。
对labelFlag进行遍历,如果labelFlag[i] == 0就表示i点没有被访问,!= 0就表示该点已经被访问了,则跳过该点继续遍历下一个点。
如果临时列表tempList为空,且遇到labelFlag[i]没有被访问,则说明需要创建一个新的连通域了。
如果tempList不为空,则将tempList列表的最后一个元素出栈得到元素index,然后判断index是否已经被访问了,如果没有被访问则继续对index为起点的路径访问;
如果index所指的行的元素不为0且不为 0 的元素所在的列对应的labelFlag[j]没有被访问,就把j压入tempList列表,并把j标记压入到连通集合中。

经过上面的遍历就能获得结果。

为了解决这个问题,我的代码实现如下:

import numpy as np

data = [(1, 2), (2, 4), (1, 5), (3, 6), (7, 8)]
maxLabel = np.max(data)
eqTab = np.zeros((maxLabel, maxLabel)) for left, right in data:
eqTab[left - 1, right - 1] = 1
eqTab[right - 1, left - 1] = 1 labelFlag = np.zeros(maxLabel) tempList = [1]
eqList = []
data_result = [] for i in xrange(maxLabel):
if labelFlag[i]:
continue
eqList = [i + 1]
tempList = [i + 1]
for k in xrange(maxLabel):
if not tempList:
break
index = tempList.pop()
for j in xrange(maxLabel):
if eqTab[index - 1, j] and not labelFlag[j]:
tempList.append(j + 1)
eqList.append(j + 1) labelFlag[index - 1] = 1 data_result.append(eqList) print data_result

输出结果为:[[1, 2, 5, 4], [3, 6], [7, 8]]

这个实现算法比较直白,完全是按照算法思路来写的程序,没有进一步考虑过优化什么的,读者可以自己琢磨琢磨。

等我把整个bwlabel算法写完再附上完整的源码。

Python实现MATLAB中的 bwlabel函数的更多相关文章

  1. python实现类似于Matlab中的magic函数

    参考这篇文章的代码封装了一个类似Matlab中的magic函数,用来生成魔方矩阵. #!/usr/bin/env python # -*- coding: utf-8 -*- import numpy ...

  2. matlab中的eval函数使用

    matlab中的eval函数使用 在matlab的命令行窗口中输入help eval命令回车就可以看到eval函数的官方解释,大概的意思就是执行matlab中的表达式,计算expression表示的代 ...

  3. Matlab中的eig函数和Opecv中eigen()函数的区别

    奇异值分解的理论参见下面的链接 http://www.cnblogs.com/pinard/p/6251584.html https://blog.csdn.net/shenziheng1/artic ...

  4. Matlab中的fread函数

    Matlab中fread函数用法    "fread"以二进制形式,从文件读出数据. 语法1:[a,count]=fread(fid,size,precision) 语法2:[a, ...

  5. matlab中的sub2ind函数

    在matlab中,矩阵的存储是按列优先,sub2ind函数将矩阵中指定元素的行列下标转换成存储的序号,即线性索引号.下面,我们举例子进行说明. 1 建立一个3*4*2的矩阵 rng(0,'twiste ...

  6. matlab中CRC的函数使用

    先学习一下matlab中CRC函数. 语法如下: h = crc.generator(‘Polynomial', polynomial, ‘param1', val1, etc.) 再看一个例子就比较 ...

  7. matlab中help所有函数功能的英文翻译

    doc funname 在帮助浏览器中打开帮助文档 help funname 在命令窗口打开帮助文档 helpbrowser 直接打开帮助浏览器 lookfor funname 搜索某个关键字相关函数 ...

  8. python开发_python中的range()函数

    python中的range()函数的功能hen强大,所以我觉得很有必要和大家分享一下 就好像其API中所描述的: If you do need to iterate over a sequence o ...

  9. Python连载43-current中的map函数、xml文件

    一.current中的map函数 1.map(fn,*iterable,timeout=None) (1)跟map函数相类似(2)函数需要异步执行(3)timeout代表超时时间 (4)map和sub ...

随机推荐

  1. osg qt kdchart 开发施工过程模拟软件

    void TeslaManage::initGanttModel() { ganttModel = , , this); ganttModel->setHeaderData(, Qt::Hori ...

  2. 【422】Insert often-used pieces of text in gedit

    Ref: Snippets Enable Snippets Plugin Browse Snippets Using Snippets To insert a nippet into your cur ...

  3. (十四)Centos之安装vsftp服务

    一.为什么要安装vsftp服务 我们需要向centos操作系统的服务器上上传文件或者下载文件,这时候,ftp有必要安装下,我们选择主流的vsftp 二.安装 第一步:安装vsftp yum insta ...

  4. linux 安装网易云音乐

    1.首先去官网下载最新的网易云 网易云音乐曾经推出官方Linux版本,提供的下载安装包有:deepin15(32位):http://s1.music.126.net/download/pc/net . ...

  5. Eclipse导入Spring Boot项目后pom.xml出现红叉的解决办法

    胸怀难的问题是:程序能正常运行,但是pom.xml下面有一个红叉. 解决办法: 右键项目 --> Update project...

  6. todolist形式的搜索框,分开组件写的,点击上下键时,框内显示当前选中的内容

    ### 首先  安装react 脚手架 cnpm  install  create-react-app  -g      //只需要在电脑上安装一次就好了,以后不用再下载了 ### 创建项目 crea ...

  7. 区块链学习(四)truffle部署编译智能合约以太坊私有链

    前面我们介绍了以太坊私有链的搭建以及多节点私有链网络,这次我们介绍如何使用truffle框架来部署编译智能合约到我们之前搭建的私有链网络中. 搭建环境及需使用的工具:ubuntu18.04  Truf ...

  8. 最新 中钢网java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.中钢网等10家互联网公司的校招Offer,因为某些自身原因最终选择了中钢网.6.7月主要是做系统复习.项目复盘.LeetCo ...

  9. execl文件读取封装

    前言:做自动化常用的公共方法 注:第一次使用记得先 pip install xlrd 模块import xlrd class ReadExecl(): def __init__(self,filena ...

  10. 前端入门系列之CSS

    CSS (Cascading Style Sheets) 是用来样式化和排版你的网页的 —— 例如更改网页内容的字体.颜色.大小和间距,将内容分割成多列或者加入动画以及别的装饰型效果. CSS是什么 ...