种子填充算法在验证码识别中的的应用

来源:互联网 发布:php与或非逻辑符号 编辑:程序博客网 时间:2024/06/03 02:02

模拟精灵识别验证码的能用是强大的,一个函数即可以去除杂色杂点,但是有时候验证码中有大量的干扰线,并且位置随机变动的太历害,这时候我们在处理验证码以前首先去除这些干扰线并准确的去除背景提取字符.

下面是一个模拟精灵初步处理后的验证码图片.已经去除了杂色、杂点.但是上面还是有干扰线.
图片点击可在新窗口打开查看

一个可选的办法是用中值滤波再处理一下。img:median(2); 一个函数调用就可以,但是这样虽然去掉了干扰线,原来的字符也被少量的破坏了。

论坛有用户提出用种子填充算法来分析干扰线。
原贴: http://www.yhhe.net/bbs/dispbbs.asp?boardID=4&ID=3308&page=1
但是在算法的设计上存在问题,效果不理想。

下面是改进算法以后重新写的代码,不但能去除杂点,而且可以去除周围的空白(提取位置随机变化的验证码),
稍加修改还能有更多的用途.

下面是自动处理以后的效果

图片点击可在新窗口打开查看(干扰线没有了,周围的空白没有了,速度也很快,接近零延时)

下面是全部的源代码:

--[[
用一个table结构{x=0; y=0}表示图像上的「坐标点」
用一组点构成table结构表示图像上的一条「线」。所有相连的黑色的点被认为是一条「连通线」。
找出最长的一条「连通线」,被认为是字符,其他的认为是杂点。
 
 
算法原理与种子填充算法相似。
 
首先让用img:bpp函数处理为黑白图片,并初步去除杂色。
 
先找到一个黑点,创建一个表示「坐标点」对象,并添加到「连通线」中。
然后在黑点周围8个点中,再找黑色的点,找到就添加到「连通线」,这样一直递归下去
直到遍历图像所有点,可能有几块。
 
清除杂点使用方法
image.scan(img);
 
清除杂点并切去掉周围的空白
image.scan(img,true);
--]]
f
unction image.scan(img,crop)
   
    --用一个table数组记录所有的「连通线」
     assert(img:ok(),"image.scan 的参数必须是一个有效的图片");
   
     local tlines ={};
    
     --首先计算出图片的高度宽度,避免重复的调用
     local w = img:width();
     local h = img:height();
         
 
    --[[以table形式定义一个数组,对应图象中的每个点。
    作用相当一个开关,首先值为false,但黑点首次被遍历到时。把这个值变为true。
    下次,再找到这个点时忽略。避免重复加入连通线。 
    --]]
    local tchked ={};
    for i=0,w,do
        tchked[i]={};
        for j=0,h,1  do
            tchked[i][j]=false;
        end;
    end;
    
    -----去噪
    img:bpp(1);
    img:bpp(24);
    
    --首先计算出各点的颜色值,避免在循环递归中重复的取
    local tcl={};
    for i=0,w,1  do
        tcl[i]={};
        for j=0,h,1   do
            tcl[i][j]=img:getPos(i,j);
        end;
    end;
 
   
    --[[
    算点数函数
    参数x,y 坐标
    参数tab 所属连通线;
    --]]
    local   function  seed(x,y,tab)
   
        ---出界了则返回
        if(x<0 or y<0 or x>w or y>h) then
            return;
        end;
             
        ---点的颜色为白色时,返回,不处理。
        if(tcl[x][y]==16777215)  then
            return;
        end;
       
        ---值为1,则计数加1,返回
        if ( tchked[x][y]) then
            return ;
        else
            table.insert(tab,{x=x,y=y} );--添加到连通线里
            tchked[x][y]=true;---当值为0时,把值置为1。
            seed(x+1,y-1,tab);
            seed(x,y-1,tab);
            seed(x-1,y-1,tab);
            seed(x-1,y,tab);
            seed(x+1,y,tab);
            seed(x-1,y+1,tab);
            seed(x,y+1,tab);
            return seed(x+1,y+1,tab); --这里可以用一个尾调用(参考教程中的函数部份),加快递归的速度。
        end;
    end;
 
   
    ---------------------------
      
    ----遍历图像中的所有点
    for i=0,w,1   do
        for j=0,h,1  do
            ---如果是黑色的点,而且没有被计过数,则调用seed函数。
            if(tcl[i][j]==0 and (not tchked[i][j])) then       
                local tab = {}
                seed(i,j,tab);
                table.insert(tlines,tab); --添加一条连通线
   
            end;
        end;
    end;
         
    --现在tlines 里记录了的有的连通线,我们现在需要根据连通线的长度排序 
    sproc =  function(l,l2)  
        return table.maxn(l) > table.maxn(l2);--长的连通线排到前面
    end;
    table.sort(tlines,sproc)
              
    --把图像全部画成白色的点     
    for i=0,w,1  do
        for j=0,h,1  do
            img:setPos( i , j, 16777215);
        end;
    end;
         
    --然后把最长的一条连通线画上去
    for i,point in  ipairs(tlines[1])  do
        img:setPos( point.x, point.y , 0);  
    end;
   
 
    --如果需要去掉周围的空白
    if(crop)then
        local n = table.maxn(tlines[1])
           
        --排序最长连通线中的所有坐标点
        sproc =  function(pt,pt2)  
            return  (pt.x <pt2.x );--*左的排前面
        end;
        table.sort(tlines[1],sproc);
        local x,x2 = tlines[1][1].x, tlines[1][n].x;
   
        --排序最长连通线中的所有坐标点
        sproc =  function(pt,pt2)  
            return (pt.y <pt2.y );--*上的排前面
        end;
        table.sort(tlines[1],sproc);
        local y,y2 = tlines[1][1].y, tlines[1][n].y;
       
        img:Crop( x,y,x2+1,y2)
    end;
   
end;

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 右腿比左腿粗2cm怎么办 八个月宝宝小腿弯怎么办 南航航班取消了怎么办 高铁不能送老人怎么办 小孩买火车票没有身份证怎么办 断奶后孩子瘦了怎么办 两岁宝宝坐飞机哭闹怎么办 八个月宝宝坐飞机哭闹怎么办 六岁儿童发烧39度怎么办 孩子坐飞机没带证件怎么办 带孩子坐飞机需要什么证件怎么办 婴儿乘飞机没带证件怎么办 吃了轮状发烧怎么办 儿童票比打折票贵怎么办 订机票订错了怎么办 如果飞机不支持婴儿票怎么办 报志愿登不上去怎么办 微单自拍是反的怎么办 蜡笔弄到桌子上怎么办 油画颜料干透了怎么办 数字油画颜料干了怎么办 数字油画的颜料干了怎么办 丙烯颜料画错了怎么办 油画的油干了怎么办 数字油画没画完颜料干了怎么办? 涂完口红很干怎么办 吃鸡匹配不到人怎么办 电脑吃鸡更新慢怎么办 苹果手机吃鸡更新不了怎么办 吃鸡更新硬盘不够怎么办 吃鸡链接不到更新服务器怎么办 6s吃鸡更新不了怎么办 凌美钢笔刮纸怎么办 毕加索钢笔不出水怎么办妙招 打印机总显示墨水已用完怎么办 樱花勾线笔干了怎么办 枣核卡在喉咙里怎么办 马桶被玉米棒堵了怎么办 雪糕棒掉马桶里了怎么办 食用色素吃多了怎么办 蜡笔弄到指甲里怎么办