图像采集---摄像头取像程序

要入门AI,不就是眼和耳吗?所以你需要打通关键的声音采集,和图像采集。特别是编程,他的重要性不言而喻。虽然这都是玩一玩,在微软支撑下,简单,过气,但是他激发的探索和兴致(求知欲)从来不会过时,这会让你打开更加专业的basler相机,灰点(grey)相机图像采集(针对机器视觉)的大门,如果你不会对眼和耳采集的花花世界感兴趣,怎么会对算法和意识感兴趣呢?

请看整理的c#摄像头取像程序:我们给他起了一个名字叫usbcamscale(usb摄像头缩放),这里只表述图像采集代码:

第一,声明: WebCamera wc = null;
          public ShowVideo.CAPDRIVERCAPS capDriverCaps;
        public ShowVideo.CAPSTATUS capStatus;
        public ShowVideo.CAPTUREPARMS captureparms;

第二,初始化:  capDriverCaps = new ShowVideo.CAPDRIVERCAPS();
            capStatus = new ShowVideo.CAPSTATUS();
            captureparms = new ShowVideo.CAPTUREPARMS();

第三,取像:

  wc = new WebCamera(pictureBox1.Handle, pictureBox1.Width, pictureBox1.Height);//
            wc.StartWebCam();

            if (!wc.capDriverConnect(wc.IwndC, 0))
            {
                return;
            }
            ShowVideo.SendMessage(wc.IwndC, ShowVideo.WM_CAP_DRIVER_GET_CAPS, ShowVideo.SizeOf(capDriverCaps), ref capDriverCaps);

            if (capDriverCaps.fCaptureInitialized)
            {
                wc.capPreviewRate(wc.IwndC, 25);
                wc.capPreview(wc.IwndC, true);//没有显示,被设置。要显示设置为WS_VISIBLE(向后看)。
            }

ok,取像成功。好,这是微软给我们的便利,我们瞪大眼睛只能看着,那么如何取出一幅像呢?继续:

            int mod = wc.mWidth % 4;//这是vfw模式(opencv1.0也是如此)的,在win8.1上测试通过,win10你可以想办法去通关
            glob_buffer32 = new byte[640 * 480*4];//vfw模式,只能取出640*480的pixels,win8.1可以运行800*600的摄像头
            glob_buffer8 = new byte[640 * 480 ];//但是取出来的仍然是640*480,所以你又需要开动脑筋通关
            glob_buffer8G = new byte[640 * 480];
            glob_buffer8B = new byte[640 * 480];
            timer1.Start();

第四,取出一幅像:

 Bitmap  glob_curBitmap=null;
      Bitmap transBmp = null;
        private void timer1_Tick(object sender, EventArgs e)
        {
                      
            if (ShowVideo.SendMessage(wc.IwndC, ShowVideo.WM_CAP_SINGLE_FRAME_OPEN, 0, 0))
            {
                if (ShowVideo.SendMessage(wc.IwndC, ShowVideo.WM_CAP_SINGLE_FRAME, 0, 0))
                {
                    if (ShowVideo.SendMessage(wc.IwndC, ShowVideo.WM_CAP_SINGLE_FRAME_CLOSE, 0, 0))
                    {
                     

                        ShowVideo.SendMessage(wc.IwndC, ShowVideo.WM_CAP_EDIT_COPY, 0, 0);
                        IDataObject iData = Clipboard.GetDataObject();
                        iData.GetDataPresent(DataFormats.Bitmap);
                     
                        transBmp = (Bitmap)iData.GetData(DataFormats.Bitmap);
                       this.pictureBox1.Image = (Bitmap)iData.GetData(DataFormats.Bitmap);//这里显示彩色图像
                        Clipboard.Clear();
                
                        glob_curBitmap = (Bitmap)transBmp.Clone();
                   

                    }
                }
            }
            int ww=640;
            int hh=480;
            BitmapData _cutPic = glob_curBitmap.LockBits(new Rectangle(0, 0, ww, hh),//PixelFormat.Format32bppArgb
                  ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);//glob_curBitmap.
            IntPtr ptr = _cutPic.Scan0;//得到首地址
            //把cutvalues数组给ptr
      
            Marshal.Copy(ptr, glob_buffer32, 0, 640*480* 4);
            glob_curBitmap.UnlockBits(_cutPic);
        
            for (int j = 0; j < 640; j++)
            {
                for (int i = 0; i < 480; i++)
                {
                    int nn = j * 480 + i;
                    glob_buffer8[nn] = glob_buffer32[nn * 4+0];//这里已经取出了RGB图像放在r,g,b数组(byte【】)中
                    glob_buffer8G[nn] = glob_buffer32[nn * 4 + 1];//你需要想办法写入bitmap,并显示
                    glob_buffer8B[nn] = glob_buffer32[nn * 4 + 2];//这里的buffer8B里头存的是红色分量,发现没有?
                }
            }
            drawload2scale(640, 480, glob_buffer8, pictureBox2);//这里显示的是灰度图像,用来可以图像处理了

}//我们把蓝色分量b数组作为灰度图像是不妥的,应该是红色0.3,绿色0.59,蓝色0.11

剩下的,就是来解释前面的关键类:第一个

  class WebCamera
    {
       
            public delegate void RecievedFrameEventHandler(byte[] data);
            public event RecievedFrameEventHandler RecievedFrame;
            public IntPtr IwndC;
            public IntPtr mControlPtr;
            public int mWidth;
            public int mHeight;
            public ShowVideo.FrameEventHandler mFrameEventHandler;
            public void FrameCallBack(IntPtr Iwnd, IntPtr lpVHdr)
            {
                ShowVideo.VIDEOHDR videoHeader = new ShowVideo.VIDEOHDR();
                byte[] VideoData;
                videoHeader = (ShowVideo.VIDEOHDR)ShowVideo.GetStructure(lpVHdr, videoHeader);
                VideoData=new byte[videoHeader.dwBytesUsed];
                ShowVideo.Copy(videoHeader.lpData, VideoData);
                if (this.RecievedFrame != null)
                {
                    this.RecievedFrame(VideoData);
                }
            }
            public WebCamera(IntPtr handle, int width, int height)
            {
                mControlPtr = handle;
                mWidth = width;
                mHeight = height;
            }
            public void StartWebCam()        
            {
                byte[] abc = new byte[32];
                abc[0] = (byte)'u';
                abc[1] = (byte)'s';
                abc[2] = (byte)'b';
                abc[3] = (byte)'C';
                abc[4] = (byte)'a';
                abc[5] = (byte)'m';

                for (int i = 6; i < 32; i++)
                {
                    abc[i] = (byte)'0';
                }


               // IwndC = ShowVideo.capCreateCaptureWindowA(abc, ShowVideo.WS_CHILD | ShowVideo.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);//要显示图像,使用此行代码
                //WS_DISABLED
                IwndC = ShowVideo.capCreateCaptureWindowA(abc, ShowVideo.WS_CHILD | ShowVideo.WS_DISABLED, 0, 0, mWidth, mHeight, mControlPtr, 0);//注意,这里被设置为不显示
            }
            public void CloseCamera()
            {
                this.capDriverDisconnect(this.IwndC);
            }
            public bool capDriverConnect(IntPtr Iwnd, short i)
            {
                return ShowVideo.SendMessage(Iwnd, ShowVideo.WM_CAP_DRIVER_CONNECT, i, 0);
            }
            public bool capDriverDisconnect(IntPtr Iwnd)
            {
                return ShowVideo.SendMessage(Iwnd, ShowVideo.WM_CAP_DRIVER_DISCONNECT, 0, 0);
            }
            public bool capPreview(IntPtr Iwnd, bool f)
            {
                return ShowVideo.SendMessage(Iwnd, ShowVideo.WM_CAP_SET_PREVIEW, f, 0);
            }
            public bool capPreviewRate(IntPtr Iwnd, short wMS)
            {
                return ShowVideo.SendMessage(Iwnd, ShowVideo.WM_CAP_SET_PREVIEWRATE, wMS, 0);
            }
            public bool capSetVideoFormat(IntPtr hWnd, ref ShowVideo.BITMAPINFO bitmapinfo, int size)
            {
                //return ShowVideo.capGetVideoFormat(hWnd, bitmapinfo, size);
                return ShowVideo.SendMessage(hWnd, ShowVideo.WM_CAP_SET_VIDEOFORMAT, size, ref bitmapinfo);
            }
            public bool capSetCallbackOnFrame(IntPtr IWnd, ShowVideo.FrameEventHandler lpProc)
            {
                return ShowVideo.SendMessage(IWnd, ShowVideo.WM_CAP_SET_CALLBACK_FRAME, 0, lpProc);
            }
            public void StartCamera()
            {
                byte[] lpszName = new byte[100];
                byte[] lpszVer = new byte[100];

                this.IwndC = ShowVideo.capCreateCaptureWindowA(lpszName, ShowVideo.WS_VISIBLE + ShowVideo.WS_CHILD,
                    0, 0, mWidth, mHeight, mControlPtr, 0);
            }
            public void caprecord(IntPtr Iwnd, string path)
            {
                IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
                ShowVideo.SendMessage(Iwnd, ShowVideo.WM_CAP_FILE_SET_CAPTURE_FILEA, 0, hBmp.ToInt32());
                ShowVideo.SendMessage(Iwnd, ShowVideo.WM_CAP_SEQUENCE, 0, 0);
            }
            public void caprecordstop(IntPtr Iwnd)
            {
                ShowVideo.SendMessage(Iwnd, ShowVideo.WM_CAP_STOP, 0, 0);
            }
            public void capsnapimage(IntPtr Iwnd, string path)
            {
                ShowVideo.BITMAPINFO bmpinfo = new ShowVideo.BITMAPINFO();
                IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
                ShowVideo.SendMessage(Iwnd, ShowVideo.WM_CAP_SAVEDIB, 0, hBmp.ToInt32());
            }
        
    }///////////////////////////////////////////////////////////////////

第二个:注意这是一个form类,你需要创建一个form窗口

 public partial class ShowVideo : Form
    {
        public const int WS_CHILD = 0x40000000;
        public const int WS_VISIBLE = 0x10000000;
        public const int WS_DISABLED=0x08000000;
        public const int WM_USER = 1024;
        public const int WM_CAP_START = WM_USER;
        public const int WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
        public const int WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
        public const int WM_CAP_SET_PREVIEW = WM_CAP_START + 50;
        public const int WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52;
        public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + 45;
        public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + 5;
        public const int WM_CAP_FILE_SET_CAPTURE_FILEA = WM_USER + 20;
        public const int WM_CAP_SEQUENCE=WM_USER +62;
        public const int WM_CAP_SAVEDIB = WM_USER + 25;
        public const int WM_CAP_STOP = WM_USER + 68;
        public const int WM_CAP_GET_SEQUENCE_SETUP=WM_USER+65;
        public const int WM_CAP_DRIVER_GET_CAPS=WM_USER+14;
        public const int WM_CAP_DRIVER_GET_STATUS = WM_USER + 54;

        public delegate void FrameEventHandler(IntPtr Iwnd, IntPtr lpVHdr);
        public static object GetStructure(IntPtr ptr, ValueType structure)
        {
            return Marshal.PtrToStructure(ptr, structure.GetType());
        }
        public static object GetStructure(int ptr, ValueType structure)
        {
            return GetStructure(new IntPtr(ptr), structure);
        }
        public static void Copy(IntPtr ptr, byte[] data)
        {
            Marshal.Copy(ptr, data, 0, data.Length);
        }
        public static void Copy(int ptr, byte[] data)
        {
            Copy(new IntPtr(ptr), data);
        }

        public static int SizeOf(object structer)
        {
            unsafe
            {
                return Marshal.SizeOf(structer);
            }
        }

        [DllImport("avicap32.dll")]
        public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y,
            int nwidth, int nheight, IntPtr hWndParent, int nID);

        [DllImport("User32.dll")]
        public static extern bool SendMessage(IntPtr hWnd, int wMsg, short WParam, int LParam);
        [DllImport("User32.dll")]
        public static extern bool SendMessage(IntPtr hWnd, int wMsg, bool WParam, int LParam);
        [DllImport("User32.dll")]
        public static extern bool SendMessage(IntPtr hWnd,int wMsg,short WParam,FrameEventHandler LParam);
        [DllImport("User32.dll")]
        public static extern bool SendMessage(IntPtr hWnd, int wMsg, int WParam, ref BITMAPINFO LParam);
        [DllImport("User32.dll")]
        public static extern bool SendMessage(IntPtr hWnd, int wMsg, int WParam, ref CAPDRIVERCAPS LParam);
        [DllImport("User32.dll")]
        public static extern bool SendMessage(IntPtr hWnd, int wMsg, int WParam, ref CAPTUREPARMS LParam);
        [DllImport("User32.dll")]
        public static extern bool SendMessage(IntPtr hWnd, int wMsg, int WParam, ref CAPSTATUS LParam);

        [DllImport("User32.dll")]
        public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
        [DllImport("User32.dll")]
        public static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize);

        public const int WM_CAP_SINGLE_FRAME_OPEN = WM_USER + 70;
        public const int WM_CAP_SINGLE_FRAME_CLOSE = WM_USER + 71;
        public const int WM_CAP_SINGLE_FRAME=WM_USER+72;
        public const int WM_CAP_EDIT_COPY = (WM_USER + 30);

        //[DllImport("User32.dll")]
        //public static extern bool EmptyClipboard();
        //[DllImport("User32.dll")]
        //public static extern bool CloseClipboard();
        //[DllImport("User32.dll")]
        //public static extern bool OpenClipboard(IntPtr hWnd);
        //[DllImport("User32.dll")]
        //public static extern bool IsClipboardFormatAvailable(uint format);
        //[DllImport("User32.dll")]
        //public static extern IntPtr GetClipboardData(uint uFormat);
        //[DllImport("User32.dll")]
        //public static extern IntPtr GlobalLock(IntPtr handle);
        //[DllImport("User32.dll")]
        //public static extern bool GlobalUnlock(IntPtr handle);
        //[DllImport("User32.dll")]
        //public static extern bool CloseClipboard();

        [StructLayout(LayoutKind.Sequential)]
        public struct VIDEOHDR
        {
            [MarshalAs(UnmanagedType.I4)]
            public int lpData;
            [MarshalAs(UnmanagedType.I4)]
            public int dwBufferLength;
            [MarshalAs(UnmanagedType.I4)]
            public int dwBytesUsed;
            [MarshalAs(UnmanagedType.I4)]
            public int dwTimeCaptured;
            [MarshalAs(UnmanagedType.I4)]
            public int dwUser;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public int[] dwReserved;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct BITMAPINFOHEADER
        {
            [MarshalAs(UnmanagedType.I4)]
            public Int32 biSize;
            [MarshalAs(UnmanagedType.I4)]
            public Int32 biWidth;
            [MarshalAs(UnmanagedType.I4)]
            public Int32 biHeight;
            [MarshalAs(UnmanagedType.I2)]
            public short biPlanes;
            [MarshalAs(UnmanagedType.I2)]
            public short biBitCount;
            [MarshalAs(UnmanagedType.I4)]
            public int biCompression;
            [MarshalAs(UnmanagedType.I4)]
            public int biSizeImage;
            [MarshalAs(UnmanagedType.I4)]
            public int biXpelsPerMeter;
            [MarshalAs(UnmanagedType.I4)]
            public int biYPelsPerMeter;
            [MarshalAs(UnmanagedType.I4)]
            public int biClrUsed;
            [MarshalAs(UnmanagedType.I4)]
            public int biClrImportant;

        }
        [StructLayout(LayoutKind.Sequential)]
        public struct BITMAPINFO
        {
            [MarshalAs(UnmanagedType.Struct, SizeConst = 100)]
            public BITMAPINFOHEADER bmiHeader;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
            public int[] bmiColors;

        }
        [StructLayout(LayoutKind.Sequential)]
        public struct CAPDRIVERCAPS
        {
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 wDeviceIndex;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fHasOverlay;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fHasDlgVideoSource;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fHasVideoFormat;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fHasDlgVideoDisplay;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fCaptureInitialized;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fDriverSuppliesPalettes;
            [MarshalAs(UnmanagedType.I4)]
            public int hVideoIn;
            [MarshalAs(UnmanagedType.I4)]
            public int hVideoOut;
            [MarshalAs(UnmanagedType.I4)]
            public int hVideoExtIn;
            [MarshalAs(UnmanagedType.I4)]
            public int hVideoExtOut;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct CAPTUREPARMS
        {
            public int dwRequestMicroSecPerFrame;//默认15秒每帧
            public bool fMakeUserHitOkToCapture;//开始捕获标志
            public uint wPercentDropForError;//丢帧默认10
            public bool fYield;//另起线程标志
            public int dwIndexSize;
            public uint wChunkGranularity;
            public bool fUsingDOSMemory;
            public uint wNumVideoRequested;//分配最大视频缓存
            public bool fCaptureAudio;
            public uint wNumAudioRequested;//最大数量音频缓存
            public uint vKeyAbort;//终止流捕获的虚拟键盘吗
            [MarshalAs(UnmanagedType.Bool)]
            public bool fAbortLeftMouse;
            public bool fAbortRightMouse;
            public bool fLimitEnabled;//捕获操作时间限制
            public uint wTimeLimit;//具体终止时间
            public bool fMCIControl;
            public bool fStepMCIDevicd;
            public int dwMCIStartTime;
            public int dwMCIStopTime;
            public bool fStepCaptureAt2x;
            public int wStepCaptureAverageFrames;
            public int dwAudioBufferSize;//0.5s或10k字节
            public int fDisableWriteCache;
            public int AVStreamMaster;//音频同步标志
            
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct CAPSTATUS
        {
            public int uiImageWidth;
            public int uiImageHeight;
            public bool fOverlayWindow;
            public bool fLiveWindow;
            public bool fScale;
            public Point ptScroll;
            public bool fUsingDefaultPalette;
            public bool fAudioHardware;
            public bool fCapFileExists;
            public int dwCurrentVideoFrame;
            public int dwCurrentVideoFramesDropped;
            public int dwCurrentWaveSamples;
            public int dwCurrentTimeElapsedMS;
            public IntPtr hPalCurrent;
            public int  dwReturn;
            public bool fCapturingNow;
            public int wNumVideoAllocated;
            public int wNumAudioAllocated;
        }
        public ShowVideo()
        {
            InitializeComponent();
        }
    }

网络真是个学习的好地方,有很多的大咖需要谢谢,但更应该感谢微软!如果有想要看vc++版本的摄像头图像采集程序,请留言,或许,有对比,才能更好的学习进步,不要以为我放弃vc++了,那可是我的初心!(vc++都能搞定,C#都不是事,虽然没人教过)

待续(慢慢来!...........)每天一点小改变☺

我的邮箱[email protected];[email protected]

发布了66 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ganggangwawa/article/details/102540998
今日推荐