gige工业相机突破(三,c#winform实现,这些花费巨大,可以私有,不必公布的独门绝技,为什么要公开?)

我们是做个程序员,还是做个工程师?

我们是做个工程师,还是对世界充满兴趣和热爱的人?

这些花费巨大,可以私有,不必公布的独门绝技,为什么要公开?

通过华为事件,可以看出,我们的工业软件还是受制于人,我们所做的,只不过是为国家添砖加瓦,或者说报答父母。

这些规则,本来谁都可以得到,却被垄断了,不太好。

以下是c#winform的程序整理:(仍然是针对500万的海康gige工业黑白相机,这里的针对性很强,但又gige的协议和wireshark,我相信其他相机也是可以搞定的,最容易的是海康的其他分辨率的工业黑白相机)

  public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //   UdpClient socketRxRaw = new UdpClient(63378);
        UdpClient GVCPsocket = new UdpClient(3956);
        private void Form1_Load(object sender, EventArgs e)
        {
                
         


        
        }

        private void button1_Click(object sender, EventArgs e)
        {
         


            byte[] sendbuff = new byte[12] { 0x42, 0x01, 0x00, 0x02, 0x00, 0x00,0,1,0,0,0,0 };
       
            IPEndPoint remotetarget = new IPEndPoint(IPAddress.Parse("192.168.20.54"), 3956);
            IPEndPoint localtarget = new IPEndPoint(IPAddress.Any, 3956);
            GVCPsocket.Send(sendbuff, 12, remotetarget);

            Thread.Sleep(1000);

            byte[] buf = GVCPsocket.Receive(ref localtarget);

           // GVCPsocket.Close();//关闭链接
        }

        private void button2_Click(object sender, EventArgs e)
        {
            IPEndPoint localtarget = new IPEndPoint(IPAddress.Any, 3956);
            IPEndPoint remotetarget = new IPEndPoint(IPAddress.Parse("192.168.20.54"), 3956);
            byte[] sendbuff = new byte[12] {   0x42, 0x01, 0x00, 0x80, 0x00, 0x04,
        0x00, 0x91, 0x00, 0x03, 0x03, 0x60 };
          
            GVCPsocket.Send(sendbuff, 12, remotetarget);

            Thread.Sleep(1000);

            byte[] camwidth = GVCPsocket.Receive(ref localtarget);
        }

        private void button3_Click(object sender, EventArgs e)
        {
           

                  IPEndPoint localtarget = new IPEndPoint(IPAddress.Any, 3956);
            IPEndPoint remotetarget = new IPEndPoint(IPAddress.Parse("192.168.20.54"), 3956);
            byte[] sendbuff = new byte[12] {   0x42, 0x01, 0x00, 0x80, 0x00, 0x04,
        0x00, 0x92, 0x00, 0x03, 0x03, 0xa0 };

            GVCPsocket.Send(sendbuff, 12, remotetarget);

            Thread.Sleep(1000);

            byte[] camheight = GVCPsocket.Receive(ref localtarget);
        }

        private void button5_Click(object sender, EventArgs e)
        {
          

                   IPEndPoint localtarget = new IPEndPoint(IPAddress.Any, 3956);
            IPEndPoint remotetarget = new IPEndPoint(IPAddress.Parse("192.168.20.54"), 3956);
            byte[] sendbuff = new byte[12] {   0x42, 0x01, 0x00, 0x80, 0x00, 0x04,
        0x00, 0x93, 0x00, 0x03, 0x03, 0x0e0 };

            GVCPsocket.Send(sendbuff, 12, remotetarget);

            Thread.Sleep(200);

            byte[] camoffsetx = GVCPsocket.Receive(ref localtarget);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            IPEndPoint localtarget = new IPEndPoint(IPAddress.Any, 3956);
            IPEndPoint remotetarget = new IPEndPoint(IPAddress.Parse("192.168.20.54"), 3956);
            byte[] sendbuff = new byte[12] {  0x42, 0x01, 0x00, 0x80, 0x00, 0x04,
        0x00, 0x94, 0x00, 0x03, 0x04, 0x20};

            GVCPsocket.Send(sendbuff, 12, remotetarget);

            Thread.Sleep(100);

            byte[] camoffsety = GVCPsocket.Receive(ref localtarget);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            IPEndPoint localtarget = new IPEndPoint(IPAddress.Any, 3956);
            IPEndPoint remotetarget = new IPEndPoint(IPAddress.Parse("192.168.20.54"), 3956);
            byte[] sendbuff = new byte[12] {  0x42, 0x01, 0x00, 0x80, 0x00, 0x04,
        0x00, 0x95, 0x00, 0x03, 0x06, 0x10 };

            GVCPsocket.Send(sendbuff, 12, remotetarget);

            Thread.Sleep(50);

            byte[] cammono8 = GVCPsocket.Receive(ref localtarget);//=01080001
        }
        bool 可以控制 = false;
        bool 可以设置心跳 = false;
        private void button7_Click(object sender, EventArgs e)
        {
            IPEndPoint localtarget = new IPEndPoint(IPAddress.Any, 3956);
            IPEndPoint remotetarget = new IPEndPoint(IPAddress.Parse("192.168.20.54"), 3956);
            byte[] sendbuff = new byte[12] { 0x42, 0x01, 0x00, 0x80, 0x00, 0x04,
        0x01, 0x28, 0x00, 0x00, 0x0a, 0x00 };

            GVCPsocket.Send(sendbuff, 12, remotetarget);

            Thread.Sleep(50);

            byte[] retfree = GVCPsocket.Receive(ref localtarget);// //如果返回如此[11]=0,its free can be control

            if (retfree[11] == 0)
                可以控制 = true;
            if(可以控制)
            {
                //开始控制,向寄存器写入0x02
                sendbuff = new byte[16] { 0x42, 0x01, 0x00, 0x82, 0x00, 0x08,
        0x01, 0x29, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x02 };
                GVCPsocket.Send(sendbuff, 16, remotetarget);

                Thread.Sleep(50);
                retfree = GVCPsocket.Receive(ref localtarget);// //如果返回如此[11]=1,开始设置心跳

                if (retfree[11] ==1)
                    可以设置心跳 = true;
            }


            if (可以设置心跳)
            {
                byte 增加1 = 0x2d;
                for (int i = 0; i < 5; i++)//怎样判断gvcpReply.status==success?如果在5次内设置成功了,就要跳出来
                {
                    byte[] sendbuff16 = new byte[16] { 0x42, 0x01, 0x00, 0x82, 0x00, 0x08,
        0x01, 增加1, 0x00, 0x00, 0x09, 0x38, 0x00, 0x00, 0x27, 0x10 };

                    GVCPsocket.Send(sendbuff16, 16, remotetarget);

                    Thread.Sleep(500);

                    byte[] ret12 = GVCPsocket.Receive(ref localtarget);
                    if (ret12[11] == 1)
                    {
                        //成功了?
                        i = 5;
                        break;
                    }
                    增加1++;
                }
            }
            backgroundWorker1.RunWorkerAsync();//启动心跳

            }

        bool m_bgvsp = false;
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            byte hello增加1 = 0x2d;
            IPEndPoint remotetarget = new IPEndPoint(IPAddress.Parse("192.168.20.54"), 3956);
            m_bgvsp = true;
            while (m_bgvsp)
            {

                byte[] sendbuff16 = new byte[16] { 0x42, 0x01, 0x00, 0x82, 0x00, 0x08,
        0x01, hello增加1, 0x00, 0x00, 0x09, 0x38, 0x00, 0x00, 0x27, 0x10 };

                GVCPsocket.Send(sendbuff16, 16, remotetarget);            

                hello增加1++;

                Thread.Sleep(50);
            }
        }
        Socket socketRxRaw;
        private void button8_Click(object sender, EventArgs e)
        {
          

            if (m_bgvsp)
            {
                //1,开始控制,向寄存器写入GevSCPHostPort
                IPEndPoint remotetarget = new IPEndPoint(IPAddress.Parse("192.168.20.54"), 3956);
                byte[] sendbuff16 = new byte[16] { 0x42, 0x01, 0x00, 0x82, 0x00, 0x08,
        0x01, 0x2e, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f7, 0x92};//写入端口port=63378

            GVCPsocket.Send(sendbuff16, 16, remotetarget);//返回1,才可以下一步
                Thread.Sleep(50);
                //2,开始控制,向寄存器写入GevSCDA

                sendbuff16 = new byte[16] { 0x42, 0x01, 0x00, 0x82, 0x00, 0x08,
           0x01, 0x2f, 0x00, 0x00, 0x0d, 24, 192, 168, 20, 48};
            //写入ip192.168.20.48
                GVCPsocket.Send(sendbuff16, 16, remotetarget);//返回1,才可以下一步
                Thread.Sleep(50);
                /* 3, <Integer Name="ExposureTime_RegAddr">
                                              <Value>
                                                0x00030b04
                                              </Value>*/
                sendbuff16 = new byte[16] {0x42, 0x01, 0x00, 0x82, 0x00, 0x08,
        0x03, 0x2f, 0x00, 0x03, 0x0b, 0x04,0,0,0x61,0x0a8};
                //写入曝光值25000
              //   0x03, 0x2f, 0x00, 0x03, 0x0b, 0x04,0,0,0x3a,0x98}; //写入曝光值15000
                GVCPsocket.Send(sendbuff16, 16, remotetarget);//返回1,才可以下一步
                Thread.Sleep(50);
                //4,开始控制,向寄存器写入 var gevSCPSPacketSize = (await Gvcp.GetRegister(nameof(GvcpRegister.GevSCPSPacketSize))).pValue;//地址0x0d04
                sendbuff16 = new byte[16] {0x42, 0x01, 0x00, 0x82, 0x00, 0x08,
            0x01, 0x31, 0x00, 0x00, 0x0d,  0x04, 64, 0, 0x1f, 0x0e4};
                //写入mtu8164
                GVCPsocket.Send(sendbuff16, 16, remotetarget);//返回1,才可以下一步
                Thread.Sleep(50);
                //5,开始控制,向寄存器写入  acquisitionStart.SetValueAsync(1).ConfigureAwait(false)) as GvcpReply
                sendbuff16 = new byte[16] {0x42, 0x01, 0x00, 0x82, 0x00, 0x08,
        0x01, 0x32, 0x00, 0x03, 0x08, 4, 0, 0, 0, 1};
                //写入mtu8164
                GVCPsocket.Send(sendbuff16, 16, remotetarget);//返回1,才可以下一步,进入异步线程接受图像
                Thread.Sleep(50);

                IPEndPoint localtarget = new IPEndPoint(IPAddress.Any, 3956);
                byte[] ret12 = GVCPsocket.Receive(ref localtarget);


                if (ret12[11] == 0x01)
                {
                    buffer5038848[0] = new byte[2592 * 1944];
                    buffer5038848[1] = new byte[5038848];

                    //初始化接受套接字
                    // 设置UDP服务器的端点
                  
                    socketRxRaw = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    socketRxRaw.Bind(new IPEndPoint(IPAddress.Any, 63378));// ProtocolType.Udp

                    //   IPEndPoint remotetargetRx = new IPEndPoint(IPAddress.Parse("192.168.20.54"), 63378);
                    //    IPEndPoint localtargetRx = new IPEndPoint(IPAddress.Any, 63378);

                    socketRxRaw.ReceiveTimeout = 1000;
                    //One full hd image with GVSP2.0 Header as default, it will be updated for image type

                    socketRxRaw.ReceiveBufferSize = (int)(5*1024 * 1024);

                    //socketRxRaw.ReceiveBufferSize = (int)(1920 * 1100);

                    创建缓冲区以接收数据
                    //byte[] bytess = new byte[socketRxRaw.ReceiveBufferSize];
                    //EndPoint remoteEP = (EndPoint)groupEP;

                    //接受第0帧,测试帧
                    //  socketRxRaw.Receive(m_buff9000);
                    // 等待广播数据
                    //int bytesRec = socketRxRaw.ReceiveFrom(bytess, ref remoteEP);
                    //if (bytess[7]==0)
                    {
                        backgroundWorker2.RunWorkerAsync();
                    }
                    
                }
            }
        }
        void showbuffer2pict(byte[] buffer, int ww, int hh, PictureBox destImg)
        {
             destImg.Size = new System.Drawing.Size(ww, hh);
            //  //顯示
            //  int mod = ww % 4;//解决四位对齐问题20150716
            //  ww = ww  - mod;

            //  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;

            int mod = ww % 4;//解决四位对齐问题20150716
            int temproiw = ww + (4 - mod) % 4;//其实这都是和显示相关,处理图像其实不必考虑,
            //顯示
            byte[] cutvalues = new byte[temproiw * hh * 3];
            int bytes = temproiw * hh * 3;
            Bitmap cutPic24 = new Bitmap(temproiw, hh, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            BitmapData _cutPic = cutPic24.LockBits(new Rectangle(0, 0, temproiw, 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;
                    int m = 3 * (i * temproiw + j);
                    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;
        }
        byte[][] buffer5038848 = new byte[2][];
        byte[] m_buff9000 = new byte[9000];
     //   int frame = 1;
     //   int jiou = 1;
        IntPtr destptr = Marshal.AllocHGlobal(8128);    // 分配一个内存块  
        IntPtr destptrbig = Marshal.AllocHGlobal(5038848);    // 分配一个内存块  
        IntPtr destptrbig2 = Marshal.AllocHGlobal(5038848);    // 分配一个内存块  

        public const int WM_COPYDATA = 0x004A;
        [StructLayout(LayoutKind.Sequential)]
        public struct CopyDataStruct
        {
            public IntPtr dwData;
            public int cbData;
            //   [MarshalAs(UnmanagedType.LPStr)]
            public IntPtr lpData;

        }
        [DllImport("User32.dll", EntryPoint = "SendMessage"),]
        private static extern int SendMsg(int hwnd, int msg, int wparms, ref CopyDataStruct lparm);
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern int FindWindow(string lpClassName, string lpWindowName);
        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 63378);
            EndPoint remoteEP=(EndPoint)groupEP;
            int frame = 1;
            int jiou = 1;
       //     buffer5038848[0] = new byte[5038848];
      //      buffer5038848[1] = new byte[5038848];
            while (true)
            {
                int changdu = socketRxRaw.Receive(m_buff9000);//与函数ReceiveFrom结果一样
                                                              //  if (m_buff9000[7] == 0) continue;
                if (changdu > 1000)
                {
                    int packetIDperframe = (m_buff9000[6] << 8) | m_buff9000[7];
                    //  int zhenshidenPartOfFrame = (packetIDperframe ) % 619;
                    if (0 == packetIDperframe) continue;

                    jiou = frame % 2;


                    if (620 == packetIDperframe)//620有三个包,两个长度小于1000,202404021844剩下两个会不会是帧率?和第几帧?
                    {
                        if (jiou == 1)//效果不明显202404021914
                        {
                            System.Runtime.InteropServices.Marshal.Copy(m_buff9000, 8, destptrbig + (packetIDperframe - 1) * 8128, 7616);//结果与上面一样,有横线
                            System.Runtime.InteropServices.Marshal.Copy(destptrbig, buffer5038848[0], 0, 5038848);

                            showbuffer2pict(buffer5038848[0], 2592, 1944, pictureBox9);
                        }
                        else
                        {
                            System.Runtime.InteropServices.Marshal.Copy(m_buff9000, 8, destptrbig2 + (packetIDperframe - 1) * 8128, 7616);//结果与上面一样,有横线
                            System.Runtime.InteropServices.Marshal.Copy(destptrbig2, buffer5038848[1], 0, 5038848);
                            showbuffer2pict(buffer5038848[1], 2592, 1944, pictureBox9);
                        }
                        frame++;
                           cds.lpData = buffer2[1];//这样写可以吗?

                        //if (jiou == 0)
                        //{
                        //    //  cds.lpData = buffer2[0];


                        //showbuffer2pict(buffer5038848[0], 2592, 1944, pictureBox9);
                    }
                    else//处理1-619包
                    {
                        if (jiou == 1)
                        {
                            System.Runtime.InteropServices.Marshal.Copy(m_buff9000, 8, destptrbig + (packetIDperframe - 1) * 8128, 8128);//结果与上面一样,有横线
                        }
                        else
                        {
                            System.Runtime.InteropServices.Marshal.Copy(m_buff9000, 8, destptrbig2 + (packetIDperframe - 1) * 8128, 8128);//结果与上面一样,有横线
                        }
                    }
                }
            }
          for(;;)
            {
                //try
                //{
                 //   int changdu = socketRxRaw.ReceiveFrom(m_buff9000, ref remoteEP);
                    int changdu = socketRxRaw.Receive(m_buff9000);//与函数ReceiveFrom结果一样
                    if (m_buff9000[7] == 0) continue;
                   // int changdu = socketRxRaw.Receive(m_buff9000);//虽然8164,只接受8136
                    if (changdu != 8136) continue;
                    if (changdu == 8136)
                    {
                      //  jiou = frame % 2;
                        int packetIDperframe = (m_buff9000[6] << 8) | m_buff9000[7];//7,8字节是每帧的分包计数
                        int zhenshidenPartOfFrame = (packetIDperframe - 1) % 619;//5038848/8128=619

                        //if (jiou == 1)
                        //{

                        //    //int bufferStart = (zhenshidenPartOfFrame) *8128; //This use buffer length of regular packet
                        //    //int bufferLength = 8136 -8;  //This will only change for final packet

                        //    System.Runtime.InteropServices.Marshal.Copy(m_buff9000, 8, destptr, 8128);
                        //    System.Runtime.InteropServices.Marshal.Copy(destptr, buffer5038848[1], zhenshidenPartOfFrame * 8128, 8128);
                        //    //  std::copy(std::begin(buffer) + 8, std::begin(buffer) + 8136, buffer2[1] + zhenshidenPartOfFrame * 8128);

                        //}
                        //else
                        //{
                        //    //  std::copy(std::begin(buffer) + 8, std::begin(buffer) + 8136, buffer2[0] + zhenshidenPartOfFrame * 8128);

                        
                            //System.Runtime.InteropServices.Marshal.Copy(m_buff9000, 8, destptr, 8128);
                            //System.Runtime.InteropServices.Marshal.Copy(destptr, buffer5038848[0], zhenshidenPartOfFrame * 8128, 8128);

                        //destptrbig202403301518,为什么c#有横线,c版本没有,代码是一致的
                        System.Runtime.InteropServices.Marshal.Copy(m_buff9000, 8, destptrbig+ zhenshidenPartOfFrame * 8128, 8128);//结果与上面一样,有横线
                        //     }

                        if (618 == zhenshidenPartOfFrame)
                        {

                            //frame++;
                               cds.lpData = buffer2[1];//这样写可以吗?

                            //if (jiou == 0)
                            //{
                            //    //  cds.lpData = buffer2[0];

                            System.Runtime.InteropServices.Marshal.Copy(destptrbig, buffer5038848[0], 0,5038848);
                            showbuffer2pict(buffer5038848[0], 2592, 1944, pictureBox9);//不是bmp z序的,正常的202302061722
                                                                                       //}
                                                                                       //else
                                                                                       //{
                                                                                       //    showbuffer2pict(buffer5038848[1], 2592, 1944, pictureBox9);//不是bmp z序的,正常的202302061722
                                                                                       //}


                      //  int windowHandler = FindWindow(null, "arrimg");
                      //  if (windowHandler == 0)
                      //  {
                      //      return;
                      //  }
                       if (Matchbt != null)
                      //  {
                      //      CopyDataStruct cds = new CopyDataStruct();
                      //      cds.dwData = (IntPtr)null;
                      //   //   cds.cbData = Matchbt.GetLength(0);
                      //      cds.cbData = 5038848;
                      //      // Matchbt.ToString();
                      //      cds.lpData = Marshal.AllocHGlobal(5038848);

                      //      Marshal.Copy(buffer5038848[0], 0, cds.lpData, 5038848);
                      //      SendMsg(windowHandler, WM_COPYDATA, 0, ref cds);
                      //  }


                    }
                    }
                //}
                //catch (Exception ee)
                //{ }
              
             }

        }
    }

作为一个泥瓦工(程序猿)要上升到墨子或鲁班(数学家)的境界,难度是非常大的,但最基础的一点,充满热爱,能解决小问题,能思考,把老师教的,能用,变成自己的,持之以恒,在某个方向上努力自学。

我也很喜欢,好好学习,天天向上。这句话。

你有没有发现,500万黑白工业相机的所有像素等于5038848,最后四个数字8848,这不是珠穆朗玛峰的高度吗?

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值