0

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

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

这是我的代码:

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 中倾斜图像?我能找到的唯一功能需要目的地点,我不知道如何找到

我也觉得很奇怪,我需要在绘制之前指定返回图像的高度和宽度。我应该如何知道偏斜之前的尺寸?

编辑

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

现在问题仍然存在于算法上

首先是一个示例图像样本

我上面的算法为此示例图片返回了大约 -0.33 的结果。实际上我需要大约+4度的旋转。那么算法错了吗?还是需要将结果转换为度数?有任何想法吗?

赞赏地

4

2 回答 2

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 说明进行更新:

对于小角度 theta(以弧度测量),theta ~ sin(theta) ~ tan(theta)。因此,旋转角度(以度为单位)约为 l (180/PI) * 系数 * w / w = (180/PI) * 系数。

于 2013-03-20T11:19:26.270 回答
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 在此过程中提供的所有帮助

于 2013-03-22T10:34:23.660 回答