前些天在手创买了个OV5116的摄像头,回来后用绘声绘影软件和EasyCap视频采集卡看不到图像, 用示波器测试摄像头的时序信号完全正确,并且注意到场中断是16.6 ms,也就是说该视频信号是NTSC制式的,和摄像头附带资料上的摄像头参数(field 60 HZ)说明相符合。
我又换了个OV7950的摄像头(彩色的,图像非常漂亮,也是在手创买的),回来后也看不到图像,咨询了一下手创的技术人员,说OV7950也是NTSC制式的。手创的技术人员说一个摄像头看不到图像他可以忍受,但是两个都看不到他无法忍受了。呵呵,听了他的话,我自己也觉得不正常,毕竟人家专业,然后开始从我自己身上查找原因,首先从视频采集卡下手,我换了个OV6620摄像头(50HZ,PAL制式的),可以看到图像;我又查过视频采集卡的资料,可以支持NTSC制式的。这样我排除了视频采集卡的原因, 然后又从绘声绘影软件下手查找原因。
我打开软件,挨个的去尝试打开那些以前没用到过的一些功能和选项区找一下是不是我对软件的设置没有操作正确,然后就有了突破性的发现。呵呵,我改了一下设置,就看到图像啦。
我简单总结如下:
1.摄像头制式判别:目前的视频制式我用过的又两种:PAL制式和NTSC制式。我们中国用的是PAL制式。大家可以去网上随便百度一下,就可以了解了。你的摄像头是什么制式的要去看技术文档,如果是英文文档,摄像头参数有个field (就是场频)参数,如果它是50HZ,那么它就是Pal制式的;如果field 是60HZ,就是NTSC制式的。这样只看技术文档还不行,因为摄像头的制式是可以通过SCCB来更改的,有可能进行过改装,所以,从严谨的角度出发,大家一定要用示波器去测试摄像头场中断的时序信号,如果您读出来的时序信号的周期是20 ms,那么它是PAL制式的;如果是16.6 ms 左右的,那么它是NTSC制式的。这个是怎么算的,大家对场频参数取倒数就是周期了。还有些地方给的参数是帧频(一帧就是一幅图像),帧频是场频的一半,也就是说,PAL制式的帧频是25HZ,NTSC制式的是30HZ。
2.绘声绘影软件使用:绘声绘影软件正确安装后,默认只支持PAL制式的图像,大家注意,PAL制式和NTSC制式不能兼容。如果您的摄像头测试以后确定是PAL制式的,您对软件设置可以不做修改,但是如果您的摄像头是NTSC制式的,您使用默认设置就看不到图像了(我以前用的摄像头都是PAL制式的,因此形成了定性思维,再加上自己本身对软件业没有透彻了解过,我就走了弯路,带来了很多麻烦)。
修改设置方法如下:打开软件后,在面板上找到“选项”这一个选项,单击它,然后出来的下拉菜单有一个“视频和音频捕获属性设置”,打开它,找到“电视制式”,改成NTSC,然后“输入来源”改成视频组合,大家根据自己的实际情况进行设置,总之,大概是这个意思,呵呵。
说明:以上只是我根据自己的经验和查阅的资料提出的一点个人见解,希望对大家有所帮助,少走弯路,不具有权威性,与其他大虾著作的文档如有雷同,纯属巧合,
最后,小弟不才,班门弄斧了,呵呵,如果我有说错的,恳请指教并拜求改正,谢谢!
“选择手创,没错!!”
第二篇:摄像头
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
namespace WeightSystem
{
/// <summary>
/// 一个控制摄像头的类
/// </summary>
public class Pick
{
private const int WM_USER = 0x400;
private const int WS_CHILD = 0x40000000;
private const int WS_VISIBLE = 0x10000000;
private const int WM_CAP_START = WM_USER;
private const int WM_CAP_STOP = WM_CAP_START + 68;
private const int WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
private const int WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11; private const int WM_CAP_SAVEDIB = WM_CAP_START + 25;
private const int WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
private const int WM_CAP_SEQUENCE = WM_CAP_START + 62;
private const int WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20; private const int WM_CAP_SEQUENCE_NOFILE = WM_CAP_START + 63; private const int WM_CAP_SET_OVERLAY = WM_CAP_START + 51;
private const int WM_CAP_SET_PREVIEW = WM_CAP_START + 50;
private const int WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START + 6; private const int WM_CAP_SET_CALLBACK_ERROR = WM_CAP_START + 2; private const int WM_CAP_SET_CALLBACK_STATUSA = WM_CAP_START + 3; private const int WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START + 5; private const int WM_CAP_SET_SCALE = WM_CAP_START + 53;
private const int WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52;
public static int WM_CAP_DLG_VIDEOSOURCE = (WM_CAP_START + 42); //选择摄像头
private IntPtr hWndC;
private bool bStat = false;
private IntPtr mControlPtr;
private int mWidth;
private int mHeight;
private int mLeft;
private int mTop;
/// <summary>
/// 初始化摄像头
/// </summary>
/// <param name="handle">控件的句柄</param>
/// <param name="left">开始显示的左边距</param>
/// <param name="top">开始显示的上边距</param>
/// <param name="width">要显示的宽度</param>
/// <param name="height">要显示的长度</param>
public Pick(IntPtr handle, int left, int top, int width, int height) {
mControlPtr = handle;
mWidth = width;
mHeight = height;
mLeft = left;
mTop = top;
}
[DllImport("avicap32.dll")]
private static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
[DllImport("avicap32.dll")]
private static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize);
[DllImport("User32.dll")]
private static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
/// <summary>
/// 开始显示图像
/// </summary>
public void Start()
{
if (bStat)
return;
bStat = true;
byte[] lpszName = new byte[100];
hWndC = capCreateCaptureWindowA(lpszName, WS_CHILD | WS_VISIBLE, mLeft, mTop, mWidth, mHeight, mControlPtr, 0);
if (hWndC.ToInt32() != 0)
{
SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0); SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0); SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0);
SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0);
SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0);
SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0);
}
return;
}
/// <summary>
/// 停止显示
/// </summary>
public void Stop()
{
SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
bStat = false;
}
/// <summary>
/// 抓图
/// </summary>
/// <param name="path">要保存bmp文件的路径</param>
public void GrabImage(string path)
{
IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
SendMessage(hWndC, WM_CAP_SAVEDIB, 0, hBmp.ToInt32());
}
/// <summary>
/// 录像
/// </summary>
/// <param name="path">要保存avi文件的路径</param>
public void Kinescope(string path)
{
IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
SendMessage(hWndC, WM_CAP_FILE_SET_CAPTURE_FILEA, 0, hBmp.ToInt32()); SendMessage(hWndC, WM_CAP_SEQUENCE, 0, 0);
}
/// <summary>
/// 停止录像
/// </summary>
public void StopKinescope()
{
SendMessage(hWndC, WM_CAP_STOP, 0, 0);
}
/// <summary>
///
/// </summary>
public void SetShow()
{
SendMessage(hWndC, WM_CAP_DLG_VIDEOSOURCE, 0, 0);
}
}
}
//把抓到的图像保存到硬盘
private void button3_Click(object sender, EventArgs e)
{
try
{
SaveFileDialog SaveFileDialog1=new SaveFileDialog();
SaveFileDialog1.Filter = "bmp files (*.bmp)|*.bmp|jpg files (*.jpg)|*.jpg|All files (*.*)|*.*";
SaveFileDialog1.FilterIndex = 2; //默认图片保存格式 JPG SaveFileDialog1.RestoreDirectory = true;
SaveFileDialog1.FileName = "Pic01"; //默认图片保存名称 Pic01
if (SaveFileDialog1.ShowDialog() == DialogResult.OK) {
pk.GrabImage(SaveFileDialog1.FileName);
}
}
catch
{
}
}