这才是我当年写出的一个比较烂的程序 $t~@xCi]S
K_/zuTy
Main2.bas :hRs`=d"r
<7_KeOLJ
Attribute VB_Name = "SubMain" e>}}:Ud
Option Explicit 8RW&r
!#2=\LUC
'采集文件与临时文件 "TcW4U9
Public Const TmpFile As String = "d:\30-0600.dat" p(F " /
'已有数据:30-0600.dat /30日早6点进车与6:30出车头 ORN6vX(1
)$Mmn
Public fStatus As Long, hFile As Long, bytesRW As Long, lptrFile As Long $ ((6=39s
Public hBCFile As Long '记录采集参数的文件 "O[j!fG8,
Public Const TmpBMP As String = "d:\1.bmp" Oakb
'
Public hTmpFile As Long ])DX%$f
o>Er_r
bFS>)
'采集窗口参数常量 44ed79ly0)
Public Const FrameH As Long = 280& N K]B?
Public Const FrameW As Long = 768& Hr<o!e{Y
Public Const pFrameSize As Long = FrameW * FrameH ccFn.($p?,
m#vL*]c}
'标志区范围,用于识别车辆 7nU6k%_ %
Public Const PilarC As Integer = 260 '识别标志立柱中线坐标X 69K{+|
Public Const mkW As Integer = 28 '识别标志立柱宽度 SqA
J-_~
Public Const mkH As Integer = 80 ''识别标志立柱高度(上白中黑下白) n5-)/R[z
Public Const mkY As Integer = 4 ''识别标志立柱Y坐标(40-79白, 80-119黑,120-159白) .7NNT18
Public Const mkX As Integer = PilarC - mkW / 2 '识别标志立柱X坐标 +rXF{@
l
'车缝检测位置常数 '8 Ztj
Public Const sSize As Long = 32& !7bw5H
Public Const sPos As Long = 310& FQz?3w&ia
Public Const sPosL As Long = 200& zSEs?
Public Const sPosR As Long = 500& h}`!(K^;3
'车缝检测框位置 bx4'en#
Public Slice(1 To sSize, 1 To FrameH) As Byte e({9]
Public SliceL(1 To sSize, 1 To FrameH) As Byte }x0- V8
Public SliceR(1 To sSize, 1 To FrameH) As Byte ^Xb7[+I6
Public avSL As Integer, avSLR As Integer, avSLL As Integer ;Q;[*B=kE
wC_l@7t
&MZ$j46
Public MKpilar(1 To mkW * mkH) As Byte '一维数组用于亮度对比度分析,比使用二维数组更便于VB编译优化 Ny- [9S-<
'该数组用于亮度对比度调节、车辆通过识别与车皮间隔识别 %+>s#Q2d
Public BsLine(1 To 4 * FrameW) As Byte, bsAV As Integer '图像的前4行。用于确定标志区的亮度与对比度范围 >'uU)Y{
Public PilarW As Long, PilarH As Long, PilarX As Long, PilarY As Long $~0Q@
):
Public LeftBK(1 To 1024, 0 To 1) As Byte, RightBK(1 To 1024, 0 To 1) As Byte }@1q
@xU
'前后帧左右上角128列*8行像素块,根据平均值差绝对值判断进车方向 cF)/^5Z
B/JO~;{
A-
YBQPE
{6 6sB{P
'一次连续采集的帧数 7dG79H
Public tFrames As Long tR0pH8?e"
A>`945|
'在采集卡申请的缓存中,是按帧为单位的,每一帧包含奇偶场两场的数据 -|k)tvAm
'而该卡的硬件设置是按场采集,只需要读第一场的数据即可。 !" #9<~Q,p
'所以要设置的缓存帧的大小是frameW*frameH*2,而一场的数据量为pFrameSize `:m!~
J5p"7bc
Public pFRAME(1 To FrameW, 1 To FrameH) As Byte PNOGN|D
Public pBuffer(1 To FrameW * FrameH * 2) As Byte $''?HjB}T
Public pWorkSpace(1 To FrameW * FrameH) As Long "@A![iP
Public Const pBufferSize As Long = FrameW * FrameH * 2 Uxfl_@lJ
Public pGray(0 To 255) As Long '整幅图像的灰度直方图 LVJI_ O{fH
]uj=:@
Public hBoard As Long '采集卡标识 cJo\#cr
Public mBufferAddr As Long '缓存地址 =]`lN-rYw
Public BufferSize As Long '缓存大小(字节) [H<bh%
Public iCurrentCard As Long >_dx_<75&
Public CapStatus As Long {5r0v#;
Public iFrames As Long @`opDu!
Public currentBr As Byte, currentContr As Byte M->*{D@a
E/&Rb*3
Public hMEM As Long, mStatus As Long 0Sq][W=
Public Const hMemSize As Long = pFrameSize * 4 9E2j!
Public hMemWork As Long H=*5ASc
Public Const hMemWorkSize As Long = pFrameSize * 5 X,aYK;q%z
aprm0:Q
^
4/ kv3rv
PNF?;*`-{7
'串口接收轨道衡数据 kE8>dmH23
Public WeightFromCom As String oI:o"T77sA
Public bReceiveComplete As Boolean s>k Uh
zya5Jb:Sg
*[ #;j$m
Public Type GrayBMPHeader `\`> 0hlu
Tag As Integer 3f" %G\
FileLength As Long '文件大小 -oeL{9;
Reserve1 As Long PWRy7d
DataOffset As Long '图像数据偏移量 *-W
#G}O0
BMPHeaderSize As Long '文件头长 VErv;Gy
V
'length of the bitmap info header used to describe the bitmap colors, compression,… @vL20O.
'the following sizes are possible: eI.2`)>
'28h - windows 3.1x, 95, nt, … 7]xm2CHx5
'0ch - os/2 1.x &8&d3EQ
'f0h - os/2 2.x <~TP#uAz
wbDM5%
ImageWidth As Long '图像宽(像素数) /+*#pDx/zW
ImageHeight As Long '图像高(像素数) NjPDX>R\K
PlaneNumber As Integer '图像层数 )#|<w9uec
bpp As Integer 'bits per pixels '1 - monochrome bitmap a,F&`Wg
'4 - 16 color bitmap <!-sZ_qq
'8 - 256 color bitmap %*aJLn+]_R
'16 - 16bit (high color) bitmap ]5~s"fnG
'24 - 24bit (true color) bitmap `RU[8@ 2%
'32 - 32bit (true color) bitmap _=ua6}Xp
Compression As Long '压缩方法 '0 - none (also identified by bi_rgb) ah
@uUHB
'1 - rle 8-bit / pixel (also identified by bi_rle4) \^( 0B8|w
'2 - rle 4-bit / pixel (also identified by bi_rle8) dkgSvi :!
'3 - bitfields (also identified by bi_bitfields) M.-"U+#aD
IMAGESIZE As Long '图像数据字节数 g4`Kp;}&'
hResolution As Long '水平分辩率 像素数/米 5uq3\a
vResolution As Long '垂直分辩率 iovfo2!hD
ColorsinBMP As Long '图中所用的颜色。对256色图像总为0x100 6u`F
d#
ImportantColors As Long 0]QRsVz+
Pallate(0 To 255) As Long '图像每个值对应的实际显示颜色,项数对应PallateNumber所指调色板项数 F' U 50usV
End Type >Vy>O&r
y@2epY?{
b2 _Yu^
dzK{
Z
Public BMPHeader As GrayBMPHeader, BMP1 As GrayBMPHeader nJ4@I7Sk;
Public sRECT As RECT p4IZ
?
J}r
$aHAv/&(5
Public conn As ADODB.Connection CQel3Jtt.
Public rsTrain As ADODB.Recordset 8}H1_y-g[
Public rsOperater As ADODB.Recordset 8[r9HC
Public rsGoods As ADODB.Recordset W$U0[^1
Public rsGood2 As ADODB.Recordset J
PyOG_h
Public rsSender As ADODB.Recordset (,^*So/
Public rsReceover As ADODB.Recordset |qZ
ko[W}=
Public rsTrainTMP As ADODB.Recordset kGpa\c
g1
}$MN|s
Wg{k$T_>
'打开采集卡 #&v/icz$
'设置参数 q~CA0AR
'设置为实时单帧采集到缓存方式 ReiB $y6
'由另一线程查询采集状态,如果完成采集,传送至用户数组分析或保存 qq)0yyL r
y;mj^/SxK
m)V/L]4
Sub Main() DeR='7n
Dim i As Integer, status As Long AL$&|=C-$
!O\;Nua
InitBMPinfo Vpy 2\wZWb
'生成BMP文件头---该文件头是固定将pFRAME数组写成BMP文件 [E#UGJ@
BMPHeader.Tag = &H4D42 '$4O!YI9@
BMPHeader.ImageWidth = FrameW #;n+YM">:
BMPHeader.ImageHeight = FrameH %r&-gWTQ,
BMPHeader.BMPHeaderSize = &H28 DD" $1o"
BMPHeader.PlaneNumber = 1
q$1PG+-
BMPHeader.bpp = 8 gaA<}Tp,
BMPHeader.Compression = 0 {G <kA(Lm
BMPHeader.hResolution = &H1274 'Windows pBrush.exe的默认值,PhotoED.exe默值为0 9/+Nj /
BMPHeader.vResolution = &H1274 i)#:qAtP*
BMPHeader.ColorsinBMP = 256 y/e2l
BMPHeader.ImportantColors = BMPHeader.ColorsinBMP %WqNiF0-
BMPHeader.DataOffset = Len(BMPHeader) ^F?&|clM/
For i = 0 To 255 vR0];{
BMPHeader.Pallate(i) = RGB(i, i, i) E?(xb B
Next i A:(*y
2
BMPHeader.IMAGESIZE = FrameH * FrameW dKl^jsd
BMPHeader.FileLength = Len(BMPHeader) + BMPHeader.IMAGESIZE eC5 $#,HiC
ZmOfEg|h\
6wco&7
MoveMemory BMP1, BMPHeader, Len(BMPHeader) l3N I$Zu
Oj<S.fi
BMP1.ImageWidth = FrameW 1ygpp0IGJ
BMP1.ImageHeight = FrameH * 2 dU\%Cq-G)
BMP1.IMAGESIZE = BMP1.ImageWidth * BMP1.ImageHeight +,~z
Wv1v
BMP1.FileLength = Len(BMP1) + BMP1.IMAGESIZE iU6Gp-<M,
"V{yi!D{<
'确定标志位置,为pilarX, pilarY确定初始值 8|E'>+ D_-
PilarW = mkW )54%HM_$k
PilarH = mkH '此两项为固定值 e><5Pr)
PilarX = GetSetting(App.EXEName, "Mark", "MarkX", mkX) XLMb=T~S
PilarY = GetSetting(App.EXEName, "Mark", "MarkY", mkY) '此两项需要在程序初始化时检查并进行调整 BBcV
9CGU
E\gim<]
q+B&orp
'连续采集记录文件 Z3[S]jC
' 建立一个缓冲区为页对齐方式的文件 S+TOSjfis
If Dir(TmpFile) <> "" Then ~Lc066bLeq
hFile = CreateFile(TmpFile, GENERIC_READ Or GENERIC_WRITE, _ GGhM;%H_99
0&, 0&, OPEN_ALWAYS, FILE_FLAG_NO_BUFFERING, 0&) {3N'D2N
' 在95/98中,如果打开文件时没有声明overlapped方式,在读定文件时就不能使用overlapped参数项 Vh}SCUof'
' 而必须用setfilepointer函数调节与操作系统保留的文件指针。 Hw#d_P:
Else OL_{_K(w
hFile = CreateFile(TmpFile, GENERIC_READ Or GENERIC_WRITE, _ 9qS"uj
0&, 0&, CREATE_ALWAYS, FILE_FLAG_NO_BUFFERING, 0&) olLfko4$*V
End If 0%!rx{f#\
If hFile = 0 Then XZw6Xtn
MsgBox TmpFile & ": File Open Error", vbOKOnly b64
@s2]
Exit Sub + [Hh,I7
End If P0`Mdk371
'采集参数记录文件 n$xQ[4eH)
hBCFile = FreeFile() JG{j)O|L
Open TmpFile + ".BC" For Binary Access Read Write As #hBCFile 6<K6Y5<6
L
8{\r$
hMEM = VirtualAlloc(ByVal 0&, hMemSize, MEM_COMMIT, PAGE_READWRITE) ’分配系统内容 7d92Pe
If hMEM = 0 Then g$.
\
fStatus = GetLastError ''\;z<v
MsgBox "内存分配错误: 错误代码 - " & Str(fStatus) & vbCrLf _ s=?g \oR
& "请向技术人员报告该错误代码。", vbOKOnly Ltjbxw"Qd
CloseHandle hFile ]*7Y~dO
Exit Sub &rkEK4
End If ?\8?%Qk
(C]o,7cYS
hMemWork = VirtualAlloc(ByVal 0&, hMemWorkSize, MEM_COMMIT, PAGE_READWRITE) zhY+x<-
If hMemWork = 0 Then hHqh{:q{v
fStatus = GetLastError oD}uOC}FS{
MsgBox "内存分配错误: 错误代码 - " & Str(fStatus) & vbCrLf _ k6=nO?$
& "请向技术人员报告该错误代码。", vbOKOnly v]B
L[/4
'释放已成功分配的内存 vkLC-Mzm<
mStatus = VirtualFree(ByVal hMEM, hMemSize, MEM_DECOMMIT) 0Z{j>=$
mStatus = VirtualFree(ByVal hMEM, 0&, MEM_RELEASE) gm9mg*aM
lO2[JP
CloseHandle hFile r>GZ58i
Exit Sub i-yy/y-N
End If sB69R:U;
v&Kqq!DE
' Test writing O
Fje+S
'WriteFile hFile, ByVal hMEM, ByVal 4096&, bytesRW, ByVal 0& RpLE
02U
=@F&o4) r
'初始化采集卡参数 r!
Ay:r
iCurrentCard = -1 V.wqZ {G
hBoard = okOpenBoard(iCurrentCard) gW
Y"w!f
Debug.Print hBoard dMR3)CO
If hBoard = 0 Then $%VuSrZ&
ExitGrabber h*ZC*eV>
End a<]B B$~
End If U-n;
xX0=
okGetBufferSize hBoard, mBufferAddr, BufferSize :!zl^J;
If mBufferAddr = 0 Then *,Bzc Z
MsgBox "缓存不存在!" ko5V9Drc
ExitGrabber (k np#
End If 2w)-\/j}
Debug.Print Hex(mBufferAddr), Hex(BufferSize) l }XU5
9
};'\~g,1
ja=F 7Usb
currentBr = 128: currentContr = 128 vM_:&j_?``
'设置视频输入参数 Zw
wqSyuGf
okSetVideoParam hBoard, VIDEO_SOURCECHAN, 1 'Video2 d#2$!z#
' lParam=0,1.. Comp.Video; 0x100,101...to Y/C(S-Video), 0x200,0x201 to RGB Chan.Input !%dN<%Ah
okSetVideoParam hBoard, VIDEO_BRIGHTNESS, currentBr '亮度 wcDRH)AW.
okSetVideoParam hBoard, VIDEO_CONTRAST, currentContr '对比度 ---初始设置条件下如果图像亮度达不到基本要求则控制灯光 .f+TZDUO
okSetVideoParam hBoard, VIDEO_RGBFORMAT, FORM_GRAY8 '8位灰度模式 r,_?F7
okSetVideoParam hBoard, VIDEO_TVSTANDARD, 0 'PAL制式
]({~,8s
okSetVideoParam hBoard, VIDEO_SIGNALTYPE, &H10000 '逐行(低字)同步开槽(高字) ePIiF_X
okSetVideoParam hBoard, VIDEO_RECTSHIFT, 144 + &H2C0000 '有效区起始位置:高字Y偏移,低字X偏移 (144/44经验值) Q]p(u\
*
okSetVideoParam hBoard, VIDEO_AVAILRECTSIZE, FrameW + FrameH * 2 * &H10000 '有效区大小:低字X高字Y (768/576采集卡最大值) _HhbIU
okSetVideoParam hBoard, VIDEO_FREQSEG, 0 ' 低频部分信号 l7De6A"
Nan[<
'设置采集参数 NH_<q"gT
okSetCaptureParam hBoard, CAPTURE_INTERVAL, 0 '逐帧 M:5b4$Qh<
okSetCaptureParam hBoard, CAPTURE_CLIPMODE, 2 '裁剪方式 @3kKJ
okSetCaptureParam hBoard, CAPTURE_BUFRGBFORMAT, FORM_GRAY8 '8位灰度 ?`J[[",
okSetCaptureParam hBoard, CAPTURE_HARDMIRROR, 0 '不作镜像变换 }MUn/ [x
okSetCaptureParam hBoard, CAPTURE_FRMRGBFORMAT, FORM_GRAY8 '帧存格式 O{ /q-~_
okSetCaptureParam hBoard, CAPTURE_SAMPLEFIELD, 0 ' 逐场采集 r H ~" 4
okSetCaptureParam hBoard, CAPTURE_HORZPIXELS, 944 '水平像素数 PAL制式固定值 J*9
$;
okSetCaptureParam hBoard, CAPTURE_VERTLINES, 625 '垂直线数 H4]Ul
eU
okSetCaptureParam hBoard, CAPTURE_SEQCAPWAIT, 0 '不等结束立即返回 HYmn:?H
'okSetCaptureParam hBoard, CAPTURE_BUFBLOCKSIZE, FrameW + FrameH * 2 * &H10000 Ytgj|@jsp
'Buffer Block Size不用设置,而用okSetTargetRect函数进行动态调节 :kfp_o+J
UwC=1g U
l3 DYg
okCloseBoard hBoard BL&LeSa
Sleep 50 Xy%p "b<
hBoard = okOpenBoard(iCurrentCard) '关闭后重新打开使新的设置值生效 u+{a8=
,]b~t0|B
'设置数据传送方式 7 I
>G{
'okSetConvertParam hBoard, CONVERT_FIELDEXTEND, FIELD_COPYEXTEND '逐行并扩展行 }jill+]
'该设置对本程序无意义,因为程序直接用CopyMemory方法读缓存,而扩展行方式是在用采集卡内置函数读RECT过程中实现的。 tDAhyy73
sUPz/Z.h
sRECT.Right = -1 '用于获得当前设置值 trE{ FT
iFrames = okSetTargetRect(hBoard, BUFFER, sRECT) C!7>1I~5
Debug.Print sRECT.Left, sRECT.Right, sRECT.Top, sRECT.Bottom KN-
avu_Ix
Debug.Print okSetCaptureParam(hBoard, CAPTURE_BUFBLOCKSIZE, -1) 'FrameW + FrameH * &H10000 ]r_;dY a
sRECT.Left = 0 ;NlWb =
sRECT.Top = 0 }`+B=h-dW
sRECT.Right = sRECT.Left + FrameW 9(":,M(/o
sRECT.Bottom = sRECT.Top + FrameH * 2 /r_~:3F
iFrames = okSetTargetRect(hBoard, BUFFER, sRECT) }<'5 z
qS
<id}<H
sRECT.Right = -1 '检查新设置值 [V:\\$
iFrames = okSetTargetRect(hBoard, BUFFER, sRECT) TwgrRtj'
Debug.Print sRECT.Left, sRECT.Right, sRECT.Top, sRECT.Bottom tnLAJ+-M
Debug.Print Hex(okSetCaptureParam(hBoard, CAPTURE_BUFBLOCKSIZE, -1)) fA89|NTSUh
^wS5>lf7p
If TESTSignal = False Then U!Ek'
'ExitGrabber {/pm
<k=
End If N!`e}Z6S
ul*Qt}
d|4}obCt
yv)
ux:P&+
'设为实时采集状态 2h%z ("3/
'iFrames = okCaptureActive(hBoard, BUFFER, 0&) 4V~?.
CW<N: F.9
N]RZbzK_5G
'单帧采集 J:skJ.Wx
'okWaitSignalEvent hBoard, EVENT_FRAMEHEADER, -1 LiKxq=K
'iFrames = okCaptureSingle(hBoard, BUFFER, 0&) @gG<le6
okCaptureTo hBoard, BUFFER, 0, 1 'single '}Ri`
'Do While okGetCaptureStatus(hBoard, False) <> 0 \rPbK+G.
' Sleep 20 w|Nz_3tI
'Loop
n[(Qr9
okGetCaptureStatus hBoard, True &5:tn=E
MoveMemory pFRAME(1, 1), ByVal mBufferAddr, pFrameSize #h/Mbj~S
'写入768*576测试图象 m>SErxU(z
ArrayToBMP TmpBMP Uk\Id~xLV
|.wEm;Bz
'打开数据库 &?h,7
D;A
Set conn = New ADODB.Connection S6[v;{xJ
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ U#U]Pt
"Persist Security Info=False;Data Source=" & "c:\train\train.mdb" & _ Uo2GK3nT
"; Mode=Read|Write" EAeqLtFqs
conn.Open tY
<Z'xA?
@_z4tUP
frmRecord.Picture1.Picture = LoadPicture(TmpBMP) t:fFU1x
frmRecord.Visible = True *_ ?dVhxf
frmQuery.Visible = True zz& ?{vJ
Load frmReceiveFromComm @$T 9Ll
Gm\/Y:U
'调试参数 ~jsLqY*(+
If InStr(UCase(Command()), "/CAPTURE") > 0 Then `Qqk<o
SignalBox.Visible = True Ge<nxl<Bd
End If $HJwb-I
If InStr(UCase(Command()), "/COMM") > 0 Then vv=VRhwF
frmReceiveFromComm.Visible = True <vwkjCA`
End If GaSPJt
gJM`[x`T
End Sub ~,*b }O
QD%L0;j
Sub ExitGrabber() H@l}WihW
'关闭数据库 ]7e =fM9V;
'关闭采集卡 LQjsOo
mStatus = VirtualFree(ByVal hMEM, hMemSize, MEM_DECOMMIT) ZI=v.wa
mStatus = VirtualFree(ByVal hMEM, 0&, MEM_RELEASE) 6"}?.E$
mStatus = VirtualFree(ByVal hMemWork, hMemWorkSize, MEM_DECOMMIT) 'e6WDC1Am(
mStatus = VirtualFree(ByVal hMemWork, 0&, MEM_RELEASE) -I=l8m6L
okStopCapture hBoard +a*tO@HG
okCloseBoard hBoard JY6
Qp
CloseHandle hFile E4hLtc^
+
Close #hBCFile &~W:xg(jN
conn.Close {GJ@psG*
End q&d~
\{J
End Sub 2,*M|+W~
?Ae ven
Function ArrayToBMP(ByVal File As String) RZ+`T+zL
Dim BytesWrite As Long `hb%+-lj+
/d%=E
hTmpFile = CreateFile(File, GENERIC_READ Or GENERIC_WRITE, 0&, 0&, _ __.+s32SS$
CREATE_ALWAYS, 0&, 0&) G\(|N9^:
!o$!Fr c
If hTmpFile = 0 Then QVtQx>K`
ArrayToBMP = False +!|9hF'
Exit Function M|Rb&6O
End If %HJK;
k-}b{
SetFilePointer hTmpFile, 0&, 0&, FILE_BEGIN oJfr +3I
WriteFile hTmpFile, BMPHeader, 2&, BytesWrite, ByVal 0& 7.`fJf?
SetFilePointer hTmpFile, 2&, 0&, FILE_BEGIN sM9+dh
WriteFile hTmpFile, BMPHeader.FileLength, Len(BMPHeader) - 2, BytesWrite, ByVal 0& -a-(r'Qc(
1/"WD?a
SetFilePointer hTmpFile, Len(BMPHeader), 0&, FILE_BEGIN l]5w$dded~
WriteFile hTmpFile, pFRAME(1, 1), pFrameSize, BytesWrite, ByVal 0& #t+d iR
s-v
If BytesWrite < pFrameSize Then /i77
ArrayToBMP = False nvPwngEQm
End If +>PX&F
=kuMWaD
CloseHandle hTmpFile l'eyq}&
=W'Ae,&
End Function !/wtYI-`
8-O)Xx}cU
Function ArrayToBMP1(ByVal File As String) IC7M$
S9#)A->
Dim BytesWrite As Long V5rST +
,{
mCf^
hTmpFile = CreateFile(File, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, _ %VnbmoO
CREATE_ALWAYS, 0&, 0&) o>VVsH
f`Fi#EKT
If hTmpFile = 0 Then R2
V4#
ArrayToBMP1 = False w`5xrqt@
Exit Function D
gaMO,
End If :ijAqfX
hodgDrmO/
SetFilePointer hTmpFile, 0&, 0&, FILE_BEGIN q|),`.eh\
WriteFile hTmpFile, BMP1, 2&, BytesWrite, ByVal 0& vuYSVI2=H
)+6MK(<"
SetFilePointer hTmpFile, 2&, 0&, FILE_BEGIN eow'K
821A
WriteFile hTmpFile, BMP1.FileLength, Len(BMP1) - 2, BytesWrite, ByVal 0& F|!){=
y`=]T>X&x
SetFilePointer hTmpFile, Len(BMP1), 0&, FILE_BEGIN 5D'\b}*lJ}
WriteFile hTmpFile, pBuffer(1), pBufferSize, BytesWrite, ByVal 0& <%"b9T`'
ctGL-kp
If BytesWrite < pBufferSize Then d m`E!R_
ArrayToBMP1 = False \o^2y.q:>
End If lg&t8FHa;
r
>nG@A
CloseHandle hTmpFile ^-
d%
r
=y-@AU8
End Function o !U
6?
q7E~+p(>(
'使用该过程建立的文件要求在用后关闭 5^x1cUB]
Public Function ArrayToBMP2(File As String) As Boolean hyFyP\u]
zO iu5
Dim BytesWrite As Long 1aTB%F
mrjswF27$o
ArrayToBMP2 = True \*<d{gZ~
q*>&^V $M
hTmpFile = CreateFile(File, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, _ .qZI$
l.
CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0&) O`<KwUx !
=z
/dcC$r
If hTmpFile = 0 Then ZEx}$<)_
ArrayToBMP2 = False % S os
Exit Function J7g8D{4
End If c3CWRi`LE
sL$:"=
SetFilePointer hTmpFile, 0&, 0&, FILE_BEGIN .yEBOMNZ
WriteFile hTmpFile, BMPHeader, 2, BytesWrite, ByVal 0& _/tHD]um
KGFv"u{
SetFilePointer hTmpFile, 2&, 0&, FILE_BEGIN $\U4hHOo
WriteFile hTmpFile, BMPHeader.FileLength, Len(BMPHeader) - 2, BytesWrite, ByVal 0& .P"D
q0zr
E5
SetFilePointer hTmpFile, Len(BMPHeader), 0&, FILE_BEGIN >o=-$gz`
WriteFile hTmpFile, pFRAME(1, 1), pFrameSize, BytesWrite, ByVal 0& T]c%!&^_
n~V
]Z
If BytesWrite < pFrameSize Then BGX.U\uc
ArrayToBMP2 = False &:`U&06q
End If @8I4[TE
]@u6HH~^
CloseHandle hTmpFile $
F5 b
53n^3M,qK
End Function #%h-[/
{Sj9%2'M)
Private Function TESTSignal() As Boolean LBZ+GB
Dim extsign As Long, videotype As Long, scanlines As Long, fieldfrq As Long h[@tZ(jrY
W}mn}gTQ
extsign = okGetSignalParam(hBoard, SIGNAL_VIDEOEXIST) q1KZ5G)6GJ
FFEfI4&SfS
If extsign = 1 Then N <Xq]!
K-
TESTSignal = True D-._z:_
Else |0f>aZ
If extsign = 0 Then 71t*%
MsgBox "无视频输入信号,检查摄像机电源!", vbOKOnly 7](KV" %V
TESTSignal = False jIyB
Exit Function Ev}C<zk*
End If OL^l 3F
End If #^ A*
fNW"+ <W
'测试视频输入类型 @W"KVPd
'video type }|8_9Rx0*
okWaitSignalEvent hBoard, EVENT_ODDFIELD, 40 jr:7?8cH0L
videotype = okGetSignalParam(hBoard, SIGNAL_VIDEOTYPE) Jh!I:;/
If videotype = 1 Then AiO$<CS
'"隔行信号(Interlaced)" bl&nhI)w
Else #$8% w
If videotype = 0 Then &n8_0|gK
'"逐行信号(Non-interlaced)" *(T:,PY
Else $cU!m(SILQ
If videotype = -1 Then m3/O.DY%0
' "不支持" R1$:~p2m
End If YF>m$?;
End If 9j6QX~,
End If 2HsLc*9{4
t,+nQ9
'测试垂直扫描线数 |}di&y@-JI
'video scanlines |$
lM#Ua
scanlines = -1 85Otss/mM
scanlines = okGetSignalParam(hBoard, SIGNAL_SCANLINES) z)r=+ -
If scanlines = -1 Then /k,-P
' "不支持" z?*w8kU&>
Else /~$WUAh
'Trim(Str(ScanLines)) + " 行数/幅" Tq[kl'_
End If LAS'u"c|
lrIjJ
V
'测试帧频 -^hWM}F
'video field frequency 8b;1FQ'
fieldfrq = okGetSignalParam(hBoard, SIGNAL_FIELDFREQ) =E#%'/ A;c
If fieldfrq = -1 Then
BdH-9n~,
'lblSignal(8) = "不支持" %2{%Obp'
Else Oagsoik
'lblSignal(8) = Trim(Str(FieldFRQ)) + " 场数/秒" hFy;ffs.
End If i\r
Du^VQ
End Function &keR~~/
x#xFh0CA
7 *`h/
Sub PicIdentify() `ux{;4q
'本程序完成从文件中按顺序读出一幅图像并完成图像识别 Xx0hc 8qd
'根据固定位置判断透过车皮连接处接收的对面的立柱影像。出现立柱后该帧前1-2帧与后1-2帧分别为车号信息与车皮信息 Ay0U=#XP
'判定标准:如果在立柱位置上有明显的模式反差,则视为车皮之间的间隔 (Hb:?(
'方法:对立柱标志区进行平均值二值化,面积为32*40,亮区(255)与暗区(0)的亮度平均值理论差大于200倍,实际差值应不小于100倍 +{f:cea (1
>8#X;0\Kj
Dim fPTR As Long, cFrame As Long _8F`cuyW
Dim i As Long, j As Integer, pTotal As Long, pAV As Integer Ni-xx9)=
=k^Y?.
dQA'($
cFrame = 0 g'n7T|h
~
jk [1{I/
zv\kPfGDK
Do While cFrame < tFrames 1e{IC=
sg3OL/"
fStatus = SetFilePointer(hFile, cFrame * pFrameSize, 0&, FILE_BEGIN) n%.7h3
fStatus = ReadFile(hFile, ByVal hMEM, ByVal pFrameSize, bytesRW, ByVal 0&) {CGUL|y
MoveMemory pFRAME(1, 1), ByVal hMEM, pFrameSize 8h*Icf
8y.wSu
frmRecord.RText.Text = Str(cFrame) @] DVD
frmRecord.RText.Refresh R?
"q]af~
B][U4WJ)
If CheckMark = True Then S79;^X
ArrayToBMP TmpBMP
\kMefU
frmRecord.Picture1.Picture = LoadPicture(TmpBMP) D"2&
P^-
frmRecord.RText.Text = "第" & Str(cFrame) & "帧" &-Gqdnc
i/`m`qdg
DrawSlice L>aLqQ3
qGB{7-r u
'i = MsgBox("检测到立柱:第" & Str(cFrame) & "帧", vbYesNo) fY51:0{
'If i = vbNo Then ?kH8Lw~{5W
' Exit Do CFMo)"
'End If gv-xm
'cFrame = cFrame + 1 xRzFlay8
'}Z~JYa0
End If pm
9"4 z
DoEvents Tz8PS k1[
cFrame = cFrame + 1 y[)> yq y
Loop 5A3xVN=
End Sub #mCL) [
qzK
dQ&vO
W_\5nF
Function CheckMark(Optional iBlk As Integer = 30, Optional iWhite As Integer = 230) As Boolean xqG[~)~
aJbO((%$|u
'如标志区模式反差存在则为TRUE,否则返回FALSE !h23cj+V
:*
Z4yx
Dim i As Integer, j As Integer, mTotal As Long, mAV As Single, mTop As Long, mBot As Long x7!L{(E3
CheckMark = True rrBsb -
Ez
fN&8E
'复制标志区 ,*&:2o_r
For i = 1 To mkH %InA+5s`
MoveMemory MKpilar((i - 1) * PilarW + 1), pFRAME(PilarX, PilarY + i), PilarW AQ,'
6F9
Next i $0>60<J
g"
p%C:NN
For j = 1 To PilarW * PilarH / 2 Mh:L$f0A%O
mTop = mTop + MKpilar(j) zuJ@E=7
Next j =JK@z
#*K}IBz
For j = PilarW * PilarH / 2 + 1 To PilarW * PilarH e4
78U$
mBot = mBot + MKpilar(j) /_An
P
Next j p6#g;$V$
Eg#K.5hJ
mTop = mTop / PilarW / PilarH * 2 NV72
mBot = mBot / PilarW / PilarH * 2 *
KDI}B>
8pIP
mAV = (mTop + mBot) / 2 + (mBot - mTop) / 4 '标志区平均亮度 jHE}qE~>5
{GK;63`1
'平均值极值化 i@)i$i4
For j = 1 To PilarH * PilarW =S+wCN
MKpilar(j) = IIf(MKpilar(j) > mAV, 255, 0) v1+3}5b'uF
Next j 93("oBd[s(
m.#
VYN`+A
mTop = 0: mBot = 0 5HkKurab
For j = 1 To PilarH * PilarW / 2 ~962i#&4
mTop = mTop + MKpilar(j) (_mnB W
Next j Dwr)0nk
"55skmD.P
For j = PilarH * PilarW / 2 + 1 To PilarH * PilarW c
dl&9-}
mBot = mBot + MKpilar(j) )U7t
Next j k;AD`7(=
F4}]b(L
?
(Dq ?-.
mTop = mTop / PilarH / PilarW * 3 =jOv] /
mBot = mBot / PilarH / PilarW * 3 "U>JM@0DNm
-D
Tc>
If mBot > iWhite And mTop < iBlk Then QwJVS(Gs4
CheckMark = True cl=EA6P\X
Else r~jm`y
CheckMark = False G'Q-An%z
End If "GMBjT8
End Function PV'x+bN5
*'.|9W
Sub Capture1Frame() f33 2J
okCaptureTo hBoard, BUFFER, 0, 1 'single 5cL83FQh
okGetCaptureStatus hBoard, True K6v6yn
p/
MoveMemory pFRAME(1, 1), ByVal mBufferAddr, pFrameSize Z_};|B}
End Sub p*4':TFuD;
7~^GA.92
WM7oM~&{6
Sub CopyMark(iBlk As Integer, iWhite As Integer) %Gz0^[+
'复制标志区并返回标志区暗区与亮区的亮度平均值 jnK WZ/R
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 R_W+Ylob
Vd,jlt.t
'复制标志区 Fq~yL!#!
For i = 1 To mkH GK)?YM
MoveMemory MKpilar((i - 1) * PilarW + 1), pFRAME(PilarX, PilarY + i), PilarW 0QXVW}`hz
Next i ZRh~`yy
-3t7*
For j = 1 To mkW * mkH / 2 qT{U(
mTotal = mTotal + MKpilar(j) 8=B|C'>
Next j s C%&cRQD
n$xc];j
iBlk = mTotal / (mkW * mkH / 2) '标志区上部白区平均亮度 ww\CQ6/h
;f0I
8i,JN
mTotal = 0 ov`h
For j = mkW * mkH / 2 + 1 To mkW * mkH [842&5Pd?
mTotal = mTotal + MKpilar(j) +7D|4
Next j &=Ar
WejYy|
iWhite = mTotal / (mkW * mkH / 2) '标志区下部黑区平均亮度 bv]`!g:
C
bH7X'%r
'背景亮度 :|V$\!o'U
MoveMemory BsLine(1), pFRAME(1, 1), 4 * FrameW p4.wh|n
For i = 1 To 4 * FrameW ieDk ;
bsTotal = bsTotal + BsLine(i) q0i(i.h
Next i 2,$8icM
bsAV = bsTotal / FrameW / 4 V
wg|K|
!;&p"E|b#
End Sub l2zFKCGF(
Zd^rNHhA
]i&6c
Sub AdjIMGbright(Optional bInit As Boolean = True) cs,N <|
3}TaF~
'自动调节亮度与对比度,此时处于无车辆状态(白天特别高,而夜间特别暗) ck ]Do
!h
'图像平均亮度白天不高于200(当车辆通过时可能会下降到100左右),不低于100 BZ94NOOdw
' 夜间不高于80(过高时通常是由于雪花噪声引起),但立柱不低于30 zT=Ho
_E &A{HkJ
Dim bsTotal As Long, i As Integer, iBlack As Integer, iBright As Integer b#uL?f
Y;dz,}re
'按标准亮度与对比度采集一帧,确定背景亮度 :1cV;gJ
currentContr = 128 '初始对比度 @Lpq~ 1eZB
currentBr = 128 '初始亮度 >BIMi^
okSetVideoParam hBoard, VIDEO_BRIGHTNESS, currentBr '亮度 8'r2D+Vwm
okSetVideoParam hBoard, VIDEO_CONTRAST, currentContr '对比度 ?*[N_'2W+
DoEvents q@QksAq
Capture1Frame AF;)#T
<
'获得图像上缘4行象素 W98i[Q9A7
MoveMemory BsLine(1), pFRAME(1, 1), 4 * FrameW tvkb~
CopyMark iBlack, iBright '图像标志区亮度 ]
bM)t<
For i = 1 To 4 * FrameW Y>|B;Kj0(
bsTotal = bsTotal + BsLine(i) YIn',]p:
Next i 1L%CJ+Q#0i
bsAV = bsTotal / FrameW / 4 '图像上缘基线亮度 5gH1.7i b
.*@;@06?
Select Case bsAV *g:4e3Iy
Case 0 To 60 '夜间通过灯光照明,完全没有背景 wKtl+}}
currentBr = 150 x5,++7Tz
currentContr = 60 C]O(T2l{l
Case 61 To 80 '有可见背景 W]"zctE
currentBr = 140 q
MfT>rH
currentContr = 70 x[wq]q#*
Case 81 To 100 '有清晰背景 -[*,^Ti`
currentBr = 128 q-[@$9AS
currentContr = 80 ypbe!Y<i]
Case 100 To 150 '有明亮背景 UldXYtGe
currentBr = 140 '5:30-6:00钟实测数据 9TgIB
currentContr = 50 5L+>ewl
Case 151 To 180 zvYq@Mhr
currentBr = 130 CY
4gSe?
currentContr = 60 ;,C)!c&
Case 181 To 220 '背景全为白色 s>B5l2Q4
currentBr = 110 9oyE$S h]
currentContr = 130 0t^M3+nc
Case 221 To 255 '背景全为白色 YZL kL26[
currentBr = 100 <{dVKf,e
currentContr = 100 %q/62f
7?
End Select _Zp}?b5Q
4,bv)Im+ `
Select Case (iBlack + iBright) / 2 '图像反射光强度修正 oibsh(J3
Case 100 To 150 54gBJEhg
currentBr = currentBr - 10 p#ol*m5wE
Case 151 To 255 **w!CaqvY
currentBr = currentBr - 20 ?Nup1!
D
End Select ^nT/i
.#_
' KWyx
okSetVideoParam hBoard, VIDEO_BRIGHTNESS, currentBr '亮度 %824Cqdc
okSetVideoParam hBoard, VIDEO_CONTRAST, currentContr '对比度 09X01
X[
End Sub u!!Y=!y*<
B8nf,dj?X
Sub CopyCorner(rowID As Integer, diffL As Integer, diffR As Integer) ^!<U_;+
Dim i As Integer, j As Integer, L1 As Long, L2 As Long, R1 As Long, R2 As Long Ff$L|
bx#>BK!
For i = 1 To 8 PXK7b2fE.
MoveMemory LeftBK((i - 1) * 128 + 1, rowID), pFRAME(1, i), 128& ~+Rc}K
MoveMemory RightBK((i - 1) * 128 + 1, rowID), pFRAME(640, i), 128& kW2sY^Rg
Next i ^Ew]uN>,
y~B
h
For j = 1 To 1024 nGpXI\K
L1 = L1 + LeftBK(j, 0) @)UZ@ ~R
L2 = L2 + LeftBK(j, 1) W3]_m8,Z
R1 = R1 + RightBK(j, 0) X\]L=>]C
R2 = R2 + RightBK(j, 1) G! ]k#.^A,
Next j .GsV>H
diffL = Abs(L1 - L2) / 1024 Nh8Q b/::
diffR = Abs(R1 - R2) / 1024 sd ,J
3
End Sub c&
r70L,
TC@s
Function CheckSlice() As Boolean "9m2/D`=
CopySlice avSL, avSLR, avSLL ujDd1Bxf?
If Abs(avSL - avSLL) > (Abs(avSLL - avSLR) + 5) * 4 Then HFKfkAl
CheckSlice = True @KWb+?_H{<
Else @E;=*9ek{u
CheckSlice = False p31NI
f`
End If J}htu
End Function LIS)(X<]?
whmdcVh.
Sub CopySlice(avSL As Integer, avSLR As Integer, avSLL As Integer) x*![fK
Dim i As Long, j As Long, total As Long, totalL As Long, totalR As Long -d~4A
For i = 1 To FrameH b=g8eMm
MoveMemory Slice(1, i), pFRAME(sPos, i), sSize Lrta/SU*
MoveMemory SliceL(1, i), pFRAME(sPosL, i), sSize dU6ou'pf
MoveMemory SliceR(1, i), pFRAME(sPosR, i), sSize ta35 K"
Next i 2"0es40;0
For i = 1 To FrameH >z/#_z@LV
For j = 1 To sSize 33o9Yg|J~
total = total + Slice(j, i) Of-Rx/
totalL = totalL + SliceL(j, i) di?K"Z>
totalR = totalR + SliceR(j, i) bt"W(m&f
Next j ge,H-8'Z
Next i x^HGVWw_
avSL = total / FrameH / sSize Z,RzN5eN
avSLR = totalR / FrameH / sSize 'z0:Ccbj
avSLL = totalL / FrameH / sSize hU(umL<
End Sub 8J=?5
19&<|qTz
Sub DrawSlice() MC?,UDNd%
frmRecord.Picture1.Line (sPosL, 0)-(sPosL + sSize, FrameH), RGB(255, 0, 0), B vX{J' H]u
frmRecord.Picture1.Line (sPos, 0)-(sPos + sSize, FrameH), RGB(0, 255, 0), B :9O#ObFR
frmRecord.Picture1.Line (sPosR, 0)-(sPosR + sSize, FrameH), RGB(0, 0, 255), B w:%o?pKet1
frmRecord.RText.Text = Str(avSLL) & "/" & Str(avSL) & "/" & Str(avSLR) T?:Rdo!:u
End Sub A'j;\
`1
Sub DrawMark(pic As Control) H(R1o~
Dim i As Long, j As Long GS0;bI4ay
pic.Line (PilarX, FrameH - PilarY)-(PilarX + PilarW, FrameH - PilarY - PilarH / 2), RGB(255, 0, 0), B _4rFEYz$d
pic.Line (PilarX, FrameH - PilarY - PilarH / 2 - 1)-(PilarX + PilarW, FrameH - PilarY - PilarH), RGB(0, 0, 255), B VYu~26Zr
For i = 1 To PilarH a
K&b{d
For j = 1 To PilarW {\S+#W\
pic.PSet (PilarX + PilarW + 10 + j, FrameH - PilarY - i), RGB(MKpilar((i - 1) * PilarW + j), 0, 0)
>7wOoK|1'
Next j Ozw;(fDaU
Next i #Vl 0.l3
End Sub QP@%(]f G
NhfJ30~
Function avIMG() As Integer jq-p;-i
Dim i As Long, j As Long, totalIMG As Long 5\N(PL
MoveMemory pBuffer(1), pFRAME(1, 1), pFrameSize r#+d&.|
For i = 1 To pFrameSize Qt iDTr
totalIMG = totalIMG + pBuffer(i) NV)!7~r}:
Next i fdxLAC
avIMG = totalIMG / pFrameSize ~"!]
3C,L
End Function &)8:h+&Z
8B7cBkl:
Function avRegion(barCol As Integer, barWidth As Integer) As Integer Y,GU%[+
Dim i As Long, j As Long, totalIMG As Long `NnUyQ;T
For i = 1 To FrameH e&simX;W
MoveMemory pBuffer((i - 1) * barWidth + 1), pFRAME(barCol, i), barWidth CKtB-a
Next i o4`hY/<t
For i = 1 To FrameH * barWidth c]$i\i#
totalIMG = totalIMG + pBuffer(i) ,oN8HpGs
Next i k>F'ypm
avRegion = totalIMG / pFrameSize m`IC6*
End Function +awW3^1Ed