• 基于海康监控的图像识别设计


    基于海康监控的图像识别设计

     

    一、基本知识和背景

         目前,安防行业正从网络化向智能化升级;从简单的视频获取、图像截获向内容分析、自动跟踪进化。借助监控摄像头,进行图像识别或机器视觉设计的需求,变得越来越强烈。这里分享一些自己的研究。

         我选用海康监控,因为目前只能接触到这种监控,其他的品牌应该差不多。关键是思路。

         在这篇文章里面,实现1)控制监控摄像头获取图像2)用opencv进行简单处理3)获得量化数据一个过程。需要注意的一点是,我这里没有直接对视频流进行操作,因为目前我还没有这个需求。而是对截获的图片进行操作,进行处理,达到内容分析的目的。

     

    二、主要步骤

         ​1)获取并利用海康SDK,得到输入图像

            官网获得CH-HCNetSDK(Windows32)V4.3.0.6.zip,里面有文档和java/mfc/csharp的demo.基于我目前的需求,采用csharp编写图像获取界面,改写“1-实时预览示例代码一”相关内容。

         

           代码内容清晰完整,是标准的调用dll的模式。其中获取图片部分为

     


            private void btnJPEG_Click(object sender, EventArgs e)

            {
                string sJpegPicFileName;
                //图片保存路径和文件名 the path and file name to save
                sJpegPicFileName = "JPEG_test.jpg";
                int lChannel = Int16.Parse(textBoxChannel.Text); //通道号 Channel number
                CHCNetSDK.NET_DVR_JPEGPARA lpJpegPara = new CHCNetSDK.NET_DVR_JPEGPARA();
                lpJpegPara.wPicQuality = 0; //图像质量 Image quality
                lpJpegPara.wPicSize = 0xff; //抓图分辨率 Picture size: 2- 4CIF,0xff- Auto(使用当前码流分辨率),抓图分辨率需要设备支持,更多取值请参考SDK文档
                //JPEG抓图 Capture a JPEG picture
                if (!CHCNetSDK.NET_DVR_CaptureJPEGPicture(m_lUserID, lChannel, ref lpJpegPara, sJpegPicFileName))
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    str = "NET_DVR_CaptureJPEGPicture failed, error code= " + iLastErr;
                    MessageBox.Show(str);
                    return;
                }
                else
                {
                    str = "Successful to capture the JPEG file and the saved file is " + sJpegPicFileName;
                    MessageBox.Show(str);
                }
                return;
            }

       添加Timer事件,每5秒运行一次,自动获取图像,文件名为当前时间,并对原代码略作修改

     


        
      //将时间补足两位
            string timehelper(int iinput)
            {
                if (iinput<10)
                {
                    return "0" + iinput.ToString();
                }
                else
                {
                    return iinput.ToString();
                }
            }
            //auto jpeg
            private void timer1_Tick(object sender, EventArgs e)
            {
                string sJpegPicFileName;
                //图片保存路径和文件名 the path and file name to save
                sJpegPicFileName = "F:/test/" + DateTime.Now.ToShortDateString() + "_" + timehelper(DateTime.Now.Hour) + "_" + timehelper(DateTime.Now.Minute) + "_" + timehelper(DateTime.Now.Second) + ".jpg";
     
                int lChannel = Int16.Parse(textBoxChannel.Text); //通道号 Channel number
     
                CHCNetSDK.NET_DVR_JPEGPARA lpJpegPara = new CHCNetSDK.NET_DVR_JPEGPARA();
                lpJpegPara.wPicQuality = 0; //图像质量 Image quality
                lpJpegPara.wPicSize = 0xff; //抓图分辨率 Picture size: 2- 4CIF,0xff- Auto(使用当前码流分辨率),抓图分辨率需要设备支持,更多取值请参考SDK文档
     
                //JPEG抓图 Capture a JPEG picture
                if (!CHCNetSDK.NET_DVR_CaptureJPEGPicture(m_lUserID, lChannel, ref lpJpegPara, sJpegPicFileName))
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    str = "NET_DVR_CaptureJPEGPicture failed, error code= " + iLastErr;
           
                }
                else
                {
                    str = "Successful to capture the JPEG file and the saved file is " + sJpegPicFileName;
                }
            }
     
            private void button2_Click(object sender, EventArgs e)
            {
                string sJpegPicFileName = DateTime.Now.ToShortDateString() + "_" + DateTime.Now.Hour + "_" + DateTime.Now.Minute + "_" +DateTime.Now.Second + ".jpg";
     
            }
        }

     

     

       OK经过观察,没有出现内存溢出,可以使用。如果是多个监控一起使用的话可能会有新的问题,希望有相关经验的高手能够指导。

       如果是实际使用的话,还需要添加对图片进行相关的删除操作,保障硬盘不要溢出。

        2)编写opencv服务,对图像进行分析

         我是这样理解“服务”的。所谓服务,就是运行在后台,能够自动处理输入的数据,得到用户想要的结果的。如果监控要想能够“智能”起来,所获得的就不只是图片,而是包含图片相关内容的分析,是一个量化的过程。。

         这里就是简单地获取最新的图片,寻找轮廓数目,并且将其打印出来这样一个过程。


    // HelicopterStitching.cpp : 定义控制台应用程序的入口点。
    // 2015年1月22日20:29:38 jsxyhelu
    # include  "stdafx.h"
    # include  <cv.h >
    # include  <cxcore.h >
    # include  <highgui.h >
    # include  "opencv2/highgui/highgui.hpp"
    # include  "opencv2/imgproc/imgproc.hpp"                    
    # include  "Prehelper.h"
    # include  "GOFunction.h"
    # include  "LaplacianBlend.h"
     
    int _tmain( int argc, _TCHAR * argv[])
    {    
        vector <Mat > inputmat;
        vector <Mat > outputmat;
        vector <cv : :Point2f > points1;
        vector <cv : :Point2f > points2;
        vector <Point > locmat1;
        vector <Point > locmat2;
         int i;
         //读入参数
        FILE  *stream;
         int   numread, numwritten;
         //定义文件路径 
         char * cur_dir = "F:\\test";
         int iimagesize  = 0;
        Mat src;
        Mat src_gray;
        vector <pair < char *,Mat >> imgs;
        
        Mat  canny_output;
        vector <vector <Point >   >  contours;
        vector <Vec4i >  hierarchy;
         int thresh  = 50;
         while( true)
        {    
            imgs  = read_img(cur_dir);
             if (imgs.size() > 0)
            {
                src  = imgs[imgs.size() - 1].second; //获得最新的图片
                imshow( "src",src);    
                cvtColor(src,src_gray,CV_RGB2GRAY);
                Canny(  src_gray,  canny_output,  thresh,  thresh * 2,   3  );
                 ///  Find  contours
                findContours(  canny_output,  contours,  hierarchy,  CV_RETR_TREE,  CV_CHAIN_APPROX_SIMPLE,  Point( 0,   0)  );
                imshow( "canny_output",canny_output);
                printf(     "找到轮廓%d个\n",contours.size());
            }
        
            cv : :waitKey( 3000); //等待3秒
        }
        
        cv : :waitKey();
         return  0;
    }

    三、小结反思

         这样一个项目,原理并不复杂。其鲁棒性如何,在高并发的情况下是否会出现新的问题,都需要进一步验证。但是的确是一种引入监控图像的方法,并且得到了“智能分析”的结果。

         感谢阅读到此,希望有经验者能够提出宝贵意见,希望对你有所帮助。



  • 相关阅读:
    linux查看安装文件
    mysql 查询表结构
    linux回退到上次访问目录
    正则表达式匹配所有字符包括换行符
    Spring配置文件中使用表达式
    Ext 修改Store初始化加载完后修改record属性。
    数据库锁
    C#中的多线程使用 -- Thread 类详解(转)
    div背景等比例缩小
    div添加透明边框透明背景css
  • 原文地址:https://www.cnblogs.com/jsxyhelu/p/16948137.html
Copyright © 2020-2023  润新知