简单使用gige千兆网口工业相机,国产崛起(二,c#)

news/2024/4/19 7:46:56/文章来源:https://blog.csdn.net/ganggangwawa/article/details/127629342

发现海康的sdk不错,可以用海康,basler,大华工业相机,估计其他的也可以,有机会试一试!国产厉害,崛起了!赞一个,热情爆棚!且随窃喜!

首先下载海康工业相机的安装包,并安装,安装后如图,打开:

他的开发包和范例安装包路径如下:

参考里边的可以写你想要的程序,当然是打开相机取像了,我使用的是他的bmp位图方式(你懂的,存图是z字序的),图像是反的,我给颠倒过来了:(这是黑白相机c#范例,后续还有彩色相机的)

第一,初始化:果断注释掉以前basler的,只留海康

     #region haikangcam
            // ch:枚举设备 | en:Enum device
            if (nDevIndex == -1) { MessageBox.Show("请选择相机"); return; }
            MyCamera.MV_CC_DEVICE_INFO_LIST stDevList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
            nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE, ref stDevList);//| MyCamera.MV_USB_DEVICE
            MyCamera.MV_CC_DEVICE_INFO stDevInfo;
            for (Int32 i = 0; i < stDevList.nDeviceNum; i++)
            {
                stDevInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));

                if (MyCamera.MV_GIGE_DEVICE == stDevInfo.nTLayerType)
                {
                    MyCamera.MV_GIGE_DEVICE_INFO stGigEDeviceInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(stDevInfo.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
                
                   string str= stGigEDeviceInfo.chModelName;              
                   bool youwu00 = str.Contains("gc");//彩色判断
                   bool youwu01 = str.Contains("gC");
                   bool youwu10 = str.Contains("Gc");
                   bool youwu11 = str.Contains("GC");
                   if (youwu00 || youwu01 || youwu10 || youwu11) { checkBoxBW.Checked = false; } else { checkBoxBW.Checked = true; }
                }
              
                stDevInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[nDevIndex], typeof(MyCamera.MV_CC_DEVICE_INFO));
                // ch:创建设备 | en:Create device
                nRet = device.MV_CC_CreateDevice_NET(ref stDevInfo);
                // ch:打开设备 | en:Open device
                nRet = device.MV_CC_OpenDevice_NET();
                // ch:设置触发模式为off || en:set trigger mode as off
                if (MyCamera.MV_OK != device.MV_CC_SetEnumValue_NET("TriggerMode", 0))
                {
                  //控制台的,没用,删掉
                }
                device.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
                float value = (float)(Convert.ToDouble(textBox3.Text));//改为880000
                int hello = device.MV_CC_SetExposureTime_NET(value);//感觉有效果202208060942
                // ch:开启抓图 | en:start grab
                nRet = device.MV_CC_StartGrabbing_NET();
                if (MyCamera.MV_OK != nRet)
                {
                 
                }

                // ch:获取包大小 || en: Get Payload Size
                MyCamera.MVCC_INTVALUE stParam = new MyCamera.MVCC_INTVALUE();
                nRet = device.MV_CC_GetIntValue_NET("PayloadSize", ref stParam);
                if (MyCamera.MV_OK != nRet)
                {
                   
                }
                nPayloadSize = stParam.nCurValue;
                pBufForDriver = Marshal.AllocHGlobal((int)nPayloadSize);
            }
            #endregion haikangcam

 第二,上面第一句执行不了,返回了,所以问题在这里:

a,引用,using MvCamCtrl.NET;

b,声明变量, //ishaikang20211230
        MyCamera device = new MyCamera();
        int nRet = MyCamera.MV_OK;
        MyCamera.MVCC_INTVALUE stParam;
        UInt32 nPayloadSize;
        // int nCount = 0;
        IntPtr pBufForDriver;
        IntPtr pBufForSaveImage = IntPtr.Zero;
        MyCamera.MV_FRAME_OUT_INFO_EX FrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();

c,枚举相机,添加到combox:

  //列举相机个数
            //  int nRet = MyCamera.MV_OK;
            //   MyCamera device = new MyCamera();

            // ch:枚举设备 | en:Enum device
            MyCamera.MV_CC_DEVICE_INFO_LIST stDevList1 = new MyCamera.MV_CC_DEVICE_INFO_LIST();
            do
            {

                int tempint = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref stDevList1);
                if (MyCamera.MV_OK != tempint)
                {
                  
                    break;
                }
             
                textBoxcamno.Text = stDevList1.nDeviceNum.ToString();
                if (0 == stDevList1.nDeviceNum)
                {
                    break;
                }


            } while (false);

            MyCamera.MV_CC_DEVICE_INFO stDevInfo;
            for (Int32 i = 0; i < stDevList1.nDeviceNum; i++)
            {
                stDevInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(stDevList1.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));

                if (MyCamera.MV_GIGE_DEVICE == stDevInfo.nTLayerType)
                {
                    MyCamera.MV_GIGE_DEVICE_INFO stGigEDeviceInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(stDevInfo.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));                

                    comboBoxCamSel.Items.Add(i.ToString());// + //":" + stGigEDeviceInfo.chSerialNumber +":"+ stGigEDeviceInfo.chModelName.ToString()+ 
                                                           //"\r\n";

                }
            }

第三,万事具备,取像,连续取像,开一个timer,启动:

 int ww = Convert.ToInt32(inputW.Text);//无论是2千万,还是200万,我只去1024*768
            int hh = Convert.ToInt32(inputH.Text);//无论是2千万,还是200万,我只去1024*768
            nRet = device.MV_CC_GetOneFrameTimeout_NET(pBufForDriver, nPayloadSize, ref FrameInfo, 1000);

第四,ok,完了,但要显示出来,并且把数据放入二维数组,需要花费功夫(这里先处理黑白相机,默认8位):

   if (pBufForSaveImage == IntPtr.Zero)
                    {
                        pBufForSaveImage = Marshal.AllocHGlobal((int)(FrameInfo.nHeight * FrameInfo.nWidth * 3 + 2048));
                    }
                    MyCamera.MV_SAVE_IMAGE_PARAM_EX stSaveParam = new MyCamera.MV_SAVE_IMAGE_PARAM_EX();
                    stSaveParam.enImageType = MyCamera.MV_SAVE_IAMGE_TYPE.MV_Image_Bmp;
                    stSaveParam.enPixelType = FrameInfo.enPixelType;
                    stSaveParam.pData = pBufForDriver;
                    stSaveParam.nDataLen = FrameInfo.nFrameLen;
                    stSaveParam.nHeight = FrameInfo.nHeight;
                    stSaveParam.nWidth = FrameInfo.nWidth;
                    stSaveParam.pImageBuffer = pBufForSaveImage;
                    stSaveParam.nBufferSize = (uint)(FrameInfo.nHeight * FrameInfo.nWidth * 3 + 2048);
                    stSaveParam.nJpgQuality = 80;
                    nRet = device.MV_CC_SaveImageEx_NET(ref stSaveParam);

                    byte[] data = new byte[stSaveParam.nImageLen];
                    Marshal.Copy(pBufForSaveImage, data, 0, (int)stSaveParam.nImageLen);

 //以下是针对黑白相机的//这个黑白相机程序也是ok的,但与彩色相机程序有差别//20220427
                         byte[] tempdata2 = new byte[FrameInfo.nHeight * FrameInfo.nWidth];
                         for (int i = 0 + 1078; i < FrameInfo.nHeight * FrameInfo.nWidth + 1078; i++)
                         {

                             tempdata2[i - 1078] = data[i];

                         }
                         byte[] data2 = new byte[FrameInfo.nHeight * FrameInfo.nWidth];
                         for(int i=0;i<FrameInfo.nHeight;i++)
                             for (int j = 0; j <FrameInfo.nWidth ; j++)
                             {
                                 data2[i  *FrameInfo.nWidth + j] = tempdata2[(FrameInfo.nHeight - 1 - i) * FrameInfo.nWidth + j];
                             }
                     
                         int bytes = ww * hh * 3;
                         byte[] bufercopy = new byte[bytes];
                         Bitmap cutPic24 = new Bitmap(ww, hh,
                             System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                         BitmapData _cutPic = cutPic24.LockBits(new Rectangle(0, 0, ww, hh),
                             ImageLockMode.ReadWrite, cutPic24.PixelFormat);
                         IntPtr ptr = _cutPic.Scan0;//得到首地址                   

                         int yy = (FrameInfo.nHeight - hh) / 2;//FrameInfo.nHeight
                         int xx = (FrameInfo.nWidth - ww) / 2;// FrameInfo.nWidth
                         for (int ii = yy; ii < yy + hh; ii++)//图像复原,即由8位图变成24位图像
                         {
                             for (int j = xx; j < xx + ww; j++)
                             {//位图z序颠倒后,正常
                                 int n = ii * FrameInfo.nWidth + j;
                                 int k = (ii - yy) * ww + j - xx;
                                 int m = 3 * k;
                                 glob_buffer8[k] = checkBoxConvertBW.Checked ? (byte)(255 - data2[n]) : data2[n];//为什么可以,可以验证,可以分析202209231111
                               
                                 bufercopy[m] =  data2[n];
                                 bufercopy[m + 1] = data2[n];
                                 bufercopy[m + 2] = data2[n];
                              
                             }
                         }

   showbuffer2pict(data2, FrameInfo.nWidth, FrameInfo.nHeight, pictureBoxrgb);

第五,解释showbuffer2pict函数:(主要针对黑白8为图像显示)

   void showbuffer2pict(byte[] buffer, int ww, int hh,PictureBox destImg)
        {
          //  destImg.Size = new System.Drawing.Size(ww, hh);
            //顯示
            byte[] cutvalues = new byte[ww * hh * 3];
            int bytes = ww * hh * 3;
            Bitmap cutPic24 = new Bitmap(ww, hh, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            BitmapData _cutPic = cutPic24.LockBits(new Rectangle(0, 0, ww, hh), ImageLockMode.ReadWrite,
                                                 cutPic24.PixelFormat);

            IntPtr ptr = _cutPic.Scan0;//得到首地址

            for (int i = 0; i < hh; i++)
            {
                for (int j = 0; j < ww; j++)
                {
                    int n = i * ww + j;
                    int m = 3 * n;
                    cutvalues[m] = buffer[n];
                    cutvalues[m + 1] = buffer[n];
                    cutvalues[m + 2] = buffer[n];

                }
            }
            System.Runtime.InteropServices.Marshal.Copy(cutvalues, 0, ptr, bytes);
            cutPic24.UnlockBits(_cutPic);
            destImg.Image = cutPic24;
        }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_410315.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站SEO标题撰写技巧,做到这些可以提高点击率

搜索引擎认为&#xff0c;一个网站的点击率越高&#xff0c;那么这个网站就越受欢迎&#xff0c;因此就会提高网站的关键词排名。网站的点击率越高&#xff0c;就会获得更多流量。网站标题和点击率息息相关&#xff0c;一个好的网站标题&#xff0c;能够轻松获得流量。那么&…

[carla入门教程]-2 pythonAPI的使用

本专栏教程将记录我从安装carla到调用carla的pythonAPI进行车辆操控的全流程,带领大家从安装carla开始,到最终能够熟练使用carla仿真环境进行传感器数据采集和车辆控制. 第二节 pythonAPI的使用 本小节主要学习使用 pythonAPI来与carla服务器进行交互.包括获取信息,发送信息.…

IDEA热部署插件JRebel使用

JRebel安装与激活 JRebel 使用 此时已经安装好并已激活&#xff0c;我们使用 JRebel debug的时候&#xff0c;修改代码&#xff0c;不能实现热部署&#xff0c;因此还需要设置其他地方 1.项目自动编译 设置 compiler.automake.allow.when.app.running ctrlshiftA 或者 help->…

vue相关原理

vue 原理 面试为什么要考察原理 知其然知其所以然&#xff0c;各行各业通用的道理了解原理才能用的很好&#xff0c;专业性考察&#xff0c;技术的追求竞争激烈&#xff0c;则优录取大厂造轮子&#xff08;业务定制&#xff1a;有些框架不能满足需求&#xff09; 面试中如何…

【Spark NLP】第 19 章:生产化 NLP 应用程序

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

docker下快速部署openldap与PHPLdapAdmin

在一个组织中&#xff0c;为了简化各种内部系统的账号和密码的管理&#xff0c;往往就需要ldap来进行管理了。 对于ldap的实现方式也非常多&#xff0c;但在免费的开源系统中&#xff0c;openldap是ldap的首选系统。 同时&#xff0c;在这一切讲究快速的时代&#xff0c;采用d…

大数据ClickHouse进阶(二十二):ClickHouse优化

文章目录 ClickHouse优化 一、表优化 1、日期字段避免使用String存储 2、Nullable值处理 <

计算机毕业设计(附源码)python音蕾心动

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

云IDE的简单使用、体验与学习

云IDE的简单使用、体验与学习一、简单尝试二、官网展示的特点三、视频用例3.1、用Cloud IDE快速启动开源项目3.2、用Cloud IDE 在线提交PR云IDE产品介绍 云IDE使用教程 免费使用地址&#xff1a;点击【云IDE】&#xff0c;即可开始创建工作空间。 一、简单尝试 快速创建工作空…

学习用Python实现PPT的自动化

前言 在日常工作中&#xff0c;我们总是需要创建或修改PPT。但你也可以用Python来创建或修改PPT文件。本文将告诉你如何使用Python-pptx模块自动或用PPT模板生成ppt&#xff0c;以及如何通过实例修改现有的PPT。 &#xff08;文末送福利&#xff09; 1.Python模块python-ppt…

hbuilderx ios自定义基座真机测试

任务描述&#xff1a; 用uniapp框架写了一个app应用&#xff0c;需要在ios苹果手机上真机运行测试。 hbuilderx不再支持标准基座真机运行了&#xff0c;需要自定义基座运行 制定自定义基座需要准备的材料&#xff1a; ios的appid,profile文件&#xff0c;私钥证书&#xff0…

动视是否磨灭了暴雪的灵魂?

对于成千上万的人&#xff0c;也许是数百万人来说&#xff0c;暴雪是——或者曾经是——一家特殊的公司。 暴雪——游戏开发的典范 对于奇幻世界的关注&#xff0c;暴雪是无与伦比的。如果游戏没有准备好&#xff0c;它就不会发布。1998 年&#xff0c;尽管《魔兽争霸&#xf…

算法复杂度分析

复杂度分析 参考&#xff1a;《算法导论》、复杂度 - OI Wiki (oi-wiki.org)、一文弄懂算法的时间和空间复杂度分析 - 知乎 (zhihu.com)、算法讲解之复杂度分析 - 知乎 (zhihu.com)、算法的时间复杂度和空间复杂度-总结_zolalad的博客-CSDN博客_时间复杂度 算法复杂度分析的阶段…

梦开始的地方 —— C语言数据在内存中的存储(整形+浮点型)

文章目录整形在内存中的存储1. 数值类型的基本分类2. 整形在内存中的存储1. 原码、反码、补码2. 内存中为什么要存放补码&#xff1f;3. 大小端存储4. 无符号有符号数练习5. 有符号数无符号数小结浮点型在内存中的存储IEEE 754整形在内存中的存储 1. 数值类型的基本分类 整形…

AJAX基础+Axios快速入门+JSON使用+综合案例

目录1、 AJAX1.1 概述1.1.1 作用1.1.2 同步和异步1.2 快速入门1.2.1 服务端实现1.2.2 客户端实现1.3 案例1.3.1 需求1.3.2 分析1.3.2 后端实现1.3.3 前端实现2、 Axios异步框架2.1 基本使用2.2 快速入门2.2.1 后端实现2.2.2 前端实现2.3 请求方法别名3、 JSON3.1 概述3.2 JSON基…

GAS技能系统

HUT -》 在\Intermediate\Build\Win64\UE4Editor\Inc\的目录下 找到generated 头文件和cpp文件 里面有HUT根据UCLASS 和 Generate Body 生成的 定义 以及声明宏(UFUNCTION 里的CustomThunk元可以让用户自己手动添加宏定义和宏声明) 将wildcard改为通配符然后手动将自定义的…

Terraform 华为云实践 项目初始化

这个架构就是DNS加上负载均衡加ecs&#xff0c;最后vpc的架构。网络这块是DNS和VPC&#xff0c;对象存储是用来做terraform的后端来配置。 项目的初始化 Terraform Registry 华为云的terraform链接如上所示。 先将项目的目录结构建好&#xff0c;modules是我们的模块&#xf…

来一场关于元宇宙的灵魂辩论|BOOK DAO内容共建招募

「 备选问题 」1. 你认为元宇宙最重要的特点是什么&#xff1f;用一句话描述你理解的 “元宇宙”2. 元宇宙是游戏2.0吗&#xff1f;它与游戏有什么不同&#xff1f;3. 元宇宙是否需要区块链&#xff1f;是否需要NFT&#xff1f;各扮演什么角色&#xff1f;4. 元宇宙是否需要经济…

大数据项目之电商数仓、电商业务简介、电商业务流程、电商常识、业务数据介绍、电商业务表、后台管理系统

文章目录5. 电商业务简介5.1 电商业务流程5.2 电商常识5.2.1 SKU和SPU5.2.2 平台属性和销售属性5.2.2.1 平台属性5.2.2.2 销售属性6. 业务数据介绍6.2 电商业务表6.2.1 收藏商品6.2.2 加购物车6.2.3 领用优惠券6.2.4 下单6.2.5 支付6.2.6 退单6.2.7 退款6.2.8 评价6.3 后台管理…

部署简易POD image自己定义镜像

k8s部署pod apiversion: 版本 kind: 类型 metadata: 字面意识&#xff0c;元素信息&#xff0c;POD信息 name: POD名字 labels: 字母意识&#xff0c;标签 通过拓扑 label 进行副本调度 label的使用无非就是增删改查 还有个重要的标签namespace&#xff08;命名空间&…