按角度去偏斜图像

时间:2013-03-19 15:11:57

标签: .net vb.net bitmap rotation angle

我花了几个小时研究这个并且我已经取得了一些进展但仍需要一些帮助。

我知道有些库可以做到这一点,但由于我的场景非常简单,我宁愿拥有自己的代码。我在支票扫描仪中扫描支票,但有些图像弯曲,需要去掉;

这是我的代码:

Function DeskewImage(Original As Bitmap) As Bitmap
    Dim w = Original.Width
    Dim h = Original.Height
    'i go over the first 200 rows of pixels and for each row i get the first black pixel. this should be enough to get me the angle
    Dim FirstBlacks As New List(Of Point)
    For row = 0 To 200
        For col = 0 To w - 1
            Dim p = Original.GetPixel(col, row)
            Dim rl = CInt(p.R) + p.G + p.B
            If rl < 760 Then
                FirstBlacks.Add(New Point(col, row))
                Exit For
            End If
        Next
    Next
    'here i try to get the angle, im not sure its correct though
    Dim xyAvg = FirstBlacks.Select(Function(pnt) pnt.X * pnt.Y).Average
    Dim xAvg = FirstBlacks.Select(Function(pnt) pnt.X).Average
    Dim yAvg = FirstBlacks.Select(Function(pnt) pnt.Y).Average
    Dim xVar = FirstBlacks.Select(Function(pnt) pnt.X).Variance
    Dim coefficient = (xyAvg - xAvg * yAvg) / xVar
    Dim LeftTop = -20
    'now id like utilize the angle to skew
    Dim destinationPoints = {New Point(0, LeftTop), New Point(w, 0), New Point(0, h)}
    Dim ret = New Bitmap(w, h)
    Dim g = Graphics.FromImage(ret)
    g.DrawImage(Original, destinationPoints)
    ret.Save("D:\aa.jpg")
    Return Original
End Function

我有两个问题:

  1. 我的系数是否正确?这是基于这里的一篇文章     http://www.experts-exchange.com/Microsoft/Development/MS_Access/A_2799-Simple-Linear-Regression-in-MS-Access.html     但我不确定我是否正确移植了
  2. 如何利用系数来扭曲.net中的图像?唯一的 功能,我可以     找到需要的目的地点,我有         不知道怎么找
  3. 我也觉得很奇怪,我需要指定高度&amp;绘图前返回图像的宽度。我怎么知道歪斜之前的大小?

    修改

    感谢Pieter Geerkens我将代码更改为旋转而不是倾斜

    问题现在仍然存在于算法

    首先是一个样本图像sample

    我上面的算法返回了大约-0.33这个样本图片的结果。实际上我需要大约+4度旋转。算法错了吗?或者结果是否需要转换为度?任何想法?

    欣赏

2 个答案:

答案 0 :(得分:1)

尝试更改destinationPoints的分配,如下所示:

Dim dh = coefficient * h
Dim dw = coefficient * w
Dim destinationPoints = { 
  New Point(0, LeftTop), 
  New Point(w,-dw), 
  New Point(dh, h) 
}

根据以下OP说明进行更新:

对于小角度θ(以弧度表示),θ~sin(θ)~tan(θ)。因此,旋转角度(以度为单位)约为1(180 / PI)*系数* w / w =(180 / PI)*系数。

答案 1 :(得分:0)

行。感谢http://www.alcula.com/calculators/statistics/linear-regression/我能够调试我的算法结果。这个工具帮我发现我实际上正在混合xs和ys。正确的代码如下。

我也不得不忽略低x值,这实际上是左边界,而不是顶边。

Dim ret As Double?
    Dim w = Original.Width
    Dim h = Original.Height
    Dim FirstBlacks = New List(Of Point)
    Dim MaxHeight = h - 1
    Dim done = False
    For y = 0 To MaxHeight
        If done Then Exit For
        For x = 0 To w - 1
            Dim p = Original.GetPixel(x, y)
            Dim rl = p.GetBrightness
            If rl < 1 Then
                If x < 20 Then
                    done = True
                Else
                    FirstBlacks.Add(New Point(x, y))
                End If
                Exit For
            End If
        Next
    Next
    If FirstBlacks.Count > 2 Then
        Dim xyAvg = FirstBlacks.Select(Function(pnt) pnt.X * pnt.Y).Average
        Dim xAvg = FirstBlacks.Select(Function(pnt) pnt.X).Average
        Dim yAvg = FirstBlacks.Select(Function(pnt) pnt.Y).Average
        Dim xVar = FirstBlacks.Select(Function(pnt) pnt.X).Variance
        ret = (xyAvg - xAvg * yAvg) / xVar
    End If
    Return ret

感谢Pieter-Geerkens一路上的所有帮助