最近做验证码识别,原本用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. Qt编写控件属性设计器6-动态属性

    一.前言 之前就提过,Qt的属性机制强大到爆,这次的动态属性功能就是要让他爆,很难想象只要一行代码即可widget->setProperty("value", value); ...

  2. Django之中间件、缓存以及信号

    Django之中间件 中间件执行流程 我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下: 也就是说,每一个请求都是先通 ...

  3. Ext.net中Combobox如何绑定数据库中的值

    ];      ];      " />       </Items> </ext:ComboBox>

  4. 【Leetcode_easy】686. Repeated String Match

    problem 686. Repeated String Match solution1: 使用string类的find函数: class Solution { public: int repeate ...

  5. CSS基础(html+css基础)

    css: CSS全称为“层叠样式表 (Cascading Style Sheets)”,它主要是用于定义HTML内容在浏览器内的显示样式,如文字大小.颜色.字体加粗等. 1.CSS代码语法: css ...

  6. WebGL学习之纹理盒

    原文地址:WebGL学习之纹理盒 我们之前已经学习过二维纹理 gl.TEXTURE_2D,而且还使用它实现了各种效果.但还有一种立方体纹理 gl.TEXTURE_CUBE_MAP,它包含了6个纹理代表 ...

  7. 【ARM-Linux开发】使用QT和Gstreanmer 遇到的一些问题

    1.如果出现错误,可能是在安装UCT PCRF时,相关组件不全,略举两个碰到的错误. 1)curl/curl.h:No such file or directory --可能原因是libcurl及相关 ...

  8. jquery-easyui中改变【确认框控件的按钮文字】($.messager.confirm)

    根据API这句话,就很自然想到重写该方法,代码如下: $.messager.defaults = { ok: "通过", cancel: "不通过" ,widt ...

  9. udevdm命令详解

    udevadm 后接一个命令和命令指定选项.它控制了udev运行的行为,处理内核事件,控制事件队列,并且提供简单的调试机制. 选项: --debug 打印错误信息 --version 打印版本信息 - ...

  10. 【leetcode算法-中等】3. 无重复字符的最长字串

    [题目描述] 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 " ...