去除这样验证码的干扰线,大家有什么好的思路吗?

wzp144650 2013-02-05 12:03:23



去除这样验证码的干扰线,大家有什么好的思路吗?说下思路就行
...全文
9171 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
yiyefangzhou24 2013-07-16
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
'接上帖
Private Function recognize() As String
    t = 2 '上面3行空白
    l = 1 '左边1列空白
    w = 11 '每个数字宽11像素
    h = 13 '每个数字高13像素
    g = 11 '两个数字相距11像素
    r = "xxxx"
    On Error GoTo RERR
    Picture1.Picture = LoadPicture(FPFN)
    For n = 0 To 3
        s = ""
        For y = 0 To h - 1
            For x = 0 To w - 1
                'Debug.Print " "; Right("00000000" + Hex(Picture1.Point(n * w + x, t + y)), 8);
                b = ColorDistance(Picture1.Point(l + n * g + x, t + y), &HE6AFBE)
                'Debug.Print " "; Right(" " + CStr(b), 2); " ";
                If b < 30 Then
                    Debug.Print "-";
                    s = s + "-"
                Else
                    Debug.Print "O";
                    s = s + "O"
                End If
                Picture1.PSet (l + n * g + x, t + y), RGB(255, 0, 0)
            Next
            Debug.Print
        Next
        Debug.Print
        For i = 0 To 9
            a = 0
            For j = 0 To h - 1
                For k = 0 To w - 1
                    c1 = Mid(s, 1 + j * w + k, 1)
                    c2 = Mid(nm(i), 1 + j * w + k, 1)
                    If c1 = c2 Then
                        a = a + 1
                    End If
                Next
            Next
            aa(i) = a
            Debug.Print i, a
        Next
        maxi = -1
        maxa = 0
        For i = 0 To 9
            If maxa < aa(i) Then
                maxi = i
                maxa = aa(i)
            End If
        Next
        If maxa >= 100 Then
            Mid(r, n + 1, 1) = CStr(maxi)
        End If
    Next
RERR:
    recognize = r
    Label1.Caption = r
    Exit Function
End Function

Private Sub Timer1_Timer()
Dim f As Integer
On Error Resume Next
        If LCase(Right(FPFN, 4)) = ".bmp" Then
            f = FreeFile()
            Open FPFN + ".txt" For Output As #f
            Print #f, recognize()
            Close #f
            End
        Else
            logtofile "[" + FPFN + "] is not .bmp file!"
        End If
End Sub
Public Function FileExists(filename) As Boolean
Dim msg As String
    On Error GoTo CheckError
        FileExists = (Dir(filename) <> "")
        Exit Function
CheckError:
    Const mnErrDiskNotReady = 71, mnErrDeviceUnavailable = 68
    If (Err.Number = mnErrDiskNotReady) Then
        msg = "将软盘插入驱动器 "
        msg = msg + ",然后关好驱动器门。"
        If MsgBox(msg, vbExclamation + vbOKCancel) = vbOK Then
            Resume
        Else
            FileExists = False
            Exit Function
        End If
    ElseIf Err.Number = mnErrDeviceUnavailable Then
        msg = "找不到: "
        msg = msg + filename
        MsgBox msg, vbExclamation
        FileExists = False
        Exit Function
    Else
        FileExists = False
        Exit Function
        'msg = "出现 #" + str(Err.Number)
        'msg = msg + " 意外错误: " + Err.Description
        'MsgBox msg, vbCritical
        'End'Form
    End If
    FileExists = False
    Exit Function
End Function

Private Sub logtofile(s As String)
Dim f As Integer
On Error Resume Next
    f = FreeFile()
    Open App.Path + "\numeye2.log" For Append As #f
    Print #f, Format(Now, "YYYY-MM-DD hh:mm:ss") + " " + s
    Close #f
End Sub

Private Function Minimum(ParamArray Vals())
Dim n As Integer, MinVal
On Error Resume Next
    MinVal = Vals(0)
    For n = 1 To UBound(Vals)
        If Vals(n) < MinVal Then MinVal = Vals(n)
    Next n
    Minimum = MinVal
End Function
Private Function Maximum(ParamArray Vals())
Dim n As Integer, MaxVal
On Error Resume Next
    MaxVal = Vals(0)
    For n = 1 To UBound(Vals)
        If Vals(n) > MaxVal Then MaxVal = Vals(n)
    Next n
    Maximum = MaxVal
End Function
Private Sub c2hsb(ByVal clr As Long)
Dim MyR As Single, MyG As Single, MyB As Single
Dim Max As Single, Min As Single
Dim MyS As Single
Dim Delta As Single, MyVal As Single
Dim cc As String * 6
Dim r1, g1, b1 As Byte
On Error Resume Next
    cc = Right("000000" + Hex$(clr), 6)
    b1 = Val("&H" + Left(cc, 2))
    g1 = Val("&H" + Mid(cc, 3, 2))
    r1 = Val("&H" + Right(cc, 2))
    MyR = r1 / 255: MyG = g1 / 255: MyB = b1 / 255
    Max = Maximum(MyR, MyG, MyB)
    Min = Minimum(MyR, MyG, MyB)
    hsbB = Int(Max * 100)
    If Max <> 0 Then
        MyS = (Max - Min) / Max * 100
    Else
        MyS = 0
    End If
    hsbS = MyS
    If hsbS = 0 Then
        hsbH = 0
    Else
        Delta = Max - Min
        Select Case Max
        Case MyR
            MyVal = (MyG - MyB) / Delta
        Case MyG
            MyVal = 2 + (MyB - MyR) / Delta
        Case MyB
            MyVal = 4 + (MyR - MyG) / Delta
        End Select
        MyVal = MyVal * 60
        If MyVal < 0 Then MyVal = MyVal + 360
        hsbH = MyVal
    End If
'   Debug.Print "hsb="; hsbH; " "; hsbS; " "; hsbB
End Sub
Private Function ColorDistance(ByVal c1 As Long, ByVal c2 As Long) As Long
Dim cd As Long
Dim h1, s1, b1, h2, s2, b2 As Single
On Error Resume Next
    If c1 = -1 Or c2 = -1 Then
        ColorDistance = 1000000
        Exit Function
    End If
    c2hsb (c1)
    h1 = hsbH / 360
    s1 = hsbS
    b1 = hsbB
    c2hsb (c2)
    h2 = hsbH / 360
    s2 = hsbS
    b2 = hsbB
    cd = Abs(h1 - h2)
    cd = cd + Abs(s1 - s2)
    cd = cd + Abs(b1 - b2)
    ColorDistance = cd
End Function
这回好像没灌水
Clove 2013-07-16
  • 打赏
  • 举报
回复
@zhao4zhong1 的做法可以,我测试了一下.就是阀值容错率 还有lz可以参考http://bbs.anjian.com/viewthread.php?tid=411245 和http://www.cnblogs.com/marryZhan/archive/2010/05/11/2213952.html 去去噪点和干扰线
dubiousway 2013-02-05
  • 打赏
  • 举报
回复
不太明白你的意思。你说的比对指什么跟什么的比对。是指模板匹配吗?
wzp144650 2013-02-05
  • 打赏
  • 举报
回复
引用 2 楼 dubiousway 的回复:
用图像的开闭运算试试好用吗。 我自己觉得其实现在验证码的干扰形式的种类绕越来越多,不是仅有干扰线这一种。 还是觉得用网络训练的形式,根据结果百分比来判断比较好(如果结果比较低,可以重新刷新后,再次获的新验证码)
恩,我也想过你说的思路,对于比对方面正好也有个问题。 比如 0010 0010 1111 0010 与 1010 0010 1111 0010 对比时,我可以把第二个多出来的1忽略。毕竟都是16个位置与16个位置的比较。但是,如果第一个图不变,而第二分析出的图成了 0010 0010 0010 1111 0010 那么比对的结果差了很多啊,几乎错了一半,这如何解决呢
dubiousway 2013-02-05
  • 打赏
  • 举报
回复
用图像的开闭运算试试好用吗。 我自己觉得其实现在验证码的干扰形式的种类绕越来越多,不是仅有干扰线这一种。 还是觉得用网络训练的形式,根据结果百分比来判断比较好(如果结果比较低,可以重新刷新后,再次获的新验证码)
wzp144650 2013-02-05
  • 打赏
  • 举报
回复
都没人看么。。。
赵4老师 2013-02-05
  • 打赏
  • 举报
回复
'接上帖
Private Function recognize() As String
    t = 2 '上面3行空白
    l = 1 '左边1列空白
    w = 11 '每个数字宽11像素
    h = 13 '每个数字高13像素
    g = 11 '两个数字相距11像素
    r = "xxxx"
    On Error GoTo RERR
    Picture1.Picture = LoadPicture(FPFN)
    For n = 0 To 3
        s = ""
        For y = 0 To h - 1
            For x = 0 To w - 1
                'Debug.Print " "; Right("00000000" + Hex(Picture1.Point(n * w + x, t + y)), 8);
                b = ColorDistance(Picture1.Point(l + n * g + x, t + y), &HE6AFBE)
                'Debug.Print " "; Right(" " + CStr(b), 2); " ";
                If b < 30 Then
                    Debug.Print "-";
                    s = s + "-"
                Else
                    Debug.Print "O";
                    s = s + "O"
                End If
                Picture1.PSet (l + n * g + x, t + y), RGB(255, 0, 0)
            Next
            Debug.Print
        Next
        Debug.Print
        For i = 0 To 9
            a = 0
            For j = 0 To h - 1
                For k = 0 To w - 1
                    c1 = Mid(s, 1 + j * w + k, 1)
                    c2 = Mid(nm(i), 1 + j * w + k, 1)
                    If c1 = c2 Then
                        a = a + 1
                    End If
                Next
            Next
            aa(i) = a
            Debug.Print i, a
        Next
        maxi = -1
        maxa = 0
        For i = 0 To 9
            If maxa < aa(i) Then
                maxi = i
                maxa = aa(i)
            End If
        Next
        If maxa >= 100 Then
            Mid(r, n + 1, 1) = CStr(maxi)
        End If
    Next
RERR:
    recognize = r
    Label1.Caption = r
    Exit Function
End Function

Private Sub Timer1_Timer()
Dim f As Integer
On Error Resume Next
        If LCase(Right(FPFN, 4)) = ".bmp" Then
            f = FreeFile()
            Open FPFN + ".txt" For Output As #f
            Print #f, recognize()
            Close #f
            End
        Else
            logtofile "[" + FPFN + "] is not .bmp file!"
        End If
End Sub
Public Function FileExists(filename) As Boolean
Dim msg As String
    On Error GoTo CheckError
        FileExists = (Dir(filename) <> "")
        Exit Function
CheckError:
    Const mnErrDiskNotReady = 71, mnErrDeviceUnavailable = 68
    If (Err.Number = mnErrDiskNotReady) Then
        msg = "将软盘插入驱动器 "
        msg = msg + ",然后关好驱动器门。"
        If MsgBox(msg, vbExclamation + vbOKCancel) = vbOK Then
            Resume
        Else
            FileExists = False
            Exit Function
        End If
    ElseIf Err.Number = mnErrDeviceUnavailable Then
        msg = "找不到: "
        msg = msg + filename
        MsgBox msg, vbExclamation
        FileExists = False
        Exit Function
    Else
        FileExists = False
        Exit Function
        'msg = "出现 #" + str(Err.Number)
        'msg = msg + " 意外错误: " + Err.Description
        'MsgBox msg, vbCritical
        'End'Form
    End If
    FileExists = False
    Exit Function
End Function

Private Sub logtofile(s As String)
Dim f As Integer
On Error Resume Next
    f = FreeFile()
    Open App.Path + "\numeye2.log" For Append As #f
    Print #f, Format(Now, "YYYY-MM-DD hh:mm:ss") + " " + s
    Close #f
End Sub

Private Function Minimum(ParamArray Vals())
Dim n As Integer, MinVal
On Error Resume Next
    MinVal = Vals(0)
    For n = 1 To UBound(Vals)
        If Vals(n) < MinVal Then MinVal = Vals(n)
    Next n
    Minimum = MinVal
End Function
Private Function Maximum(ParamArray Vals())
Dim n As Integer, MaxVal
On Error Resume Next
    MaxVal = Vals(0)
    For n = 1 To UBound(Vals)
        If Vals(n) > MaxVal Then MaxVal = Vals(n)
    Next n
    Maximum = MaxVal
End Function
Private Sub c2hsb(ByVal clr As Long)
Dim MyR As Single, MyG As Single, MyB As Single
Dim Max As Single, Min As Single
Dim MyS As Single
Dim Delta As Single, MyVal As Single
Dim cc As String * 6
Dim r1, g1, b1 As Byte
On Error Resume Next
    cc = Right("000000" + Hex$(clr), 6)
    b1 = Val("&H" + Left(cc, 2))
    g1 = Val("&H" + Mid(cc, 3, 2))
    r1 = Val("&H" + Right(cc, 2))
    MyR = r1 / 255: MyG = g1 / 255: MyB = b1 / 255
    Max = Maximum(MyR, MyG, MyB)
    Min = Minimum(MyR, MyG, MyB)
    hsbB = Int(Max * 100)
    If Max <> 0 Then
        MyS = (Max - Min) / Max * 100
    Else
        MyS = 0
    End If
    hsbS = MyS
    If hsbS = 0 Then
        hsbH = 0
    Else
        Delta = Max - Min
        Select Case Max
        Case MyR
            MyVal = (MyG - MyB) / Delta
        Case MyG
            MyVal = 2 + (MyB - MyR) / Delta
        Case MyB
            MyVal = 4 + (MyR - MyG) / Delta
        End Select
        MyVal = MyVal * 60
        If MyVal < 0 Then MyVal = MyVal + 360
        hsbH = MyVal
    End If
'   Debug.Print "hsb="; hsbH; " "; hsbS; " "; hsbB
End Sub
Private Function ColorDistance(ByVal c1 As Long, ByVal c2 As Long) As Long
Dim cd As Long
Dim h1, s1, b1, h2, s2, b2 As Single
On Error Resume Next
    If c1 = -1 Or c2 = -1 Then
        ColorDistance = 1000000
        Exit Function
    End If
    c2hsb (c1)
    h1 = hsbH / 360
    s1 = hsbS
    b1 = hsbB
    c2hsb (c2)
    h2 = hsbH / 360
    s2 = hsbS
    b2 = hsbB
    cd = Abs(h1 - h2)
    cd = cd + Abs(s1 - s2)
    cd = cd + Abs(b1 - b2)
    ColorDistance = cd
End Function
赵4老师 2013-02-05
  • 打赏
  • 举报
回复
仅供参考
Option Explicit
Dim FPFN As String 'FullPathFileName
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim t As Integer
Dim l As Integer
Dim g As Integer
Dim n As Integer
Dim x As Integer
Dim y As Integer
Dim w As Integer
Dim h As Integer
Dim a As Integer
Dim aa(0 To 9) As Integer
Dim maxa As Integer
Dim maxi As Integer
Dim b As Long
Dim nm(9) As String
Dim s As String
Dim r As String
Dim c1 As String * 1
Dim c2 As String * 1
Dim hsbH, hsbS, hsbB As Single
Private Sub Form_Load()
    FPFN = Command$
    If Left(FPFN, 1) = Chr(34) Then FPFN = Mid(FPFN, 2)
    If Right(FPFN, 1) = Chr(34) Then FPFN = Left(FPFN, Len(FPFN) - 1)
    If Not FileExists(FPFN) Then
        logtofile "[" + FPFN + "] file not find!"
        End 'form
    End If
    nm(0) = _
    "----OOO----" + _
    "--OOOOOOO--" + _
    "--OO---OO--" + _
    "-OO-----OO-" + _
    "-OO-----OO-" + _
    "-OO-----OO-" + _
    "-OO-----OO-" + _
    "-OO-----OO-" + _
    "-OO-----OO-" + _
    "-OO-----OO-" + _
    "--OO---OO--" + _
    "--OOOOOOO--" + _
    "----OOO----"
    nm(1) = _
    "----OOO----" + _
    "--OOOOO----" + _
    "--OOOOO----" + _
    "-----OO----" + _
    "-----OO----" + _
    "-----OO----" + _
    "-----OO----" + _
    "-----OO----" + _
    "-----OO----" + _
    "-----OO----" + _
    "-----OO----" + _
    "--OOOOOOOO-" + _
    "--OOOOOOOO-"
    nm(2) = _
    "--OOOOO----" + _
    "-OOOOOOO---" + _
    "-O-----OO--" + _
    "-------OO--" + _
    "-------OO--" + _
    "------OO---" + _
    "-----OO----" + _
    "----OO-----" + _
    "---OO------" + _
    "--OO-------" + _
    "-OO--------" + _
    "-OOOOOOOO--" + _
    "-OOOOOOOO--"
    nm(3) = _
    "--OOOOO----" + _
    "-OOOOOOOO--" + _
    "-O-----OO--" + _
    "-------OO--" + _
    "------OO---" + _
    "--OOOO-----" + _
    "--OOOOOO---" + _
    "------OOO--" + _
    "-------OO--" + _
    "-------OO--" + _
    "-O----OOO--" + _
    "-OOOOOOO---" + _
    "--OOOOO----"
    nm(4) = _
    "------OO---" + _
    "-----OOO---" + _
    "-----OOO---" + _
    "----OOOO---" + _
    "---OO-OO---" + _
    "---OO-OO---" + _
    "--OO--OO---" + _
    "--OO--OO---" + _
    "-OOOOOOOOO-" + _
    "-OOOOOOOOO-" + _
    "------OO---" + _
    "------OO---" + _
    "------OO---"
    nm(5) = _
    "-OOOOOOOO--" + _
    "-OOOOOOOO--" + _
    "-OO--------" + _
    "-OO--------" + _
    "-OO--------" + _
    "-OOOOO-----" + _
    "-OOOOOOO---" + _
    "------OOO--" + _
    "-------OO--" + _
    "-------OO--" + _
    "-O----OOO--" + _
    "-OOOOOOO---" + _
    "--OOOOO----"
    nm(6) = _
    "----OOOO---" + _
    "---OOOOOO--" + _
    "--OO----O--" + _
    "--OO-------" + _
    "-OO--------" + _
    "-OO-OOOO---" + _
    "-OOOOOOOO--" + _
    "-OOO---OOO-" + _
    "-OO-----OO-" + _
    "-OO-----OO-" + _
    "--OO---OOO-" + _
    "--OOOOOOO--" + _
    "----OOOO---"
    nm(7) = _
    "--OOOOOOOO-" + _
    "--OOOOOOOO-" + _
    "--------OO-" + _
    "--------O--" + _
    "-------OO--" + _
    "------OO---" + _
    "------O----" + _
    "-----OO----" + _
    "-----O-----" + _
    "----OO-----" + _
    "----OO-----" + _
    "---OO------" + _
    "---OO------"
    nm(8) = _
    "---OOOOO---" + _
    "--OOOOOOO--" + _
    "--OO---OO--" + _
    "--OO---OO--" + _
    "--OOO--O---" + _
    "---OOOOO---" + _
    "---OOOOO---" + _
    "--OO--OOO--" + _
    "-OO-----OO-" + _
    "-OO-----OO-" + _
    "-OOO---OOO-" + _
    "--OOOOOOO--" + _
    "---OOOOO---"
    nm(9) = _
    "---OOOO----" + _
    "--OOOOOOO--" + _
    "-OOO---OO--" + _
    "-OO-----OO-" + _
    "-OO-----OO-" + _
    "-OOO---OOO-" + _
    "--OOOOOOOO-" + _
    "---OOOO-OO-" + _
    "--------OO-" + _
    "-------OO--" + _
    "--O----OO--" + _
    "--OOOOOO---" + _
    "---OOOO----"
    Timer1.Enabled = True
End Sub
'未完待续
wzp144650 2013-02-05
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
如果是我,不管干扰线,只统计对应字符点阵和验证码图象中字符点阵匹配像素的百分比即可。
是一个思路啊,不过,估计J L、U Y V分不清楚啊? 这个方法你真用过吗
赵4老师 2013-02-05
  • 打赏
  • 举报
回复
如果是我,不管干扰线,只统计对应字符点阵和验证码图象中字符点阵匹配像素的百分比即可。
wzp144650 2013-02-05
  • 打赏
  • 举报
回复
引用 4 楼 dubiousway 的回复:
不太明白你的意思。你说的比对指什么跟什么的比对。是指模板匹配吗?
我做了点简单的验证码识别,步骤大概是 灰度化、二值化、然后分隔字符,还未做与样品比对的步骤,我理解中这步的步骤是,比如一个字母Z吧,我分隔完成后,得到的二指化代码是 1111 0011 0100 1111 而样品是 1111 0010 0100 1111 这样逐个字符比对下来会发现第二行最后一个不一样,但是我认为这是可以设置阀值的,有一定的容错率,比如我的容错值设置为2,那么错了1个是可以容忍的。这是我认为比较简单的一种情况。如果,比如我分隔的结果是 0001 1111 0010 0100 1111 其实就是多了一个点,先抛开为什么没有把这个点去除掉,现在就认为有这个点。 那么与样品逐个字符匹配,几乎没有字符可以匹配上,这样就很难了。。 以上是我理解中的比对方法,网上也搜了,我看大家对于比对这一步都未做详细的说明。请问我的方法是常用方法么?有没有什么妙招?

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧