这才是我当年写出的一个比较烂的程序
@Z=y'yc'y. v0H>iKh7 Main2.bas
1VPN#Q! Tg{dIh.Q~O Attribute VB_Name = "SubMain"
n)wpxR Option Explicit
i+T0}M< kHo;9j-U '采集文件与临时文件
o}AqNw60v Public Const TmpFile As String = "d:\30-0600.dat"
~;O=
7 '已有数据:30-0600.dat /30日早6点进车与6:30出车头
]>S$R&a *fuGVA Public fStatus As Long, hFile As Long, bytesRW As Long, lptrFile As Long
HpjIp. Public hBCFile As Long '记录采集参数的文件
=%nqMV(y Public Const TmpBMP As String = "d:\1.bmp"
e)
/u>I Public hTmpFile As Long
!z4Hj{A_ -c<1H)W Lu#@~ '采集窗口参数常量
/KJx n6 Public Const FrameH As Long = 280&
yrK--
C8 Public Const FrameW As Long = 768&
5
a*'N~ Public Const pFrameSize As Long = FrameW * FrameH
ke;*uS d= T9mj.@ '标志区范围,用于识别车辆
!tFU9Zt Public Const PilarC As Integer = 260 '识别标志立柱中线坐标X
f'zFg["aZS Public Const mkW As Integer = 28 '识别标志立柱宽度
7]HIE]# Public Const mkH As Integer = 80 ''识别标志立柱高度(上白中黑下白)
_
/28Cw Public Const mkY As Integer = 4 ''识别标志立柱Y坐标(40-79白, 80-119黑,120-159白)
K&"Pm9
Public Const mkX As Integer = PilarC - mkW / 2 '识别标志立柱X坐标
);/5#b@<Y '车缝检测位置常数
RGPU~L Public Const sSize As Long = 32&
e&a[k Public Const sPos As Long = 310&
xzGsfd Public Const sPosL As Long = 200&
48"Y-TV Public Const sPosR As Long = 500&
U~zN*2- '车缝检测框位置
ekk&TTp# Public Slice(1 To sSize, 1 To FrameH) As Byte
?` ZGM Public SliceL(1 To sSize, 1 To FrameH) As Byte
ZC\.};. Public SliceR(1 To sSize, 1 To FrameH) As Byte
hz~CW-47 Public avSL As Integer, avSLR As Integer, avSLL As Integer
iR}i42Cu 7+Jma! o %Cbc@=k Public MKpilar(1 To mkW * mkH) As Byte '一维数组用于亮度对比度分析,比使用二维数组更便于VB编译优化
uK&wS#uY '该数组用于亮度对比度调节、车辆通过识别与车皮间隔识别
h+'eFAZ Public BsLine(1 To 4 * FrameW) As Byte, bsAV As Integer '图像的前4行。用于确定标志区的亮度与对比度范围
$xn%i\ Public PilarW As Long, PilarH As Long, PilarX As Long, PilarY As Long
(=&bo p Public LeftBK(1 To 1024, 0 To 1) As Byte, RightBK(1 To 1024, 0 To 1) As Byte
L!}j3(I '前后帧左右上角128列*8行像素块,根据平均值差绝对值判断进车方向
?\p%Mx? |Nx!g fU :Ro"
0/d Iz$W3#hi '一次连续采集的帧数
51(`wo>LS Public tFrames As Long
B6!<@*BI WUOPYYW<o '在采集卡申请的缓存中,是按帧为单位的,每一帧包含奇偶场两场的数据
|EEz>ci '而该卡的硬件设置是按场采集,只需要读第一场的数据即可。
S
bqM=I+ '所以要设置的缓存帧的大小是frameW*frameH*2,而一场的数据量为pFrameSize
p~zT
Rnm a518N*]j Public pFRAME(1 To FrameW, 1 To FrameH) As Byte
o!_; H}pq Public pBuffer(1 To FrameW * FrameH * 2) As Byte
Q j~W-^/ - Public pWorkSpace(1 To FrameW * FrameH) As Long
(9[C0e S Public Const pBufferSize As Long = FrameW * FrameH * 2
[{!j9E?( Public pGray(0 To 255) As Long '整幅图像的灰度直方图
[email protected] [ u{lDof> Public hBoard As Long '采集卡标识
/*p?UW<*4 Public mBufferAddr As Long '缓存地址
*$Wx*Jo Public BufferSize As Long '缓存大小(字节)
Kd[`m
kmS Public iCurrentCard As Long
,DUQto Public CapStatus As Long
2Z9gOd<M~ Public iFrames As Long
G|Yp<W%o Public currentBr As Byte, currentContr As Byte
n~>CE"q D!E 9@*Lf Public hMEM As Long, mStatus As Long
]B.,7 Public Const hMemSize As Long = pFrameSize * 4
.gsu_N_v Public hMemWork As Long
yLa5tv/ Public Const hMemWorkSize As Long = pFrameSize * 5
"E[*rnsLN =
]HJa ZzaW@6LJF -0J<R;cVs '串口接收轨道衡数据
AiHDoV+- Public WeightFromCom As String
'*{Rn
7B5 Public bReceiveComplete As Boolean
u9~V2>r\ s1b\I6&:J $8 ww]}K Public Type GrayBMPHeader
A5H
8+gATK Tag As Integer
k49n9EX FileLength As Long '文件大小
xA1pDrfC/ Reserve1 As Long
q}24U3ow DataOffset As Long '图像数据偏移量
]=XL9MI BMPHeaderSize As Long '文件头长
@_:?N(%( 'length of the bitmap info header used to describe the bitmap colors, compression,…
(a4y1k t- 'the following sizes are possible:
J3}C T '28h - windows 3.1x, 95, nt, …
m_ONsZHy '0ch - os/2 1.x
jE5
9h 'f0h - os/2 2.x
Fu$Gl$qV?% O09g b[ ImageWidth As Long '图像宽(像素数)
`[u>NEb ImageHeight As Long '图像高(像素数)
!";$Zu PlaneNumber As Integer '图像层数
5N</Z6f'o bpp As Integer 'bits per pixels '1 - monochrome bitmap
NTX+7< '4 - 16 color bitmap
[-94=|S @ '8 - 256 color bitmap
52R.L9Ai '16 - 16bit (high color) bitmap
RuEnr7gi '24 - 24bit (true color) bitmap
*wZV*)} '32 - 32bit (true color) bitmap
GN"LU>9| Compression As Long '压缩方法 '0 - none (also identified by bi_rgb)
GQAg
ex)D '1 - rle 8-bit / pixel (also identified by bi_rle4)
^|12~d_.T '2 - rle 4-bit / pixel (also identified by bi_rle8)
<+JFa
l '3 - bitfields (also identified by bi_bitfields)
0J,d9a [1 IMAGESIZE As Long '图像数据字节数
P*=3$-` hResolution As Long '水平分辩率 像素数/米
Jt^JE{m9% vResolution As Long '垂直分辩率
.xQ'^P_q ColorsinBMP As Long '图中所用的颜色。对256色图像总为0x100
M@ZpgAfq ImportantColors As Long
<T~fh>a Pallate(0 To 255) As Long '图像每个值对应的实际显示颜色,项数对应PallateNumber所指调色板项数
jl%eO. End Type
1UWgOCc EC\:uK
k#G7`dJl 48*pKbbM4 Public BMPHeader As GrayBMPHeader, BMP1 As GrayBMPHeader
QL!+.y% Public sRECT As RECT
;x
C~{O 6D]G*gwk[ /faP]J) Public conn As ADODB.Connection
t-m,~Io W Public rsTrain As ADODB.Recordset
&zDFf9w2{ Public rsOperater As ADODB.Recordset
Pb&+(j Public rsGoods As ADODB.Recordset
Jy
NY * Public rsGood2 As ADODB.Recordset
Z 2jMBe Public rsSender As ADODB.Recordset
-.3k
vL Public rsReceover As ADODB.Recordset
D_kzR
Public rsTrainTMP As ADODB.Recordset
mP+yjRw on&=%tCAL n&&U9sf? '打开采集卡
6? ly.h$ '设置参数
:rc[j@|pH '设置为实时单帧采集到缓存方式
X51$5% '由另一线程查询采集状态,如果完成采集,传送至用户数组分析或保存
Fd.d( 1MFpuPJk 4gt "dfy+ Sub Main()
zC;lfy{f= Dim i As Integer, status As Long
e[o
;l
&8L\FAY0%9 InitBMPinfo
9rc
n*sm '生成BMP文件头---该文件头是固定将pFRAME数组写成BMP文件
^moIMFl BMPHeader.Tag = &H4D42
TmH13N] BMPHeader.ImageWidth = FrameW
hds4_ BMPHeader.ImageHeight = FrameH
eT
Hh BMPHeader.BMPHeaderSize = &H28
l+qtA~V&2 BMPHeader.PlaneNumber = 1
<T[ui BMPHeader.bpp = 8
epyYo&x} BMPHeader.Compression = 0
m)w-mc BMPHeader.hResolution = &H1274 'Windows pBrush.exe的默认值,PhotoED.exe默值为0
qn
V9TeU) BMPHeader.vResolution = &H1274
<R%6L& BMPHeader.ColorsinBMP = 256
\>
azY
g BMPHeader.ImportantColors = BMPHeader.ColorsinBMP
pC
Is+1O/ BMPHeader.DataOffset = Len(BMPHeader)
!9OgA For i = 0 To 255
()JDjzQT BMPHeader.Pallate(i) = RGB(i, i, i)
k}qiIMdI Next i
hvZR4|k> BMPHeader.IMAGESIZE = FrameH * FrameW
CUcjJ|MZ BMPHeader.FileLength = Len(BMPHeader) + BMPHeader.IMAGESIZE
mQuaO#
I, @y&,e,3! =x]dP. MoveMemory BMP1, BMPHeader, Len(BMPHeader)
1D DOUV
bd;f@)X BMP1.ImageWidth = FrameW
cYS+XBz BMP1.ImageHeight = FrameH * 2
k=
1+mG BMP1.IMAGESIZE = BMP1.ImageWidth * BMP1.ImageHeight
SXF_)1QO\W BMP1.FileLength = Len(BMP1) + BMP1.IMAGESIZE
!}48;P l L#bQ`t '确定标志位置,为pilarX, pilarY确定初始值
ay[*b_f PilarW = mkW
GQWTQIl] PilarH = mkH '此两项为固定值
d'D\#+%>= PilarX = GetSetting(App.EXEName, "Mark", "MarkX", mkX)
?"u-@E[m PilarY = GetSetting(App.EXEName, "Mark", "MarkY", mkY) '此两项需要在程序初始化时检查并进行调整
Ux]@prA q S*:w\nXP~
>ON.ftZi '连续采集记录文件
]iX$p~riH ' 建立一个缓冲区为页对齐方式的文件
Rj=Om If Dir(TmpFile) <> "" Then
DlO;EH hFile = CreateFile(TmpFile, GENERIC_READ Or GENERIC_WRITE, _
(LPD 0&, 0&, OPEN_ALWAYS, FILE_FLAG_NO_BUFFERING, 0&)
S`.-D+.68 ' 在95/98中,如果打开文件时没有声明overlapped方式,在读定文件时就不能使用overlapped参数项
F\72^,0 ' 而必须用setfilepointer函数调节与操作系统保留的文件指针。
I ^92b Else
F'*4:WD7 hFile = CreateFile(TmpFile, GENERIC_READ Or GENERIC_WRITE, _
- mXr6R? 0&, 0&, CREATE_ALWAYS, FILE_FLAG_NO_BUFFERING, 0&)
{mGWMv End If
VHNiTp If hFile = 0 Then
" V2$g MsgBox TmpFile & ": File Open Error", vbOKOnly
C>ZeG
Vq Exit Sub
L<`g}iw End If
9x,+G['Zt '采集参数记录文件
)5x?Qn (B hBCFile = FreeFile()
KHiJOeLc Open TmpFile + ".BC" For Binary Access Read Write As #hBCFile
OO>2oH zf u78 hMEM = VirtualAlloc(ByVal 0&, hMemSize, MEM_COMMIT, PAGE_READWRITE) ’分配系统内容
*?Y6qalSy If hMEM = 0 Then
5)6%D fStatus = GetLastError
+06j+I MsgBox "内存分配错误: 错误代码 - " & Str(fStatus) & vbCrLf _
n3,wwymQ & "请向技术人员报告该错误代码。", vbOKOnly
gu&oCT CloseHandle hFile
P2F>iK#U Exit Sub
G$<0_0GF End If
px@\b]/ H:6$)# hMemWork = VirtualAlloc(ByVal 0&, hMemWorkSize, MEM_COMMIT, PAGE_READWRITE)
0k
[6 If hMemWork = 0 Then
INpub5 fStatus = GetLastError
"
z{w^k MsgBox "内存分配错误: 错误代码 - " & Str(fStatus) & vbCrLf _
_r'M^=yx[ & "请向技术人员报告该错误代码。", vbOKOnly
N4-J !r@#~ '释放已成功分配的内存
,iUx'U mStatus = VirtualFree(ByVal hMEM, hMemSize, MEM_DECOMMIT)
l0)uu4| mStatus = VirtualFree(ByVal hMEM, 0&, MEM_RELEASE)
#m>mYp8E.5 q5PYc.E([ CloseHandle hFile
\>k+Oyj Exit Sub
7i
/Cax End If
BZ9iy~ "dTXT ' Test writing
Q8i6kf! 'WriteFile hFile, ByVal hMEM, ByVal 4096&, bytesRW, ByVal 0&
{c;3$ dW68lVWq_ '初始化采集卡参数
]+P
&Y: iCurrentCard = -1
W9"I++~f hBoard = okOpenBoard(iCurrentCard)
=ndKG5 Debug.Print hBoard
ak[)+_k_ If hBoard = 0 Then
TVA1FD ExitGrabber
O6]~5&8U. End
W[s>TDc`v End If
AF6'JxG7 okGetBufferSize hBoard, mBufferAddr, BufferSize
ba13^;fm# If mBufferAddr = 0 Then
H=C;g)R MsgBox "缓存不存在!"
cK&o
C$[r- ExitGrabber
=@o} End If
63=m11Z4 Debug.Print Hex(mBufferAddr), Hex(BufferSize)
KHtY
+93 AAcbY; I"4B1g currentBr = 128: currentContr = 128
Ip0q&i<6 '设置视频输入参数
.<dmdqk] okSetVideoParam hBoard, VIDEO_SOURCECHAN, 1 'Video2
v!Z 9T ' lParam=0,1.. Comp.Video; 0x100,101...to Y/C(S-Video), 0x200,0x201 to RGB Chan.Input
CgC wM=!r okSetVideoParam hBoard, VIDEO_BRIGHTNESS, currentBr '亮度
4aC#Cv:0 okSetVideoParam hBoard, VIDEO_CONTRAST, currentContr '对比度 ---初始设置条件下如果图像亮度达不到基本要求则控制灯光
3I+pe; okSetVideoParam hBoard, VIDEO_RGBFORMAT, FORM_GRAY8 '8位灰度模式
C+5nft6: okSetVideoParam hBoard, VIDEO_TVSTANDARD, 0 'PAL制式
8vK&d> okSetVideoParam hBoard, VIDEO_SIGNALTYPE, &H10000 '逐行(低字)同步开槽(高字)
J^4k} okSetVideoParam hBoard, VIDEO_RECTSHIFT, 144 + &H2C0000 '有效区起始位置:高字Y偏移,低字X偏移 (144/44经验值)
2wCRT}C okSetVideoParam hBoard, VIDEO_AVAILRECTSIZE, FrameW + FrameH * 2 * &H10000 '有效区大小:低字X高字Y (768/576采集卡最大值)
8n? .w:Y/ okSetVideoParam hBoard, VIDEO_FREQSEG, 0 ' 低频部分信号
tw66
XxE >.|gmo>b '设置采集参数
@Rm/g#!h" okSetCaptureParam hBoard, CAPTURE_INTERVAL, 0 '逐帧
LNkyV*TI okSetCaptureParam hBoard, CAPTURE_CLIPMODE, 2 '裁剪方式
nmr>Aj8[ okSetCaptureParam hBoard, CAPTURE_BUFRGBFORMAT, FORM_GRAY8 '8位灰度
/&yT2p okSetCaptureParam hBoard, CAPTURE_HARDMIRROR, 0 '不作镜像变换
a2TC, okSetCaptureParam hBoard, CAPTURE_FRMRGBFORMAT, FORM_GRAY8 '帧存格式
g:U ul4 okSetCaptureParam hBoard, CAPTURE_SAMPLEFIELD, 0 ' 逐场采集
j7&l&)5 okSetCaptureParam hBoard, CAPTURE_HORZPIXELS, 944 '水平像素数 PAL制式固定值
4KCxhJq okSetCaptureParam hBoard, CAPTURE_VERTLINES, 625 '垂直线数
+Sfv.6~v okSetCaptureParam hBoard, CAPTURE_SEQCAPWAIT, 0 '不等结束立即返回
e=2D^G#qE 'okSetCaptureParam hBoard, CAPTURE_BUFBLOCKSIZE, FrameW + FrameH * 2 * &H10000
F*f)Dv$p 'Buffer Block Size不用设置,而用okSetTargetRect函数进行动态调节
q@:&^CS LxT ]- lS^0*(Y okCloseBoard hBoard
@zbXG_J Sleep 50
s><co] hBoard = okOpenBoard(iCurrentCard) '关闭后重新打开使新的设置值生效
00i9yC8@6 (agdgy:# '设置数据传送方式
.FU EF) 'okSetConvertParam hBoard, CONVERT_FIELDEXTEND, FIELD_COPYEXTEND '逐行并扩展行
;/@R{G{+~; '该设置对本程序无意义,因为程序直接用CopyMemory方法读缓存,而扩展行方式是在用采集卡内置函数读RECT过程中实现的。
W=!f
U{EW +> sRECT.Right = -1 '用于获得当前设置值
q<VhP2R iFrames = okSetTargetRect(hBoard, BUFFER, sRECT)
(P ?9Jct Debug.Print sRECT.Left, sRECT.Right, sRECT.Top, sRECT.Bottom
T (qu
~} Debug.Print okSetCaptureParam(hBoard, CAPTURE_BUFBLOCKSIZE, -1) 'FrameW + FrameH * &H10000
cO:x{~ sRECT.Left = 0
i(WWF#N5 sRECT.Top = 0
2xX7dl(cC sRECT.Right = sRECT.Left + FrameW
L6^h3*JyD sRECT.Bottom = sRECT.Top + FrameH * 2
cu-WY8n
iFrames = okSetTargetRect(hBoard, BUFFER, sRECT)
Ty=}A MMyE E_K7.c4M sRECT.Right = -1 '检查新设置值
:R)IaJ6) iFrames = okSetTargetRect(hBoard, BUFFER, sRECT)
E'Bt1u Debug.Print sRECT.Left, sRECT.Right, sRECT.Top, sRECT.Bottom
.
fIodk Debug.Print Hex(okSetCaptureParam(hBoard, CAPTURE_BUFBLOCKSIZE, -1))
a;K:~R+@, isjkfl-! If TESTSignal = False Then
]l%j>Vb!L 'ExitGrabber
k;sUD mrO End If
S~T[*Z/m =u(fP" |{ Gkl#s7' Ot?rsr '设为实时采集状态
7u zN/LAF 'iFrames = okCaptureActive(hBoard, BUFFER, 0&)
xk/(|f{L >qE$:V"_5 t`Sh!e '单帧采集
U&6f}=vC 'okWaitSignalEvent hBoard, EVENT_FRAMEHEADER, -1
[#:k3aFz 'iFrames = okCaptureSingle(hBoard, BUFFER, 0&)
Ev%\YI!MaY okCaptureTo hBoard, BUFFER, 0, 1 'single
QU t!fF@t 'Do While okGetCaptureStatus(hBoard, False) <> 0
V+^\SiM ' Sleep 20
v,jU9D\ 'Loop
D)Zv okGetCaptureStatus hBoard, True
4:.M
*Dz MoveMemory pFRAME(1, 1), ByVal mBufferAddr, pFrameSize
x-1[2K1"[ '写入768*576测试图象
^N]*Zf~N? ArrayToBMP TmpBMP
oW6.c]Vo WCH>9Z>cj '打开数据库
>9 iv> Set conn = New ADODB.Connection
}^H_|;e1p conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
zSu2B6YU} "Persist Security Info=False;Data Source=" & "c:\train\train.mdb" & _
Xy._&&pt "; Mode=Read|Write"
?g'l/xuRe conn.Open
W;=ZQ5Lw \21!NPXH2 frmRecord.Picture1.Picture = LoadPicture(TmpBMP)
"k.<" pf frmRecord.Visible = True
jzQgDed ] frmQuery.Visible = True
6vDgMfw Load frmReceiveFromComm
E~B
LY{3: Fq8Z:;C8 '调试参数
[(C lvGx If InStr(UCase(Command()), "/CAPTURE") > 0 Then
y3x_B@}BY SignalBox.Visible = True
<%5ny!] End If
\?j(U8mB> If InStr(UCase(Command()), "/COMM") > 0 Then
*d=pK*g frmReceiveFromComm.Visible = True
u>BR WN End If
%vW@_A~ VD4( End Sub
kW"N~Xw) %:NI@59 Sub ExitGrabber()
!59q@Mya[ '关闭数据库
ZR1EtvVG '关闭采集卡
6Pz\6DU,I mStatus = VirtualFree(ByVal hMEM, hMemSize, MEM_DECOMMIT)
d$!ibL#o mStatus = VirtualFree(ByVal hMEM, 0&, MEM_RELEASE)
OA_
%%A;o mStatus = VirtualFree(ByVal hMemWork, hMemWorkSize, MEM_DECOMMIT)
8W{R&Z7aL mStatus = VirtualFree(ByVal hMemWork, 0&, MEM_RELEASE)
&:rf80`z. okStopCapture hBoard
EB\\
F okCloseBoard hBoard
F
J)la9 CloseHandle hFile
J&Ah52 Close #hBCFile
n}"MF>
zDK conn.Close
+p2)uXqW End
hQ9VcS6=gD End Sub
j:0z/gHp$ c5JxKU_ Function ArrayToBMP(ByVal File As String)
[|vdr. Dim BytesWrite As Long
dwRJ0D]& 37VSE@Z+ hTmpFile = CreateFile(File, GENERIC_READ Or GENERIC_WRITE, 0&, 0&, _
i]P]o) CREATE_ALWAYS, 0&, 0&)
Yv>% 5` =dPrG=A If hTmpFile = 0 Then
|g~.]2az ArrayToBMP = False
nk[ixVc Exit Function
zJPzI{-w| End If
Ta_#Rg*! =7a9~&| SetFilePointer hTmpFile, 0&, 0&, FILE_BEGIN
sPut@4[S WriteFile hTmpFile, BMPHeader, 2&, BytesWrite, ByVal 0&
Lx.X#n.]T SetFilePointer hTmpFile, 2&, 0&, FILE_BEGIN
~MOIrF WriteFile hTmpFile, BMPHeader.FileLength, Len(BMPHeader) - 2, BytesWrite, ByVal 0&
-0Ps.B '2eggX% SetFilePointer hTmpFile, Len(BMPHeader), 0&, FILE_BEGIN
O[!]/qP+. WriteFile hTmpFile, pFRAME(1, 1), pFrameSize, BytesWrite, ByVal 0&
4g|}]K1s )gZ yW
If BytesWrite < pFrameSize Then
WHL@]^E@m ArrayToBMP = False
zFlW\wc End If
D_g+O"];P ]`LMyt0 CloseHandle hTmpFile
.RdnJ&K* vForj*Xo End Function
cY5h6+ _ $. Ih-
Function ArrayToBMP1(ByVal File As String)
{<V{0
s% U<zOR=_ Dim BytesWrite As Long
6:H@=fEv BPW2WSm@< hTmpFile = CreateFile(File, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, _
uT_bA0jK CREATE_ALWAYS, 0&, 0&)
)Zox;}WK+ H?PaN)_6-+ If hTmpFile = 0 Then
kIyif7 ArrayToBMP1 = False
mk}8Cu4 Exit Function
1$4dzI() End If
f mf(5 svN&~@l SetFilePointer hTmpFile, 0&, 0&, FILE_BEGIN
Vf0m7BJc3 WriteFile hTmpFile, BMP1, 2&, BytesWrite, ByVal 0&
_G@)Bj^* 3:s!0t
y" SetFilePointer hTmpFile, 2&, 0&, FILE_BEGIN
G22u+ua WriteFile hTmpFile, BMP1.FileLength, Len(BMP1) - 2, BytesWrite, ByVal 0&
QN":Qk(,q [
&51m^ SetFilePointer hTmpFile, Len(BMP1), 0&, FILE_BEGIN
m)V%l0 WriteFile hTmpFile, pBuffer(1), pBufferSize, BytesWrite, ByVal 0&
A2..gs/ dj 4:r!5_ If BytesWrite < pBufferSize Then
29:] cL(5 ArrayToBMP1 = False
o!: End If
umI@ej+D G@s
rQum( CloseHandle hTmpFile
XsEDI?p2 09/Mg End Function
,VI2dNst\ `Ps&N^[ '使用该过程建立的文件要求在用后关闭
U<K)'l6#2n Public Function ArrayToBMP2(File As String) As Boolean
c1Skt 9J*.'
Y Dim BytesWrite As Long
K9]L>Wj +JsMYv ArrayToBMP2 = True
iU+O(vi Ko:<@h hTmpFile = CreateFile(File, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, _
!Wgi[VB CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0&)
!ap}+_IA7^ ;ry~x:7L7 If hTmpFile = 0 Then
Pd)mLs Jg ArrayToBMP2 = False
3VaL%+T$, Exit Function
Phr+L9Eog End If
Cs))9'cD] c~SR@ZU SetFilePointer hTmpFile, 0&, 0&, FILE_BEGIN
Z/RSZ- WriteFile hTmpFile, BMPHeader, 2, BytesWrite, ByVal 0&
s^#B*
#ozui-u> SetFilePointer hTmpFile, 2&, 0&, FILE_BEGIN
n&1q* WriteFile hTmpFile, BMPHeader.FileLength, Len(BMPHeader) - 2, BytesWrite, ByVal 0&
NYw>Z>TD8c :<hM@>eFn SetFilePointer hTmpFile, Len(BMPHeader), 0&, FILE_BEGIN
#A\@)wJ WriteFile hTmpFile, pFRAME(1, 1), pFrameSize, BytesWrite, ByVal 0&
k..AP<hH }20~5
! If BytesWrite < pFrameSize Then
uVN2}3!)Y ArrayToBMP2 = False
kntYj}F( End If
W[/Txc0$ qz95) CloseHandle hTmpFile
tnE), JVydTvc End Function
#x*\dL 7H.3.j(L Private Function TESTSignal() As Boolean
? fW['% Dim extsign As Long, videotype As Long, scanlines As Long, fieldfrq As Long
e>0gE`8A g-? @a extsign = okGetSignalParam(hBoard, SIGNAL_VIDEOEXIST)
@Z.BYC >e>%AMzo[ If extsign = 1 Then
CVE(N/&b TESTSignal = True
5:|9pe) Else
&n9&k
Em If extsign = 0 Then
,Wv+Ek MsgBox "无视频输入信号,检查摄像机电源!", vbOKOnly
~[<C6{ TESTSignal = False
[n4nnmM Exit Function
Wz%H?m:g# End If
galzk $D End If
LY-,cXm&| G>=Fdt7Oc '测试视频输入类型
9A~w2z\G 'video type
L>L IN 1A okWaitSignalEvent hBoard, EVENT_ODDFIELD, 40
U$|q]N videotype = okGetSignalParam(hBoard, SIGNAL_VIDEOTYPE)
e.\dqt~%y If videotype = 1 Then
<p/zm}?') '"隔行信号(Interlaced)"
bMn)lrsX Else
-U*J5Q If videotype = 0 Then
Qo32oT[DM '"逐行信号(Non-interlaced)"
Me79:+d Else
S4\a"WYg If videotype = -1 Then
1*" 7q9x ' "不支持"
F/ x2}' End If
4O<sE@X End If
JR8|!Of@B End If
'i',M+0>jC /k8I6 '测试垂直扫描线数
<?s@-mpgN 'video scanlines
rGQ
2 ve scanlines = -1
Bv<aB(c scanlines = okGetSignalParam(hBoard, SIGNAL_SCANLINES)
wx^Det If scanlines = -1 Then
hC[=e`j ' "不支持"
]VL} eHZ Else
Z_[ P7P 'Trim(Str(ScanLines)) + " 行数/幅"
4%2APvLW End If
63'm
@oZ 9#TD1B/ '测试帧频
@R%*; )*F 'video field frequency
~7 `,}) d fieldfrq = okGetSignalParam(hBoard, SIGNAL_FIELDFREQ)
G9NI`]k If fieldfrq = -1 Then
3Q'vVNFh< 'lblSignal(8) = "不支持"
/poGhB1k Else
|.VSw 'lblSignal(8) = Trim(Str(FieldFRQ)) + " 场数/秒"
^s6}[LDW>@ End If
Y?TS, End Function
@Ddz|4 vEi "4\k1H"_ ^D<CoxG Sub PicIdentify()
L&c
&
<+0T '本程序完成从文件中按顺序读出一幅图像并完成图像识别
:.4O
Hp1 '根据固定位置判断透过车皮连接处接收的对面的立柱影像。出现立柱后该帧前1-2帧与后1-2帧分别为车号信息与车皮信息
KCO.8=y3 '判定标准:如果在立柱位置上有明显的模式反差,则视为车皮之间的间隔
D(l,Z '方法:对立柱标志区进行平均值二值化,面积为32*40,亮区(255)与暗区(0)的亮度平均值理论差大于200倍,实际差值应不小于100倍
6@TU9AZS` A|GtF3:G Dim fPTR As Long, cFrame As Long
8tQ;N' Dim i As Long, j As Integer, pTotal As Long, pAV As Integer
TG[u3Y4 Q7rBc
wm5 qCg<g cFrame = 0
EjL]#,QR [0EWIdT*b =* G3Khz! Do While cFrame < tFrames
udu<Nis4 7mq&]4-G fStatus = SetFilePointer(hFile, cFrame * pFrameSize, 0&, FILE_BEGIN)
.<zKBv fStatus = ReadFile(hFile, ByVal hMEM, ByVal pFrameSize, bytesRW, ByVal 0&)
d\uN MoveMemory pFRAME(1, 1), ByVal hMEM, pFrameSize
=WjHf8v; :`e#I/, frmRecord.RText.Text = Str(cFrame)
V1B!5N< frmRecord.RText.Refresh
}/dk2!?ig 9wZ?")2 If CheckMark = True Then
@4hzNi+ ArrayToBMP TmpBMP
g'KxjjYT, frmRecord.Picture1.Picture = LoadPicture(TmpBMP)
ffG<hclk frmRecord.RText.Text = "第" & Str(cFrame) & "帧"
PJiU2Y33 TKM^ DrawSlice
%ggf|\-e P&sWn?q Ol 'i = MsgBox("检测到立柱:第" & Str(cFrame) & "帧", vbYesNo)
XHekz6_ 'If i = vbNo Then
?<${?L> ' Exit Do
/i3JP}
'End If
)O" E#% 'cFrame = cFrame + 1
Qn7T{ BW '{cSWa|
# End If
Rjq Xz6 DoEvents
._^}M<o L cFrame = cFrame + 1
0W(mx-[H/ Loop
][wb4$2 End Sub
]R_R`X? n9xP8<w8
])wdd>' Function CheckMark(Optional iBlk As Integer = 30, Optional iWhite As Integer = 230) As Boolean
@>HTbs6W i+h*<){X '如标志区模式反差存在则为TRUE,否则返回FALSE
/kY9z~l db~^Gqv6k Dim i As Integer, j As Integer, mTotal As Long, mAV As Single, mTop As Long, mBot As Long
5>I-? Ki CheckMark = True
JcWp14~e 4d`YZNvZW/ '复制标志区
qFD ZD)K For i = 1 To mkH
3Rc*vVnI MoveMemory MKpilar((i - 1) * PilarW + 1), pFRAME(PilarX, PilarY + i), PilarW
4~,Z ' k Next i
d
#1Y^3n H"FK(N\ For j = 1 To PilarW * PilarH / 2
sqrLys_S mTop = mTop + MKpilar(j)
l::q
F 0 Next j
QQBh)5F QkBw59L7 For j = PilarW * PilarH / 2 + 1 To PilarW * PilarH
J-hJqR*;K mBot = mBot + MKpilar(j)
ZU73UL Next j
g%&E~V/g$ sq!$+
=1-X mTop = mTop / PilarW / PilarH * 2
HohCb4d
o mBot = mBot / PilarW / PilarH * 2
rS{}[$Zpl pR$(V4> mAV = (mTop + mBot) / 2 + (mBot - mTop) / 4 '标志区平均亮度
D`T;j[SsS# !BsQJ_H '平均值极值化
U?#wWbE1 For j = 1 To PilarH * PilarW
jc&k-d>=G MKpilar(j) = IIf(MKpilar(j) > mAV, 255, 0)
!&{rnK Next j
au{)5W4~ 5dm ~yQN/ mTop = 0: mBot = 0
2)n`Bd For j = 1 To PilarH * PilarW / 2
o]4]fLQ mTop = mTop + MKpilar(j)
x~V[}4E%> Next j
j(=w4Sd_W hm,{C For j = PilarH * PilarW / 2 + 1 To PilarH * PilarW
I/`"lAFe mBot = mBot + MKpilar(j)
8@t8P5(vL Next j
`gX|q3K\s D5,]E`jwu oZa'cZN
s mTop = mTop / PilarH / PilarW * 3
J,F1Xmr4 mBot = mBot / PilarH / PilarW * 3
p?i.<Z fOV_ >]u lI<jYd
0fZ If mBot > iWhite And mTop < iBlk Then
GGp.u@\r CheckMark = True
uzBQK Else
w}ji]V} CheckMark = False
Zz0bd473k? End If
FJ_7<4ET End Function
<y@vv 1Cw]
~jh Sub Capture1Frame()
}R%H?&P okCaptureTo hBoard, BUFFER, 0, 1 'single
qYC&0`:H okGetCaptureStatus hBoard, True
\baY+,Dr+ MoveMemory pFRAME(1, 1), ByVal mBufferAddr, pFrameSize
ZwkUd-=0i End Sub
Cz0FA]-g =rA?,74 4!IuTPmr Sub CopyMark(iBlk As Integer, iWhite As Integer)
nGH6D2!F '复制标志区并返回标志区暗区与亮区的亮度平均值
N&HI)X2& Dim i As Integer, j As Integer, mTotal As Long, mAV As Single, mTop As Long, mBot As Long, mMid As Single, bsTotal As Long
>v]
^nJl
iH8we,s' '复制标志区
wXIRn?z For i = 1 To mkH
B*Tn@t W MoveMemory MKpilar((i - 1) * PilarW + 1), pFRAME(PilarX, PilarY + i), PilarW
)[ V8YiyU Next i
1&|]8=pG7 {DRk{>K, For j = 1 To mkW * mkH / 2
*?FVLE mTotal = mTotal + MKpilar(j)
V|8'3=Z= Next j
mtmC,jnD <tD,Uu
{P iBlk = mTotal / (mkW * mkH / 2) '标志区上部白区平均亮度
O] @E8<?^ j'D%eQI,V mTotal = 0
ek][^^4o For j = mkW * mkH / 2 + 1 To mkW * mkH
"`>6M&`U mTotal = mTotal + MKpilar(j)
0P$1=oK Next j
8A#,*@V[ i#'K7XM2 iWhite = mTotal / (mkW * mkH / 2) '标志区下部黑区平均亮度
MgeC-XQM M
gXZN{ '背景亮度
W_W !v&@E= MoveMemory BsLine(1), pFRAME(1, 1), 4 * FrameW
NiZfaC6V For i = 1 To 4 * FrameW
|0n )U( bsTotal = bsTotal + BsLine(i)
Gy
q 6? Next i
?()*"+N(ck bsAV = bsTotal / FrameW / 4
W'C>Fn}lO? ]3LLlXtK[ End Sub
ZSuo
D$~k[ TxJk.c OG5{oH#K Sub AdjIMGbright(Optional bInit As Boolean = True)
t#^Cem<
7kLurv '自动调节亮度与对比度,此时处于无车辆状态(白天特别高,而夜间特别暗)
)ros-dp` '图像平均亮度白天不高于200(当车辆通过时可能会下降到100左右),不低于100
LCivZ0?|X ' 夜间不高于80(过高时通常是由于雪花噪声引起),但立柱不低于30
v\:AOY
' jZA1fV Dim bsTotal As Long, i As Integer, iBlack As Integer, iBright As Integer
p*Z<DEh# ,X|Oe@/ '按标准亮度与对比度采集一帧,确定背景亮度
0Y8gUpe3P6 currentContr = 128 '初始对比度
$gl|^c\ currentBr = 128 '初始亮度
zG9FO/@av okSetVideoParam hBoard, VIDEO_BRIGHTNESS, currentBr '亮度
cXq9k!I% okSetVideoParam hBoard, VIDEO_CONTRAST, currentContr '对比度
%g9ym@s DoEvents
74([~Qs _M Capture1Frame
|5^
iqW '获得图像上缘4行象素
C
m:AU; MoveMemory BsLine(1), pFRAME(1, 1), 4 * FrameW
bBi>BP= CopyMark iBlack, iBright '图像标志区亮度
),x0G*oebj For i = 1 To 4 * FrameW
W`[VLi}fe bsTotal = bsTotal + BsLine(i)
Ca
~8cQ Next i
,;pUBrz/[ bsAV = bsTotal / FrameW / 4 '图像上缘基线亮度
dcf,a<K\ jr`swyg Select Case bsAV
!]F`qS> Case 0 To 60 '夜间通过灯光照明,完全没有背景
o@)Fy51DD currentBr = 150
Ue}1(2.v currentContr = 60
1S?~c25=h Case 61 To 80 '有可见背景
j,OA>{-$ currentBr = 140
d]E=w6+;Q currentContr = 70
.\oz Case 81 To 100 '有清晰背景
Ic'D#m currentBr = 128
|Yl i~Qx currentContr = 80
& DP"RWT/ Case 100 To 150 '有明亮背景
OeQ[-e currentBr = 140 '5:30-6:00钟实测数据
-HF?1c currentContr = 50
k6#$Nb606 Case 151 To 180
v?He]e' currentBr = 130
jkk%zu currentContr = 60
_
s 3aaOL Case 181 To 220 '背景全为白色
O ~5t[ currentBr = 110
D"4*l5l currentContr = 130
?8O5%IrJ Case 221 To 255 '背景全为白色
g:!U,<C^a currentBr = 100
n*[ZS[I currentContr = 100
!j $cBf4 End Select
]!TE
bPTtA;u Select Case (iBlack + iBright) / 2 '图像反射光强度修正
-|V#U`mwF Case 100 To 150
H,D5)1Uu currentBr = currentBr - 10
JZ}zXv Case 151 To 255
S<T'B0r8 currentBr = currentBr - 20
?=7k<a~ End Select
}XUL\6 U wqG#jC!5 okSetVideoParam hBoard, VIDEO_BRIGHTNESS, currentBr '亮度
&k'<