VB中调用摄像头视频捕捉问题,急求解决方法

tembo09 2016-02-11 09:16:53
Private Sub Command1_Click()
SendMessage ctCapWin, WM_CAP_Sequence, 0, 0 '开始录像,录像未结束前不会返回
End Sub


Private Sub Command2_Click()
Image9.Visible = False
Image2.Visible = True

Dim nStyle As Long, T As Long

If ctCapWin = 0 Then '创建一个视频窗口,大小:640*480
T = Me.ScaleY(200, Me.ScaleMode, 3) '视频窗口垂直位置:像素
'nStyle = WS_Child + WS_Visible + WS_Caption + WS_ThickFrame '子窗口(在Form1内)+可见+标题栏+边框
'nStyle = WS_Child + WS_Visible '视频窗口无标题栏和边框
nStyle = WS_Visible '视频窗口为独立窗口,关闭主窗口视频窗口也会自动关闭
ctCapWin = capCreateCaptureWindow("视频监视中", nStyle, 0, T, 640, 480, Me.hWnd, 0)
End If
'将视频窗口连接到摄像头,如无后面两条语句视频窗口画面不会变化
SendMessage ctCapWin, WM_CAP_Connect, 0, 0 '连接摄像头
SendMessage ctCapWin, WM_CAP_Set_PreView, 1, 0 '第三个参数:1-预览模式有效,0-预览模式无效
SendMessage ctCapWin, WM_CAP_Set_PreViewRate, 30, 0 '第三个参数:设置预览显示频率为每秒 30 帧
End Sub



问题,如上程序所述,分别采用两个COMMAND 触发来实现视频建立连接和录相是完全没有问题的,但我用串口中断接收指令的形式来建立连接和录相就会出现白屏或卡死的现象,很奇怪,求高人指导。谢谢
...全文
1061 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tiger_Zhao 2016-05-05
  • 打赏
  • 举报
回复
关于绿屏的猜测:你单独的录像程序可能窗体还没有完全加载你就开始录像了,也可以加个timer延时启动录像。
tembo09 2016-05-05
  • 打赏
  • 举报
回复
谢谢Tiger_Zhao的指点!按照你的方式,效果好多了,但是我把录相功能单独生成了个EXE文件,TIMER触发打开这个录相程序或者关闭,这样会比在程序里加载录相好些,但有时会出现录相界面变成一片绿的现象,但相比以前的白屏和卡住问题没有了,看来还是把问题想复杂了,一直在琢磨多线程了,呵呵。
Tiger_Zhao 2016-05-03
  • 打赏
  • 举报
回复
是啊。把调用 jieshou 改为启动 Timer,在 Timer 事件中再调用 jieshou。
tembo09 2016-05-03
  • 打赏
  • 举报
回复
Private Sub MSComm1_OnComm()

Dim i As Integer
Dim c As String
Dim S As Integer
Dim N As Integer
Dim H As Integer

On Error GoTo Err

With MSComm1
Select Case MSComm1.CommEvent
Case comEvReceive
'MSComm1.RThreshold = 0
revbuf = MSComm1.Input
For i = 1 To Len(revbuf)
c = Mid(revbuf, i, 1)
TextReceive.Text = TextReceive.Text & c '输出显示
Next i

If Mid(revbuf, 1, 1) = "S" Then '对接收字符串是否符合要求作判断,本句拟增加接收字符串长做判断.
Image2.Visible = False
Image9.Visible = True
Label1.Caption = Mid(revbuf, 2, 3)
Label2.Caption = Mid(revbuf, 6, 3)

End If
If Mid(revbuf, 1, 1) = "H" Then '对接收字符串是否符合要求作判断,本句拟增加接收字符串长做判断.
Label3.Caption = Mid(revbuf, 2, 2)

End If

Call jieshou

'MSComm1.RThreshold = 1

End Select

End With
revbuf = ""
Err:
End Sub

Public Function jieshou()

Dim data(1) As Byte
Dim nStyle As Long, T As Long

Select Case revbuf

Case "count=1;"

If ctCapWin = 0 Then '创建一个视频窗口,大小:640*480

T = Me.ScaleY(200, Me.ScaleMode, 3) '视频窗口垂直位置:像素
'nStyle = WS_Child + WS_Visible + WS_Caption + WS_ThickFrame '子窗口(在Form1内)+可见+标题栏+边框
'nStyle = WS_Child + WS_Visible '视频窗口无标题栏和边框
nStyle = WS_Visible '视频窗口为独立窗口,关闭主窗口视频窗口也会自动关闭
ctCapWin = capCreateCaptureWindow("视频监视中", nStyle, 0, T, 640, 480, Me.hWnd, 0)
End If

'将视频窗口连接到摄像头,如无后面两条语句视频窗口画面不会变化
SendMessage ctCapWin, WM_CAP_Connect, 0, 0 '连接摄像头
SendMessage ctCapWin, WM_CAP_Set_PreView, 1, 0 '第三个参数:1-预览模式有效,0-预览模式无效
SendMessage ctCapWin, WM_CAP_Set_PreViewRate, 30, 0 '第三个参数:设置预览显示频率为每秒 30 帧

SendMessage ctCapWin, WM_CAP_Sequence, 0, 0 '开始录像,录像未结束前不会返回

Case "count=0;"

SendMessage ctCapWin, WM_CAP_Stop, 0, 0 '终止视频捕获
SendMessage ctCapWin, WM_CAP_DisConnect, 0, 0 '断开摄像头连接
SendMessage ctCapWin, WM_CLOSE, 0, 0 '关闭指定窗体标题的窗体
ctCapWin = 0

Case Else
End Select

End Function


谢谢Tiger_Zhao的指点!本人VB算是菜鸟水平,还请前辈费心指导,现在程序是这样的,电脑串口接收到单片机系统发来的指令后进入Function jieshou()程序中处理,是不是录相过程中还没有串口中断返回啊?
赵4老师 2016-05-03
  • 打赏
  • 举报
回复
可以考虑使用多进程。 不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如: A将请求数据写到文件a.txt,写完后改名为aa.txt B发现aa.txt存在时,读取其内容,调用相应功能,将结果写到文件b.txt,写完后删除aa.txt,改名为bb.txt A发现bb.txt存在时,读取其内容,读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境,B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢? 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话,文本文件的格式问题可参考json或xml 共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出我现在能想到的: ·进程之间松耦合 ·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。 ·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务,只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满) ·…… “跨语言、跨机,跨操作系统,跨硬件平台,跨国,跨*.*的”苦海无边, 回头是“使用共享纯文本文件进行信息交流”的岸!
Tiger_Zhao 2016-05-03
  • 打赏
  • 举报
回复
你的串口指令响应没返回就录像,所以卡死了。
用不着多线程,只要加个 Timer 控件进行延时应该就可以了:
串口指令响应过程中开启 Timer 后就返回;
一小段延时后 Timer 事件触发,把 Timer 停止,然后开始录像。
tembo09 2016-05-03
  • 打赏
  • 举报
回复
谢谢你的建议,我的硬件系统是这样的:单片机系统做为下位机与电脑通过232串口连接,电脑上插有USB的视频摄像头,工作的某个时候,单片机会向电脑串口发送一个开始录相的指令,电脑上的VB软件接收到这个指令后,自动打开录相窗口并开始录相,直到下位机再次向电脑串口发送停止录相指令,这时自动关闭录相窗口断开摄像头连接,并自动保存视频到默认目录下。基本功能就是这样了,我现在单独做视频采集可以,只是一加上串口指令中断处理程序就会卡死。是不是得用多线程啊??
现在还是人类 2016-02-18
  • 打赏
  • 举报
回复
串口中断接收指令?怎么用?和串口有什么关系?摄像头是串口的? 还有你的中断指令是什么回事?你跳过API直接触发 Ring 3 的CPU中断?但“串口中断”又好像是DOS的概念, 你到底说写什么?怎么完全没搞清楚你的是什么状况呢? 我知道的目前在Windows上比较流行的采集摄像头方法有两种。 1、是VFW技术,就是你用的 capCreateCaptureWindow 这种东西,其实你仔细看一下模块代码,你会发现也是windows消息,只是封装一下而已,和你else下面的SendMessage并无二异,为非是封装了SendMessage而已。 2、DirectShow,这看DX版本的,不过高版本的DX没有VB6的范例,DX8.1还有。 相对来说VFW的使用是VB6最常用的,只是兼容性不高,如系统版本,硬件支持等可能会存在问题。 不过对于固定的老系统和固定的硬件在兼容性上看到是问题不大。 而DirectShow兼容性好好很多,VFW不能正常访问的硬件DirectShow也能正常,而且效率高。只是vb6嘛还是用vfw吧。不然就在别的开发工具用DirectShow弄个控件出来给vb6用也可以。 对于vfw,你可以看看这个范例,是采集用的(不用显示出来也可采集到摄像头的位图数据) http://blog.csdn.net/supermanking/article/details/3207341 如果你想了解DirectShow,你可以去下个DX SDK,不过新版本的 DX SDK通常都是VC.NET 或是 VB.NET 的。
vansoft 2016-02-15
  • 打赏
  • 举报
回复
推荐你个控件,我们公司在用。 VideoCapX,自己百度。

7,785

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧