基于VB的hough变换和任意角度旋转

Public Sub DoRotate(Optional ByVal RotaryAngle As Long = 0) ‘任意角度旋转

Dim sDIB As New cDIB

Dim sBits() As RGBQUAD
Dim dBits() As RGBQUAD
Dim stSA As SAFEARRAY2D
Dim dtSA As SAFEARRAY2D

Dim Lev As Long
Dim Wgt As Long

Dim x As Long
Dim y As Long
Dim newW As Long, W As Long
Dim newH As Long, H As Long
Dim f1 As Double, f2 As Double

If (m_hDIB <> 0) Then

‘+++++++++++++++
Dim OldWidth, OldHeight As Integer
Dim NewWidth, NewHeight As Integer
Dim Theta As Double
Dim dx, dy As Single
Dim dxx, dyy As Integer
Dim rx0, ry0 As Double

‘ 源图四个角的坐标(以图像中心为坐标系原点)
Dim SrcX1, SrcY1, SrcX2, SrcY2, SrcX3, SrcY3, SrcX4, SrcY4, ThetaCos, ThetaSin As Double

OldWidth = m_tBIH.biWidth - 1
OldHeight = m_tBIH.biHeight - 1

SrcX1 = -(OldWidth - 1) / 2
SrcY1 = (OldHeight - 1) / 2
SrcX2 = (OldWidth - 1) / 2
SrcY2 = (OldHeight - 1) / 2
SrcX3 = -(OldWidth - 1) / 2
SrcY3 = -(OldHeight - 1) / 2
SrcX4 = (OldWidth - 1) / 2
SrcY4 = -(OldHeight - 1) / 2

Theta = RotaryAngle / 180 * 3.141592653
ThetaCos = Cos(Theta)
ThetaSin = Sin(Theta)

‘// 旋转后四个角的坐标(以图像中心为坐标系原点)
Dim DstX1, DstY1, DstX2, DstY2, DstX3, DstY3, DstX4, DstY4 As Double
DstX1 = Cos(Theta) * SrcX1 + Sin(Theta) * SrcY1
DstY1 = -Sin(Theta) * SrcX1 + Cos(Theta) * SrcY1
DstX2 = Cos(Theta) * SrcX2 + Sin(Theta) * SrcY2
DstY2 = -Sin(Theta) * SrcX2 + Cos(Theta) * SrcY2
DstX3 = Cos(Theta) * SrcX3 + Sin(Theta) * SrcY3
DstY3 = -Sin(Theta) * SrcX3 + Cos(Theta) * SrcY3
DstX4 = Cos(Theta) * SrcX4 + Sin(Theta) * SrcY4
DstY4 = -Sin(Theta) * SrcX4 + Cos(Theta) * SrcY4

NewWidth = IIf(Abs(DstX4 - DstX1) > Abs(DstX3 - DstX2), Abs(DstX4 - DstX1), Abs(DstX3 - DstX2)) + 0.5 ‘+ 50
NewHeight = IIf(Abs(DstY4 - DstY1) > Abs(DstY3 - DstY2), Abs(DstY4 - DstY1), Abs(DstY3 - DstY2)) + 0.5 ‘+ 50

rx0 = OldWidth * 0.5 ‘(rx0,ry0)为旋转中心
ry0 = OldHeight * 0.5

f1 = -0.5 * (NewWidth - 1) * ThetaCos + 0.5 * (NewHeight - 1) * ThetaSin + 0.5 * (OldWidth - 1)
f2 = -0.5 * (NewWidth - 1) * ThetaSin - 0.5 * (NewHeight - 1) * ThetaCos + 0.5 * (OldHeight - 1)

‘+++++++++++++++

‘-- Get source Bits
Call sDIB.Create(m_tBIH.biWidth, m_tBIH.biHeight)
Call sDIB.LoadBlt(m_hDC)
Call pvBuildSA(stSA, sDIB)
Call CopyMemory(ByVal VarPtrArray(sBits()), VarPtr(stSA), 4)

‘-- Create new DIB
Call Create(NewWidth, NewHeight)
Call pvBuildSA(dtSA, Me)
Call CopyMemory(ByVal VarPtrArray(dBits()), VarPtr(dtSA), 4)

W = NewWidth
H = NewHeight

For y = 1 To H - 1
For x = 1 To W - 1
With dBits(x, y)

dxx = CInt(x * ThetaCos - y * ThetaSin + f1 + 0.5)
dyy = CInt(x * ThetaSin + y * ThetaCos + f2 + 0.5)

If dxx > 0 And dyy > 0 And dxx < OldWidth And dyy < OldHeight Then
.B = sBits(dxx, dyy).B
.G = sBits(dxx, dyy).G
.R = sBits(dxx, dyy).R
Else
.B = 0
.G = 0
.R = 0
End If
End With
Next x
RaiseEvent Progress(y)
Next y
Call CopyMemory(ByVal VarPtrArray(sBits), 0&, 4)
Call CopyMemory(ByVal VarPtrArray(dBits), 0&, 4)
RaiseEvent ProgressEnd
End If
End Sub

+++++++++++++++

Public Function Hungh(DIB As cDIB, Optional ByVal Level As Byte = 95) As Integer ‘二值化

Dim Bits() As RGBQUAD
Dim tSA As SAFEARRAY2D

Dim L As Byte

Dim npp(0 To 180, 0 To 1000) As Integer ‘hungh变换后数组
Dim maxA, kmax, pMax, mp, tempL As Integer ‘最大角度 180
Dim Radian As Double
Dim m, n, k As Integer
Dim p As Integer ‘hough变换中的距离参数
maxA = 180
kmax = 0 ‘记录最长直线的角度
pMax = 0 ‘记录最长直线的距离

Radian = 3.141592653 / 180

If (DIB.hDIB <> 0) Then

pvBuildSA tSA, DIB
CopyMemory ByVal VarPtrArray(Bits()), VarPtr(tSA), 4

W = DIB.Width - 1
H = DIB.Height - 1

mp = Sqr(W * W + H * H)

For y = 2 To H - 2
For x = 2 To W - 2
With Bits(x, y)
L = 0.114 * .B + 0.587 * .G + 0.299 * .R
If L = 0 Then
For k = 1 To maxA

p = CInt(x * Cos(Radian * k) + y * Sin(Radian * k)) ‘p hough变换中的距离参数
p = CInt(p / 2 + mp / 2) ‘对P值优化,防止为负值
‘If p < 0 Then Stop
npp(k, p) = npp(k, p) + 1 ‘npp对变换域中对应重复出现的点累加

Next k
End If

End With
Next x
RaiseEvent Progress(y)
Next y

For m = 1 To maxA ‘maxa=180
For n = 1 To mp ‘mp为原图对角线距离
If npp(m, n) > tempL Then
tempL = npp(m, n) ‘找出最长直线 tempL为中间变量用于比较
kmax = m ‘记录最长直线的角度
pMax = n ‘记录最长直线的距离
End If
Next n

Next m

For y = 2 To H - 2
For x = 2 To W - 2
With Bits(x, y)
L = 0.114 * .B + 0.587 * .G + 0.299 * .R
If L = 0 Then

p = CInt(x * Cos(Radian * kmax) + y * Sin(Radian * kmax)) ‘p hough变换中的距离参数
p = CInt(p / 2 + mp / 2) ‘对P值优化,防止为负值

If p = pMax Then
.G = 0
.B = 255
.R = 0
End If

End If

End With
Next x
RaiseEvent Progress(y)
Next y

Hungh = kmax - 90
‘MsgBox kmax - 90

Call CopyMemory(ByVal VarPtrArray(Bits), 0&, 4)
RaiseEvent ProgressEnd
End If
End Function

时间: 2024-10-20 08:29:29

基于VB的hough变换和任意角度旋转的相关文章

Java实现图片内容无损任意角度旋转

转自:http://blog.csdn.net/heliang7/article/details/7309394 主要问题是如何在图片做旋转后计算出新图片的长宽. 在java 2d和基本math库的帮助下,其实利用简单的计算就可以知道. 以下算法只是计算出旋转小于90度时的公式.当旋转大于90时,可以先把问题域换算到锐角的情况,再进行计算即可. 如下图所示,需要计算出来的是len_delta的长度,就是有双竖线的位置,它是新图片要增加的宽.(要增加的高度同理可得.) 其实只要知道len的长度,还

Winform以任意角度旋转PictureBox中的图片的方法

方法1: private void RotateFormCenter(PictureBox pb, float angle) { Image img = pb.Image; int newWidth = Math.Max(img.Height, img.Width); Bitmap bmp = new Bitmap(newWidth, newWidth); Graphics g = Graphics.FromImage(bmp); Matrix x = new Matrix(); PointF

Hough变换直线检测

Hough变换直线检测 [email protected] http://blog.csdn.net/kezunhai 霍夫变换是图像变换中的经典算法之一,主要用来从图像中分离出具有某种相同特征的几何形状(如,直线,圆等).霍夫变换寻找直线与圆的方法相比与其它方法可以更好的减少噪声干扰.Hough变换的基本原理在于利用点与线的对偶性,将原始图像空间的曲线通过转换到参数空间的一个点. 从图中可以看到,x-y坐标和K-b坐标有点--线的对偶性.x-y坐标中的P1.P2对应于k-b坐标中的L1.L2:

Hough 变换

作用 霍夫变换是常用的图像变换,用于在图像中寻找直线.圆.椭圆等这类具有相同特征的几何图形.在许多应用场合中,都需要实现对特定形状物体的快速定位,而霍夫变换由于其对方向和噪声不敏感,因此在这类应用中发挥着重要作用. 原理 霍夫变换最基本的思想通俗讲就是将图像中所有可能出现的几何图形位置进行遍历,以直线检测为例,就是在整幅图像中进行扫描所有可能的直线,看图像中的像素点对各直线的贡献.下面以直线为例,形象地进行介绍: 图 1.霍夫变换示意图 如图1所示,矩形点阵表示图像,黑色的点表示边缘的像素点.霍

Hough变换检测椭圆

 由椭圆的公式(1)可得,确定一个椭圆需要5个参数,a,b 为椭圆的长轴和段轴,P,Q 为椭圆中心坐标,θ为椭圆的旋转角度.如果用传统的Hough变换方法,参数空间需要五维.这种方法在计算过程中所耗费的时间和空间资源是惊人的,根本无法应用于实际.为此,人们提出了很多新的改进算法. 改进算法主要分为两种: 1)随机Hough变换(RHT),采用多到一的映射,但是随机采样会带来大量无效的计算,当点数很大时,算法的性能急剧下降. 2)利用椭圆的几何特征降低参数的维度. 本文所提出的椭圆检测方法也是基于

Opencv图像识别从零到精通(22)-----hough变换检测直线与圆

今天要看的是霍夫变换,常用用来检测直线和圆,这里是把常见的笛卡尔坐标系转换成极坐标下,进行累计峰值的极大值,确定.HoughLines,HoughLinesP,HoughCircles,三个函数,首先先看看原理,最后会用漂亮的matlab图,来回归一下,霍夫直线变换. 霍夫线变换: 众所周知, 一条直线在图像二维空间可由两个变量表示. 例如: 在 笛卡尔坐标系: 可由参数:  斜率和截距表示. 在 极坐标系: 可由参数:  极径和极角表示 对于霍夫变换, 我们将用 极坐标系 来表示直线. 因此,

SIFT/SURF、haar特征、广义hough变换的特性对比分析[z]

 SIFT/SURF基于灰度图, 一.首先建立图像金字塔,形成三维的图像空间,通过Hessian矩阵获取每一层的局部极大值,然后进行在极值点周围26个点进行NMS,从而得到粗略的特征点,再使用二次插值法得到精确特征点所在的层(尺度),即完成了尺度不变. 二.在特征点选取一个与尺度相应的邻域,求出主方向,其中SIFT采用在一个正方形邻域内统计所有点的梯度方向,找到占80%以上的方向作为主方向:而SURF则选择圆形邻域,并且使用活动扇形的方法求出特征点主方向,以主方向对齐即完成旋转不变. 三.以主方

hough变换检测直线

hough变换检测直线原理: 假设在图像中存在一条直线y=k*x+b(此时k,b未知).取直线上的任意两点进行说明,设为(x0,y0),(x1,y1). 所有经过点(x0,y0)的直线满足:-x0*k+y0=b ---式1,那么以k.b为直角坐标轴做式1对应直线: 所有经过点(x1,y1)的直线满足:-x1*k+y1=b ---式2,那么以k.b为直角坐标轴做式2对应直线: 两直线交于一点(kk,bb),此时该交点对应的直线y=kk*x+bb就是(x0,y0),(x1,y1)所确定的直线. 在h

Python下opencv使用笔记(十一)(详解hough变换检测直线与圆)

在数字图像中,往往存在着一些特殊形状的几何图形,像检测马路边一条直线,检测人眼的圆形等等,有时我们需要把这些特定图形检测出来,hough变换就是这样一种检测的工具. Hough变换的原理是将特定图形上的点变换到一组参数空间上,根据参数空间点的累计结果找到一个极大值对应的解,那么这个解就对应着要寻找的几何形状的参数(比如说直线,那么就会得到直线的斜率k与常熟b,圆就会得到圆心与半径等等). 关于hough变换,核心以及难点就是关于就是有原始空间到参数空间的变换上.以直线检测为例,假设有一条直线L,