这才是我当年写出的一个比较烂的程序 V#cqRE3XNi
"
Jt.lL ]5
Main2.bas mMb'@
O>^C4c!
Attribute VB_Name = "SubMain" }"=AG
Option Explicit QS{1CC9$
*tgnYa[l
'采集文件与临时文件 r9 ui|>U"
Public Const TmpFile As String = "d:\30-0600.dat" Ys,{8Y,7
'已有数据:30-0600.dat /30日早6点进车与6:30出车头 W6"v)Jc>_
!R1.7}O
Public fStatus As Long, hFile As Long, bytesRW As Long, lptrFile As Long /RHo1
Public hBCFile As Long '记录采集参数的文件 qxFB%KqU
Public Const TmpBMP As String = "d:\1.bmp" mH Ic f{RG
Public hTmpFile As Long GG@md_
O+?<h{"
'[C.|)"
'采集窗口参数常量 F'B8v3
Public Const FrameH As Long = 280& UVw~8o9s
Public Const FrameW As Long = 768& 7
Garnd b
Public Const pFrameSize As Long = FrameW * FrameH 4F
{)i
:c
q9f2)
'标志区范围,用于识别车辆 Xb{
[c+.
Public Const PilarC As Integer = 260 '识别标志立柱中线坐标X `FYv3w2
Public Const mkW As Integer = 28 '识别标志立柱宽度 >S'17D
Public Const mkH As Integer = 80 ''识别标志立柱高度(上白中黑下白) |P -8HlOr
Public Const mkY As Integer = 4 ''识别标志立柱Y坐标(40-79白, 80-119黑,120-159白) 5]HS^II"
Public Const mkX As Integer = PilarC - mkW / 2 '识别标志立柱X坐标 4W3\P9p=
'车缝检测位置常数 %kB8'a3
Public Const sSize As Long = 32& @1DX
Public Const sPos As Long = 310& ~v]!+`_J
Public Const sPosL As Long = 200& 9[m6Li
Public Const sPosR As Long = 500& y($%;l
'车缝检测框位置 _Y8hb!#(
Public Slice(1 To sSize, 1 To FrameH) As Byte t?9v^vFR
Public SliceL(1 To sSize, 1 To FrameH) As Byte gF[z fDm
Public SliceR(1 To sSize, 1 To FrameH) As Byte O
[i#9)
Public avSL As Integer, avSLR As Integer, avSLL As Integer |4T!&[r
FI3)i>CnW
TiYnc3Bz}J
Public MKpilar(1 To mkW * mkH) As Byte '一维数组用于亮度对比度分析,比使用二维数组更便于VB编译优化 0%m)@ukb
'该数组用于亮度对比度调节、车辆通过识别与车皮间隔识别 &4b&X0pU
Public BsLine(1 To 4 * FrameW) As Byte, bsAV As Integer '图像的前4行。用于确定标志区的亮度与对比度范围 ai
nG6Y<O`
Public PilarW As Long, PilarH As Long, PilarX As Long, PilarY As Long <Wp
QbQM
Public LeftBK(1 To 1024, 0 To 1) As Byte, RightBK(1 To 1024, 0 To 1) As Byte %n
hm
'前后帧左右上角128列*8行像素块,根据平均值差绝对值判断进车方向 |lJX 3
Bx/L<J@
n@
U n
_io+YzS
'一次连续采集的帧数 4?-.ZUT-1
Public tFrames As Long :{IO=^D=$
xZ4~Oo@@_'
'在采集卡申请的缓存中,是按帧为单位的,每一帧包含奇偶场两场的数据 1jc,
Y.mP
'而该卡的硬件设置是按场采集,只需要读第一场的数据即可。 ~$p2#Aq
X
'所以要设置的缓存帧的大小是frameW*frameH*2,而一场的数据量为pFrameSize P?t"jKp'
"FTfk
Public pFRAME(1 To FrameW, 1 To FrameH) As Byte B
x (uRj
Public pBuffer(1 To FrameW * FrameH * 2) As Byte =
!`j7#:
Public pWorkSpace(1 To FrameW * FrameH) As Long SE),":aY
Public Const pBufferSize As Long = FrameW * FrameH * 2 hir4ZO%Zt
Public pGray(0 To 255) As Long '整幅图像的灰度直方图 |1b_3?e
'bo~%WA]n
Public hBoard As Long '采集卡标识 2I&o69x?
Public mBufferAddr As Long '缓存地址 T}"6wywM
Public BufferSize As Long '缓存大小(字节) SQqD:{#g"
Public iCurrentCard As Long 9'{}!-(xR
Public CapStatus As Long PB#fP_0C
Public iFrames As Long #B:hPZM1
Public currentBr As Byte, currentContr As Byte 6x
Z=^;H
UN zlN
Public hMEM As Long, mStatus As Long 91$]Qg,lB
Public Const hMemSize As Long = pFrameSize * 4 %*&UJpbA
Public hMemWork As Long :_t}
QP"
Public Const hMemWorkSize As Long = pFrameSize * 5 Sqo
:-
i K12pw
i { \%e
df
n9!h
'串口接收轨道衡数据 #m[|2R
Public WeightFromCom As String R,|d
`)T
Public bReceiveComplete As Boolean ;_^fk&+
,4ei2`wV
r8,romE$
Public Type GrayBMPHeader Eh|]i;G%
Tag As Integer J41G&$j(
FileLength As Long '文件大小 <o+<H
Reserve1 As Long |37
g ~
DataOffset As Long '图像数据偏移量 GKoK7qH\J
BMPHeaderSize As Long '文件头长 Nkp)Ax&
'length of the bitmap info header used to describe the bitmap colors, compression,… P&b19 K'
'the following sizes are possible: !zPa_`P
'28h - windows 3.1x, 95, nt, … I_xXDr
'0ch - os/2 1.x zxf"87se
'f0h - os/2 2.x |\U5),m
=k/IaFg 6w
ImageWidth As Long '图像宽(像素数) VY)9|JJCO
ImageHeight As Long '图像高(像素数) DqX{'jj
PlaneNumber As Integer '图像层数 RTv
qls
bpp As Integer 'bits per pixels '1 - monochrome bitmap s1e:v+B]
'4 - 16 color bitmap ^_ kJKM,
'8 - 256 color bitmap # g_Bx
'16 - 16bit (high color) bitmap nzmDA6d
'24 - 24bit (true color) bitmap
"dI;
'32 - 32bit (true color) bitmap <<i3r|}
Compression As Long '压缩方法 '0 - none (also identified by bi_rgb) nv0]05.4
'1 - rle 8-bit / pixel (also identified by bi_rle4) PSPmO'C+
'2 - rle 4-bit / pixel (also identified by bi_rle8) aBNZdX]vzO
'3 - bitfields (also identified by bi_bitfields) '3<fsK=
IMAGESIZE As Long '图像数据字节数 `&-Mi[1
hResolution As Long '水平分辩率 像素数/米 FIbp"~
vResolution As Long '垂直分辩率 5!EJxP9
ColorsinBMP As Long '图中所用的颜色。对256色图像总为0x100 3"G>>nC&
ImportantColors As Long s%2v3eb
Pallate(0 To 255) As Long '图像每个值对应的实际显示颜色,项数对应PallateNumber所指调色板项数 [+OnV&
End Type e0J6Ae4V[
*&d<yJM`b
=e8bNg
jK' N((Hz
Public BMPHeader As GrayBMPHeader, BMP1 As GrayBMPHeader %/YcL6o(
Public sRECT As RECT vq!_^F<
Ur5FC r
6$ Gep
Public conn As ADODB.Connection Op>%?W8/UF
Public rsTrain As ADODB.Recordset 1.gG^$J d
Public rsOperater As ADODB.Recordset 1
}tbH[
Public rsGoods As ADODB.Recordset ?}m']4p
Public rsGood2 As ADODB.Recordset qA!]E^0*Ke
Public rsSender As ADODB.Recordset <0S,Q+&
Public rsReceover As ADODB.Recordset
jq+A-T}@
Public rsTrainTMP As ADODB.Recordset MW PvR|Q
1!.(4gV
lhtZaU~V
'打开采集卡 F35#dIs`&
'设置参数 +e-G,%>9
'设置为实时单帧采集到缓存方式 (sQr X{~
'由另一线程查询采集状态,如果完成采集,传送至用户数组分析或保存 ZeEWp3vW
%zSuK8kxV
"h|'}7p
Sub Main() 8
O 67
Dim i As Integer, status As Long OX"j#
_z54Ycr4H
InitBMPinfo UQ[B?jc
'生成BMP文件头---该文件头是固定将pFRAME数组写成BMP文件 J]q%gcM
BMPHeader.Tag = &H4D42 i| ZceX/
BMPHeader.ImageWidth = FrameW z8[yt282
BMPHeader.ImageHeight = FrameH r" K':O6y
BMPHeader.BMPHeaderSize = &H28 #vzEu
)Ul
BMPHeader.PlaneNumber = 1 ;>AL`M+
BMPHeader.bpp = 8 g7&9"
BMPHeader.Compression = 0 n_
B"-n
BMPHeader.hResolution = &H1274 'Windows pBrush.exe的默认值,PhotoED.exe默值为0 YSj+\Z$(
BMPHeader.vResolution = &H1274 HgBGV0
BMPHeader.ColorsinBMP = 256 }sx_Yj
BMPHeader.ImportantColors = BMPHeader.ColorsinBMP .58qL-iC
BMPHeader.DataOffset = Len(BMPHeader) BSkDpr1C
For i = 0 To 255 VwEb7v,^0\
BMPHeader.Pallate(i) = RGB(i, i, i) m\ddp_l
Next i M4d47<'*~
BMPHeader.IMAGESIZE = FrameH * FrameW x ul]m*Z
BMPHeader.FileLength = Len(BMPHeader) + BMPHeader.IMAGESIZE |gsE2vV
U-:ieao@
=&},;VOh
MoveMemory BMP1, BMPHeader, Len(BMPHeader) MNg^]tpf
4T?h
BMP1.ImageWidth = FrameW qY>{cjo
BMP1.ImageHeight = FrameH * 2 bO&7-Z~:=
BMP1.IMAGESIZE = BMP1.ImageWidth * BMP1.ImageHeight |=EZ1<KzD
BMP1.FileLength = Len(BMP1) + BMP1.IMAGESIZE eYC ^4g%l(
H<QT3RF2
'确定标志位置,为pilarX, pilarY确定初始值 zLF?P3^
PilarW = mkW h(F<h_
PilarH = mkH '此两项为固定值 MSV2ip3
PilarX = GetSetting(App.EXEName, "Mark", "MarkX", mkX) 8@PX7!9
PilarY = GetSetting(App.EXEName, "Mark", "MarkY", mkY) '此两项需要在程序初始化时检查并进行调整 QMsHC%l3b
=+x yI
(%U@3._
'连续采集记录文件 AQc,>{Lm
' 建立一个缓冲区为页对齐方式的文件 .cR
-V`
If Dir(TmpFile) <> "" Then 6:]*c[7
hFile = CreateFile(TmpFile, GENERIC_READ Or GENERIC_WRITE, _ UThB7(O,
0&, 0&, OPEN_ALWAYS, FILE_FLAG_NO_BUFFERING, 0&) jZ%
TJ0(H
' 在95/98中,如果打开文件时没有声明overlapped方式,在读定文件时就不能使用overlapped参数项 YFTjPBV
' 而必须用setfilepointer函数调节与操作系统保留的文件指针。 5l,ZoB8
Else e#B#B
hFile = CreateFile(TmpFile, GENERIC_READ Or GENERIC_WRITE, _ Nr0
(E
0&, 0&, CREATE_ALWAYS, FILE_FLAG_NO_BUFFERING, 0&) ]q6;#EUr?
End If sg8/#_S1i
If hFile = 0 Then HF
q m6|
MsgBox TmpFile & ": File Open Error", vbOKOnly d oB
Exit Sub )LdyC`S\c
End If meCC?YAB
'采集参数记录文件 /l{&iLz[
hBCFile = FreeFile() Z(ZiFPx2Z
Open TmpFile + ".BC" For Binary Access Read Write As #hBCFile (?H0+zws^
3
E3qd'
hMEM = VirtualAlloc(ByVal 0&, hMemSize, MEM_COMMIT, PAGE_READWRITE) ’分配系统内容 VOr 1
If hMEM = 0 Then YOrrkbJ(
fStatus = GetLastError 3 ( ]M{4j
MsgBox "内存分配错误: 错误代码 - " & Str(fStatus) & vbCrLf _ (D
9Su^:1
& "请向技术人员报告该错误代码。", vbOKOnly de]z T^&C
CloseHandle hFile OKHX)"j\\
Exit Sub YhRWz=l
End If {<5ybbhLV
P1 zdK0TM
hMemWork = VirtualAlloc(ByVal 0&, hMemWorkSize, MEM_COMMIT, PAGE_READWRITE) HBY.DCN
[Z
If hMemWork = 0 Then 4pln5v=
fStatus = GetLastError <BW[1h1k5_
MsgBox "内存分配错误: 错误代码 - " & Str(fStatus) & vbCrLf _
i@][rdhT
& "请向技术人员报告该错误代码。", vbOKOnly ;P;((2_X9
'释放已成功分配的内存 u-1;'a
mStatus = VirtualFree(ByVal hMEM, hMemSize, MEM_DECOMMIT) m] W5+
mStatus = VirtualFree(ByVal hMEM, 0&, MEM_RELEASE) 8v71e>
2>\v*adG
CloseHandle hFile JMCW} bA
Exit Sub fi+R2p~vs
End If XK"-'
fl;s9:<
' Test writing ?X-)J=XG
'WriteFile hFile, ByVal hMEM, ByVal 4096&, bytesRW, ByVal 0& [lk'xzE
5'Q|EIL
'初始化采集卡参数 @A+RVg*=
iCurrentCard = -1 -!)xQvagD.
hBoard = okOpenBoard(iCurrentCard) fRfn2jA)d
Debug.Print hBoard TyKWy0x-3
If hBoard = 0 Then l?iSxqdT
ExitGrabber c,Euv>*`
End cv(PP-'\
End If :iiw3#]
okGetBufferSize hBoard, mBufferAddr, BufferSize ;r/;m\V
If mBufferAddr = 0 Then
5~.ZlGd
MsgBox "缓存不存在!" H
K~xOAF
ExitGrabber r|*&GHo L
End If U#n#7G6fRp
Debug.Print Hex(mBufferAddr), Hex(BufferSize) @
a4/ELx
jAh2N3)
QaGlR`Y
currentBr = 128: currentContr = 128 2..,Sk
'设置视频输入参数 $HG}[XD?
okSetVideoParam hBoard, VIDEO_SOURCECHAN, 1 'Video2 4G@nZn
' lParam=0,1.. Comp.Video; 0x100,101...to Y/C(S-Video), 0x200,0x201 to RGB Chan.Input ?go:e#
okSetVideoParam hBoard, VIDEO_BRIGHTNESS, currentBr '亮度 ?DH"V7bs
okSetVideoParam hBoard, VIDEO_CONTRAST, currentContr '对比度 ---初始设置条件下如果图像亮度达不到基本要求则控制灯光 h b/]8mR
okSetVideoParam hBoard, VIDEO_RGBFORMAT, FORM_GRAY8 '8位灰度模式 cD4
kC>P*
okSetVideoParam hBoard, VIDEO_TVSTANDARD, 0 'PAL制式 f""`cdqAOh
okSetVideoParam hBoard, VIDEO_SIGNALTYPE, &H10000 '逐行(低字)同步开槽(高字) v?c 0[+?
okSetVideoParam hBoard, VIDEO_RECTSHIFT, 144 + &H2C0000 '有效区起始位置:高字Y偏移,低字X偏移 (144/44经验值) zyg:nKQW
okSetVideoParam hBoard, VIDEO_AVAILRECTSIZE, FrameW + FrameH * 2 * &H10000 '有效区大小:低字X高字Y (768/576采集卡最大值) `+#G+Vu5
okSetVideoParam hBoard, VIDEO_FREQSEG, 0 ' 低频部分信号 {ls+dx/
f,z P*
'设置采集参数 a,Gxm!
okSetCaptureParam hBoard, CAPTURE_INTERVAL, 0 '逐帧 W[[bV
okSetCaptureParam hBoard, CAPTURE_CLIPMODE, 2 '裁剪方式 JxjI]SF02
okSetCaptureParam hBoard, CAPTURE_BUFRGBFORMAT, FORM_GRAY8 '8位灰度 4 V1bLm
okSetCaptureParam hBoard, CAPTURE_HARDMIRROR, 0 '不作镜像变换 dDDGM:]
okSetCaptureParam hBoard, CAPTURE_FRMRGBFORMAT, FORM_GRAY8 '帧存格式 xvNo(>
okSetCaptureParam hBoard, CAPTURE_SAMPLEFIELD, 0 ' 逐场采集 @R m-CWa
okSetCaptureParam hBoard, CAPTURE_HORZPIXELS, 944 '水平像素数 PAL制式固定值 hfcIvs/!
okSetCaptureParam hBoard, CAPTURE_VERTLINES, 625 '垂直线数 \*\R1_+
okSetCaptureParam hBoard, CAPTURE_SEQCAPWAIT, 0 '不等结束立即返回 `p'Q7m2y/b
'okSetCaptureParam hBoard, CAPTURE_BUFBLOCKSIZE, FrameW + FrameH * 2 * &H10000 h8G5GRD
'Buffer Block Size不用设置,而用okSetTargetRect函数进行动态调节 1shBY@mlq
XM<KF&pVB
^>?CMcN4*
okCloseBoard hBoard \ j.x0/;
Sleep 50 __@zT SVb
hBoard = okOpenBoard(iCurrentCard) '关闭后重新打开使新的设置值生效 ?%O3Oi Xz
.d?%;2*{q
'设置数据传送方式 =H8 xSJLh
'okSetConvertParam hBoard, CONVERT_FIELDEXTEND, FIELD_COPYEXTEND '逐行并扩展行 _al|'obomy
'该设置对本程序无意义,因为程序直接用CopyMemory方法读缓存,而扩展行方式是在用采集卡内置函数读RECT过程中实现的。 f(D_FTTO
b.O9I
TR
sRECT.Right = -1 '用于获得当前设置值 pr,p=4m{\
iFrames = okSetTargetRect(hBoard, BUFFER, sRECT) IZ3{>NV
Debug.Print sRECT.Left, sRECT.Right, sRECT.Top, sRECT.Bottom 81%8{yn!$"
Debug.Print okSetCaptureParam(hBoard, CAPTURE_BUFBLOCKSIZE, -1) 'FrameW + FrameH * &H10000 lZ&]|*>
sRECT.Left = 0 h7X_S4p/Mg
sRECT.Top = 0 &ff&Y.q~
sRECT.Right = sRECT.Left + FrameW 0e[d=)XG
sRECT.Bottom = sRECT.Top + FrameH * 2 N4K8
u'f^
iFrames = okSetTargetRect(hBoard, BUFFER, sRECT) ^2odr \
FA90`VOWYU
sRECT.Right = -1 '检查新设置值 PS
S?|V
k
iFrames = okSetTargetRect(hBoard, BUFFER, sRECT) idRD![!UI
Debug.Print sRECT.Left, sRECT.Right, sRECT.Top, sRECT.Bottom q@hp.(V
Debug.Print Hex(okSetCaptureParam(hBoard, CAPTURE_BUFBLOCKSIZE, -1)) Gq#~vr
j%V["?)
If TESTSignal = False Then !'=15&5@
'ExitGrabber U6[ang'l
End If 8wH.et25k
mfny4R1_
Zs2-u^3&
?8,%LIQ?
'设为实时采集状态 i{^Z1;Yl
'iFrames = okCaptureActive(hBoard, BUFFER, 0&) %g]vxm5?
<
P%}|@
h5kPn~
'单帧采集 >%Ee#m
'okWaitSignalEvent hBoard, EVENT_FRAMEHEADER, -1 qEUT90
'iFrames = okCaptureSingle(hBoard, BUFFER, 0&) QFPfIb/
okCaptureTo hBoard, BUFFER, 0, 1 'single }]UB;id'
'Do While okGetCaptureStatus(hBoard, False) <> 0 QMo}W{D
' Sleep 20 GO! uwo:
'Loop U"f??y%)
okGetCaptureStatus hBoard, True X~Rl 6/,
MoveMemory pFRAME(1, 1), ByVal mBufferAddr, pFrameSize W
YW|P2*
'写入768*576测试图象 mqfO4"lt
ArrayToBMP TmpBMP H ftxS
x\s,= n3z
'打开数据库 $[@0^IJq=K
Set conn = New ADODB.Connection ?@6/Alk
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ I1 U7.CT
"Persist Security Info=False;Data Source=" & "c:\train\train.mdb" & _ ~^)^q
8
"; Mode=Read|Write" iv(5&'[p
conn.Open Q6C-4ja
wzjU,Mwe
frmRecord.Picture1.Picture = LoadPicture(TmpBMP) ZiFooA
frmRecord.Visible = True W2-=U@
frmQuery.Visible = True ]+DI.%
Load frmReceiveFromComm 'rb'7=z5
\4ghYQ:
'调试参数 O)R(==P26P
If InStr(UCase(Command()), "/CAPTURE") > 0 Then 2h
{q h
SignalBox.Visible = True iP3Z
End If B6}FIg)
If InStr(UCase(Command()), "/COMM") > 0 Then 9^F2$+T[:
frmReceiveFromComm.Visible = True 6qo^2
End If <uP^-bv;(
2WvN2"f3
End Sub DZ
^1s~
]J2:194
Sub ExitGrabber() rAQF9O[
'关闭数据库 HjWq[[Nz
'关闭采集卡 W&"|}Pi/
mStatus = VirtualFree(ByVal hMEM, hMemSize, MEM_DECOMMIT) EA<}[4#jS
mStatus = VirtualFree(ByVal hMEM, 0&, MEM_RELEASE) t j Vh^
mStatus = VirtualFree(ByVal hMemWork, hMemWorkSize, MEM_DECOMMIT) IB9%QW"0
mStatus = VirtualFree(ByVal hMemWork, 0&, MEM_RELEASE) ]7AX%EG3
okStopCapture hBoard Z<b"`ty.
okCloseBoard hBoard P5QQpY{<I
CloseHandle hFile }iBC@`mg(
Close #hBCFile G&eP5'B4i
conn.Close Cup@TET35
End % 0:p)Z0
End Sub $trAC@3O@
tGcya0RL
Function ArrayToBMP(ByVal File As String) -m 5}#P89
Dim BytesWrite As Long w-N1.^
]r]k-GZ$
hTmpFile = CreateFile(File, GENERIC_READ Or GENERIC_WRITE, 0&, 0&, _ ;P?q2jI
CREATE_ALWAYS, 0&, 0&) Lp:6 ;
2_QN&o ~h
If hTmpFile = 0 Then 0m9ZQ
O
ArrayToBMP = False m:Go-tk
Exit Function h7_)%U<J2
End If '_+9y5
X7*`
SetFilePointer hTmpFile, 0&, 0&, FILE_BEGIN ts9pM~_~
WriteFile hTmpFile, BMPHeader, 2&, BytesWrite, ByVal 0& 24\gb
v<
SetFilePointer hTmpFile, 2&, 0&, FILE_BEGIN J?:[$ C5
WriteFile hTmpFile, BMPHeader.FileLength, Len(BMPHeader) - 2, BytesWrite, ByVal 0& P}3}ek1Ax
O,V9R
rG
SetFilePointer hTmpFile, Len(BMPHeader), 0&, FILE_BEGIN YJ7V`Np
WriteFile hTmpFile, pFRAME(1, 1), pFrameSize, BytesWrite, ByVal 0& 1D([@)^
o5Rz%k#h
If BytesWrite < pFrameSize Then ZC
^C
ArrayToBMP = False ^%oUmwP<$
End If 3mt%!}S
HO|-@yOF^
CloseHandle hTmpFile 8_\W/I!7b
)E7 FA|
End Function I12KT~z<r
K=u0nrG*
Function ArrayToBMP1(ByVal File As String) ZX`J8lZP
%NHYW\sKX
Dim BytesWrite As Long 1ywU@].6J]
yfjXqn[Z4
hTmpFile = CreateFile(File, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, _ u~ F;xQ
CREATE_ALWAYS, 0&, 0&)
r@)A
k
w5~i^x
If hTmpFile = 0 Then q<=:
>?
ArrayToBMP1 = False ? S=W&
Exit Function R
-elIp
End If D>T],3U(H
i&+w _hD
SetFilePointer hTmpFile, 0&, 0&, FILE_BEGIN ySNV^+
WriteFile hTmpFile, BMP1, 2&, BytesWrite, ByVal 0& GSVdb/+
_94s(~g:
SetFilePointer hTmpFile, 2&, 0&, FILE_BEGIN rE!1wc>L
WriteFile hTmpFile, BMP1.FileLength, Len(BMP1) - 2, BytesWrite, ByVal 0& {M~lbU
*8g<R
SetFilePointer hTmpFile, Len(BMP1), 0&, FILE_BEGIN sJr5t?
WriteFile hTmpFile, pBuffer(1), pBufferSize, BytesWrite, ByVal 0& 2C+(":=}
s'a= _cN
If BytesWrite < pBufferSize Then ^Ip3A
ArrayToBMP1 = False R 4EEelSZu
End If 3-wD^4)O,
1|y$~R.H
CloseHandle hTmpFile GaNq2 G
d}0qJoH4
End Function ?H;{~n?
f_r0})
'使用该过程建立的文件要求在用后关闭 W 5DbFSgB
Public Function ArrayToBMP2(File As String) As Boolean T.?k>Ak
u"VS* hSH
Dim BytesWrite As Long ]= x
1`j
-
HOnB=
ArrayToBMP2 = True Aa(<L$e!`
Bmr<O!
hTmpFile = CreateFile(File, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, _ |D
G@ht
CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0&) +GNWF%
zN
0~E 6QhV:
If hTmpFile = 0 Then )q?
$p9
ArrayToBMP2 = False '?/&n8J\
Exit Function ]YD(`42 x
End If -]"T^wib
jD<pIHau
SetFilePointer hTmpFile, 0&, 0&, FILE_BEGIN nTnRGf\T
WriteFile hTmpFile, BMPHeader, 2, BytesWrite, ByVal 0& ~5#)N{GbY
j64 4V|z
SetFilePointer hTmpFile, 2&, 0&, FILE_BEGIN 9fVj
8G
WriteFile hTmpFile, BMPHeader.FileLength, Len(BMPHeader) - 2, BytesWrite, ByVal 0& M?:\9DDd
} ~enEZ
SetFilePointer hTmpFile, Len(BMPHeader), 0&, FILE_BEGIN w^VSj%XH!
WriteFile hTmpFile, pFRAME(1, 1), pFrameSize, BytesWrite, ByVal 0& Q^h5">P
Xza4iV
If BytesWrite < pFrameSize Then #+sF`qR,
ArrayToBMP2 = False XdIah<F2
End If )@PnTpL*
mc@M ,2@D
CloseHandle hTmpFile mA{#]Yvf1
!QC<n/
End Function iK}v`xq
a>Re^GT+z
Private Function TESTSignal() As Boolean 3B18dv,V
Dim extsign As Long, videotype As Long, scanlines As Long, fieldfrq As Long z&'f/w8
2>y:N.
extsign = okGetSignalParam(hBoard, SIGNAL_VIDEOEXIST) wa3F
Z$2L~j"=!
If extsign = 1 Then F,Fo}YQX
TESTSignal = True nmE5]Pcg
Else 6&!l'[hU
If extsign = 0 Then :k"rhI
MsgBox "无视频输入信号,检查摄像机电源!", vbOKOnly ,w\ wQn>]K
TESTSignal = False [ #]jC[
Exit Function 03E3cp"
End If L
DX*<(
End If Kmry=`=A
1MQ/r*(
'测试视频输入类型 #vnT&FN0[
'video type )bW<8f2
okWaitSignalEvent hBoard, EVENT_ODDFIELD, 40 1$["79k
videotype = okGetSignalParam(hBoard, SIGNAL_VIDEOTYPE) ^e9aD9
If videotype = 1 Then (wL3 +
'"隔行信号(Interlaced)" 5d
5t9+t
Else Ee?;i<u
If videotype = 0 Then i-13~Dk
'"逐行信号(Non-interlaced)" a&5g!;.
Else zHFTCL>"
If videotype = -1 Then ^8742.
' "不支持" h(:<(o@<
End If $pu3Ig$^
End If (Pz8iz
End If D!l8l49hLu
i,OKfXp
'测试垂直扫描线数 STT2o=
'video scanlines *wUdC
scanlines = -1 kEAhTh&g*
scanlines = okGetSignalParam(hBoard, SIGNAL_SCANLINES) 1i,4".h?M
If scanlines = -1 Then q+/l"&j.
' "不支持" 3q~Fl=|.o
Else 6F5,3&
'Trim(Str(ScanLines)) + " 行数/幅" jU$Y>S>l
End If KS! iL=i
NNX%Bq
'测试帧频 AVpuM
Nd@
'video field frequency ER<eX4oU
fieldfrq = okGetSignalParam(hBoard, SIGNAL_FIELDFREQ)
-Cj_B\
If fieldfrq = -1 Then ,C!n}+27
'lblSignal(8) = "不支持" 46ChMTt
Else |3@=CE7G
'lblSignal(8) = Trim(Str(FieldFRQ)) + " 场数/秒" 0eA5zFU7
End If ec'tFL
#u{
End Function .~<]HAwq
=J.EH|
ZlM_m
>,o
Sub PicIdentify() UX}*X`{
'本程序完成从文件中按顺序读出一幅图像并完成图像识别 _7 `E[&v
'根据固定位置判断透过车皮连接处接收的对面的立柱影像。出现立柱后该帧前1-2帧与后1-2帧分别为车号信息与车皮信息 Jr
?!Mh-
'判定标准:如果在立柱位置上有明显的模式反差,则视为车皮之间的间隔 7
\/u&
'方法:对立柱标志区进行平均值二值化,面积为32*40,亮区(255)与暗区(0)的亮度平均值理论差大于200倍,实际差值应不小于100倍 zz3 r<?#5
i<:p.ug-O
Dim fPTR As Long, cFrame As Long qc-C>Ra
Dim i As Long, j As Integer, pTotal As Long, pAV As Integer Ao*FcrXN
Y\8+}g;KR
x(6vh2#vD
cFrame = 0 C"No5r'K3
/+P5)q
TKL
<JH9StGGc?
Do While cFrame < tFrames @zs1>\J7
V_M@g;<o
fStatus = SetFilePointer(hFile, cFrame * pFrameSize, 0&, FILE_BEGIN) 4<yK7x
fStatus = ReadFile(hFile, ByVal hMEM, ByVal pFrameSize, bytesRW, ByVal 0&) E4m:1=Nd~]
MoveMemory pFRAME(1, 1), ByVal hMEM, pFrameSize 44Qk;8*
%gTVW!q
frmRecord.RText.Text = Str(cFrame) +E#PJ_H=F8
frmRecord.RText.Refresh QZ0R :TY
Ld~4nc$H8
If CheckMark = True Then K{FhT9R'
ArrayToBMP TmpBMP 62NkU)u
frmRecord.Picture1.Picture = LoadPicture(TmpBMP) kknhthJ
frmRecord.RText.Text = "第" & Str(cFrame) & "帧" >Fh#DmQ
>nNl^ yqW
DrawSlice |UZOAGiBg
~h|m&XK+Q
'i = MsgBox("检测到立柱:第" & Str(cFrame) & "帧", vbYesNo) =+(
Q.LmhC
'If i = vbNo Then Xoi9d1fO
' Exit Do XW:%vJu^`
'End If y*|L:!
'cFrame = cFrame + 1 Qg{WMlyOP
\)GR\~z0h
End If jNqVdP]d\
DoEvents {9{J^@ @
cFrame = cFrame + 1 #fzw WP
Loop dqwWfn1lt
End Sub g
2#F
_
[iXi\Ex
yjv&4pIc1
Function CheckMark(Optional iBlk As Integer = 30, Optional iWhite As Integer = 230) As Boolean %(NN*o9"q
<|Iyt[s
'如标志区模式反差存在则为TRUE,否则返回FALSE m9b(3
TPqvp|~2
Dim i As Integer, j As Integer, mTotal As Long, mAV As Single, mTop As Long, mBot As Long ,Z4^'1{D
CheckMark = True D?J#u;h~f
r$?Vx_f`Q
'复制标志区 !3?~#e{_
For i = 1 To mkH N4+g("
MoveMemory MKpilar((i - 1) * PilarW + 1), pFRAME(PilarX, PilarY + i), PilarW ;r=?BbND?
Next i *s36OF!
UhA_1A'B
For j = 1 To PilarW * PilarH / 2 yjR)Z9t
mTop = mTop + MKpilar(j) S]b
xQa+
Next j .
]zw*t*
%OFj
For j = PilarW * PilarH / 2 + 1 To PilarW * PilarH H\f/n`@,G
mBot = mBot + MKpilar(j) $$~a=q,P[
Next j H CuK
h;}ODK(.
mTop = mTop / PilarW / PilarH * 2 &$Ci}{{n#
mBot = mBot / PilarW / PilarH * 2 ywe5tU
.hgH9$\
mAV = (mTop + mBot) / 2 + (mBot - mTop) / 4 '标志区平均亮度 7A[Ogro
5"e+& zU~f
'平均值极值化 "<T ~jk"u
For j = 1 To PilarH * PilarW `
Rsl]
GB
MKpilar(j) = IIf(MKpilar(j) > mAV, 255, 0) QP<FCmt8
Next j F b2
p(.
k?n]ZNlT
mTop = 0: mBot = 0 ip674'bq7R
For j = 1 To PilarH * PilarW / 2 q@w"yz>
mTop = mTop + MKpilar(j) VB's
Next j J2=*-O:
i)8g CDc
For j = PilarH * PilarW / 2 + 1 To PilarH * PilarW ( w5f(4
mBot = mBot + MKpilar(j) A{t"M-<
Next j d{l{P]nr
;6zPiaDQ
5d(qtFH1
mTop = mTop / PilarH / PilarW * 3 W\a!Q]pV
mBot = mBot / PilarH / PilarW * 3 A
_]D~HH
79a9L{gso
YkVRl [
If mBot > iWhite And mTop < iBlk Then g X8**g'
CheckMark = True p*!q}%U
Else vQcUaPm\$
CheckMark = False ,=x
RoXYB}
End If ,.q8Xf
End Function b+_hI)T
lnjL7x
Sub Capture1Frame() m"q/,}DR
okCaptureTo hBoard, BUFFER, 0, 1 'single :=Nb=&lst
okGetCaptureStatus hBoard, True
Bjtj{B
MoveMemory pFRAME(1, 1), ByVal mBufferAddr, pFrameSize CCn/ udp@
End Sub a6P
!Wzb
/xF
9:r
b<8q 92F
Sub CopyMark(iBlk As Integer, iWhite As Integer) }*Dd/'2+1
'复制标志区并返回标志区暗区与亮区的亮度平均值 0+p
5/5
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 >waN;
&>/
n'Bmz
'复制标志区 9G+y.^/6
For i = 1 To mkH .h a`)@MsZ
MoveMemory MKpilar((i - 1) * PilarW + 1), pFRAME(PilarX, PilarY + i), PilarW m.Twgin
Next i Slo9#26
^YqbjL
For j = 1 To mkW * mkH / 2 u5/t2}^T
mTotal = mTotal + MKpilar(j) 4^`PiRGt
Next j <qr^Nyo4
H[Cj7{V
iBlk = mTotal / (mkW * mkH / 2) '标志区上部白区平均亮度 v/ eB
,p
#[Z<