Example #1
0
 private void SaveCaptures_Click(object sender, RoutedEventArgs e)
 {
     if (camControl != null && !camControl.IsAviWriting)
     {
         Task.Run(() =>
         {
             isSaving        = true;
             var baseFolder  = MakeImageFolder(AviPath);
             string basePath = baseFolder + DateTime.Now.ToString("ddd, dd MMM yyyy hh-mm-ss tt") + " ";
             int k           = 1;
             while (camControl.queueForJPGs.Count > 0)
             {
                 using (IManagedImage rawImage = camControl.queueForJPGs.Dequeue())
                 {
                     rawImage.Save(basePath + k++ + ".jpg");
                 }
             }
             isSaving = false;
         });
     }
 }
Example #2
0
        // Code below is directly copied from example_acquisition

        // This function acquires and saves 10 images from a device.
        public int AcquireImages(IManagedCamera cam, INodeMap nodeMap, INodeMap nodeMapTLDevice)
        {
            int result = 0;

            writeLog(String.Format("\n*** IMAGE ACQUISITION ***\n\n"));

            try
            {
                //
                // Set acquisition mode to continuous
                //
                // *** NOTES ***
                // Because the example acquires and saves 10 images, setting
                // acquisition mode to continuous lets the example finish. If
                // set to single frame or multiframe (at a lower number of
                // images), the example would just hang. This is because the
                // example has been written to acquire 10 images while the
                // camera would have been programmed to retrieve less than that.
                //
                // Setting the value of an enumeration node is slightly more
                // complicated than other node types. Two nodes are required:
                // first, the enumeration node is retrieved from the nodemap and
                // second, the entry node is retrieved from the enumeration node.
                // The symbolic of the entry node is then set as the new value
                // of the enumeration node.
                //
                // Notice that both the enumeration and entry nodes are checked
                // for availability and readability/writability. Enumeration
                // nodes are generally readable and writable whereas entry
                // nodes are only ever readable.
                //
                // Retrieve enumeration node from nodemap
                IEnum iAcquisitionMode = nodeMap.GetNode <IEnum>("AcquisitionMode");
                if (iAcquisitionMode == null || !iAcquisitionMode.IsWritable)
                {
                    writeLog(String.Format(
                                 "Unable to set acquisition mode to continuous (node retrieval). Aborting...\n\n"));
                    return(-1);
                }

                // Retrieve entry node from enumeration node
                IEnumEntry iAcquisitionModeContinuous = iAcquisitionMode.GetEntryByName("Continuous");
                if (iAcquisitionModeContinuous == null || !iAcquisitionMode.IsReadable)
                {
                    writeLog(String.Format(
                                 "Unable to set acquisition mode to continuous (enum entry retrieval). Aborting...\n\n"));
                    return(-1);
                }

                // Set symbolic from entry node as new value for enumeration node
                iAcquisitionMode.Value = iAcquisitionModeContinuous.Symbolic;

                writeLog(String.Format("Acquisition mode set to continuous...\n"));

                //
                // Begin acquiring images
                //
                // *** NOTES ***
                // What happens when the camera begins acquiring images depends
                // on which acquisition mode has been set. Single frame captures
                // only a single image, multi frame catures a set number of
                // images, and continuous captures a continuous stream of images.
                // Because the example calls for the retrieval of 10 images,
                // continuous mode has been set for the example.
                //
                // *** LATER ***
                // Image acquisition must be ended when no more images are needed.
                //
                cam.BeginAcquisition();

                writeLog(String.Format("Acquiring images...\n"));

                //
                // Retrieve device serial number for filename
                //
                // *** NOTES ***
                // The device serial number is retrieved in order to keep
                // different cameras from overwriting each other's images.
                // Grabbing image IDs and frame IDs make good alternatives for
                // this purpose.
                //
                String deviceSerialNumber = "";

                IString iDeviceSerialNumber = nodeMapTLDevice.GetNode <IString>("DeviceSerialNumber");
                if (iDeviceSerialNumber != null && iDeviceSerialNumber.IsReadable)
                {
                    deviceSerialNumber = iDeviceSerialNumber.Value;

                    writeLog(String.Format(
                                 "Device serial number retrieved as {0}...\n", deviceSerialNumber));
                }
                writeLog(String.Format("\n"));

                // Retrieve, convert, and save images
                const int NumImages = 10;

                for (int imageCnt = 0; imageCnt < NumImages; imageCnt++)
                {
                    try
                    {
                        //
                        // Retrieve next received image
                        //
                        // *** NOTES ***
                        // Capturing an image houses images on the camera buffer.
                        // Trying to capture an image that does not exist will
                        // hang the camera.
                        //
                        // Using-statements help ensure that images are released.
                        // If too many images remain unreleased, the buffer will
                        // fill, causing the camera to hang. Images can also be
                        // released manually by calling Release().
                        //
                        using (IManagedImage rawImage = cam.GetNextImage())
                        {
                            //
                            // Ensure image completion
                            //
                            // *** NOTES ***
                            // Images can easily be checked for completion. This
                            // should be done whenever a complete image is
                            // expected or required. Alternatively, check image
                            // status for a little more insight into what
                            // happened.
                            //
                            if (rawImage.IsIncomplete)
                            {
                                writeLog(String.Format(
                                             "Image incomplete with image status {0}...\n", rawImage.ImageStatus));
                            }
                            else
                            {
                                //
                                // Print image information; width and height
                                // recorded in pixels
                                //
                                // *** NOTES ***
                                // Images have quite a bit of available metadata
                                // including CRC, image status, and offset
                                // values to name a few.
                                //
                                uint width = rawImage.Width;

                                uint height = rawImage.Height;

                                writeLog(String.Format(
                                             "Grabbed image {0}, width = {1}, height = {1}\n", imageCnt, width, height));
                                writeLog(String.Format(
                                             "Pixel format is {0}\n", rawImage.PixelFormatName));

                                //
                                // Convert image to mono 8
                                //
                                // *** NOTES ***
                                // Images can be converted between pixel formats
                                // by using the appropriate enumeration value.
                                // Unlike the original image, the converted one
                                // does not need to be released as it does not
                                // affect the camera buffer.
                                //
                                // Using statements are a great way to ensure code
                                // stays clean and avoids memory leaks.
                                // leaks.
                                //
                                using (IManagedImage convertedImage = rawImage.Convert(PixelFormatEnums.Mono8))
                                {
                                    // Create a unique filename
                                    String filename = "Acquisition-CSharp-";
                                    if (deviceSerialNumber != "")
                                    {
                                        filename = filename + deviceSerialNumber + "-";
                                    }
                                    filename = filename + imageCnt + ".jpg";

                                    //
                                    // Save image
                                    //
                                    // *** NOTES ***
                                    // The standard practice of the examples is
                                    // to use device serial numbers to keep
                                    // images of one device from overwriting
                                    // those of another.
                                    //
                                    convertedImage.Save(filename);

                                    writeLog(String.Format("Image saved at {0}\n\n", filename));
                                }
                            }
                        }
                    }
                    catch (SpinnakerException ex)
                    {
                        writeLog(String.Format("Error: {0}\n", ex.Message));
                        result = -1;
                    }
                }

                //
                // End acquisition
                //
                // *** NOTES ***
                // Ending acquisition appropriately helps ensure that devices
                // clean up properly and do not need to be power-cycled to
                // maintain integrity.
                //
                cam.EndAcquisition();
            }
            catch (SpinnakerException ex)
            {
                writeLog(String.Format("Error: {0}\n", ex.Message));
                result = -1;
            }

            return(result);
        }
Example #3
0
        void AcquireImages(AcquireMode acquireMode)
        {
            try
            {
                try
                {
                    if (acquireMode.Equals(AcquireMode.CONTINUOUS))
                    {
                        cam.AcquisitionMode.Value = AcquisitionModeEnums.Continuous.ToString();
                    }
                    else if (acquireMode.Equals(AcquireMode.MULTIFRAME))
                    {
                        cam.AcquisitionMode.Value       = AcquisitionModeEnums.MultiFrame.ToString();
                        cam.AcquisitionFrameCount.Value = NumImages;
                    }
                    else if (acquireMode.Equals(AcquireMode.SINGLEFRAME))
                    {
                        cam.AcquisitionMode.Value = AcquisitionModeEnums.SingleFrame.ToString();
                    }
                    //Console.WriteLine("设置获取模式-成功!");
                }
                catch (Exception)
                {
                    Console.WriteLine("连续获取模式设置-失败!");
                }

                //
                // 获取图像前
                //
                // *** NOTES ***
                // 获取图像前的操作取决于 图像获取模式。
                // Single frame captures :单图模式只获取一张图像
                // multi frame catures :多图模式获取多张图像
                // continuous captures :连续模式获得图像流
                //
                // *** LATER ***
                // 不需要获取图像后需要关闭图像获取
                //
                cam.BeginAcquisition();

                //Console.WriteLine("获取图像...");

                switch (acquireMode)
                {
                case AcquireMode.CONTINUOUS:
                    stopwatch2.Start();
                    int miss = 0;
                    for (int imageCnt = 0; imageCnt < 100; imageCnt++)
                    {
                        try
                        {
                            //
                            // 获取下一幅图像
                            //
                            // *** NOTES ***
                            // 获取相机缓冲器上的图像,若图像不存在则导致相机挂起
                            //
                            // 使用using关键字可以保证图像正确释放
                            // 缓冲器图像超出容量导致相机挂起,调用 Release() 可以手动释放图像。
                            //
                            using (IManagedImage rawImage = cam.GetNextImage())
                            {
                                //
                                // 确保图像的完整性
                                //
                                // *** NOTES ***
                                // 检测完整性,并检测错误
                                //
                                if (rawImage.IsIncomplete)
                                {
                                    miss++;
                                    Console.WriteLine("图像不完整,状态为: {0}...", rawImage.ImageStatus);
                                    Console.WriteLine("{1} miss={0}", miss, imageCnt);
                                }
                                else
                                {
                                    //
                                    // 输出长宽
                                    //
                                    // *** NOTES ***
                                    // 图像包含大量元数据,包括CRC、图像状态和偏移值等等
                                    //
                                    //uint width = rawImage.Width;

                                    //uint height = rawImage.Height;

                                    //Console.WriteLine("当前图像 {0}, width = {1}, height = {2}", imageCnt, width, height);

                                    //
                                    // 转换为8位单通道
                                    //
                                    // *** NOTES ***
                                    // 图像格式可以在已有枚举间任意转换
                                    // 与原始图像不同,转换的图像无需释放且不影响图像缓冲器
                                    //
                                    // using避免内存溢出.
                                    //
                                    using (IManagedImage convertedImage = rawImage.Convert(PixelFormatEnums.Mono8))
                                    {
                                        //显示
                                        //ImageBox.Source = ToBitmapSource(convertedImage.bitmap);
                                    }
                                }
                            }
                        }
                        catch (SpinnakerException ex)
                        {
                            Console.WriteLine("Error: {0}", ex.Message);
                        }
                    }
                    Console.WriteLine("miss:{0} in 1000", miss);
                    stopwatch2.Stop();
                    Console.WriteLine("time:{0}", stopwatch2.ElapsedMilliseconds / 100.0);
                    stopwatch2.Reset();
                    break;

                case AcquireMode.MULTIFRAME:
                    for (int imageCnt = 0; imageCnt < NumImages; imageCnt++)
                    {
                        try
                        {
                            using (IManagedImage rawImage = cam.GetNextImage())
                            {
                                if (rawImage.IsIncomplete)
                                {
                                    Console.WriteLine("图像不完整,状态为: {0}...", rawImage.ImageStatus);
                                }
                                else
                                {
                                    uint width = rawImage.Width;

                                    uint height = rawImage.Height;

                                    Console.WriteLine("当前图像 {0}, width = {1}, height = {2}", imageCnt, width, height);

                                    using (IManagedImage convertedImage = rawImage.Convert(PixelFormatEnums.Mono8))
                                    {
                                        ImageBox.Source = ToBitmapSource(convertedImage.bitmap);
                                        String filename = SavePath + "/" + "Acquisition-CSharp-";
                                        if (deviceSerialNumber != "")
                                        {
                                            filename = filename + deviceSerialNumber + "-";
                                        }
                                        filename = filename + imageCnt + ".jpg";
                                        convertedImage.Save(filename);
                                        //Console.WriteLine("图像 {0} 已储存\n", filename);
                                    }
                                }
                            }
                        }
                        catch (SpinnakerException ex)
                        {
                            Console.WriteLine("Error: {0}", ex.Message);
                        }
                    }
                    break;

                case AcquireMode.SINGLEFRAME:
                    try
                    {
                        //stopwatch2.Start();
                        using (IManagedImage rawImage = cam.GetNextImage())
                        {
                            if (rawImage.IsIncomplete)
                            {
                                Console.WriteLine("图像不完整,状态为: {0}...", rawImage.ImageStatus);
                            }
                            else
                            {
                                int width  = (int)rawImage.Width;
                                int height = (int)rawImage.Height;
                                Console.WriteLine("当前图像 {0}, width = {1}, height = {2}", 0, width, height);


                                //Matrix<double> cameraMat = new Matrix<double>(3, 3);
                                //cameraMat.Data[0, 0] = 2578.42;  cameraMat.Data[0, 1] = 0;         cameraMat.Data[0, 2] = 1266.60;
                                //cameraMat.Data[1, 0] = 0;        cameraMat.Data[1, 1] = 2491.45;   cameraMat.Data[1, 2] = 1111.35;
                                //cameraMat.Data[2, 0] = 0;        cameraMat.Data[2, 1] = 0;         cameraMat.Data[2, 2] = 1;
                                //Matrix<double> distortionMat = new Matrix<double>(1, 4);
                                //distortionMat.Data[0, 0] = -0.078470991609759;
                                //distortionMat.Data[0, 1] = 0.109106631527471;
                                //distortionMat.Data[0, 2] = 0;
                                //distortionMat.Data[0, 3] = 0;
                                //Matrix<double> mapxMat = new Matrix<double>(height, width);
                                //Matrix<double> mapyMat = new Matrix<double>(height, width);
                                //CvInvoke.InitUndistortRectifyMap(cameraMat, distortionMat, null, cameraMat, new System.Drawing.Size((int)width, (int)height), DepthType.Cv8U, mapxMat,mapyMat);

                                using (IManagedImage convertedImage = rawImage.Convert(PixelFormatEnums.Mono8))
                                {
                                    //ManagedImage currentImage = new ManagedImage(convertedImage);
                                    //畸变矫正
                                    //CvInvoke.Remap(convertedImage, currentImage, mapxMat, mapyMat, Inter.Linear);


                                    //显示
                                    ImageBox.Source = ToBitmapSource(convertedImage.bitmap);
                                    //检测高亮点
                                    IntPtr imgPtr = convertedImage.DataPtr;
                                    byte   maxPiexl;
                                    double X_ind, Y_ind;

                                    List <double[, ]> list = new List <double[, ]>();
                                    for (int y = 0; y < height; y++)
                                    {
                                        //mono8格式,忽略边缘两个像素
                                        maxPiexl = Marshal.ReadByte(imgPtr, (int)(y * width + 2));
                                        X_ind    = 2;
                                        Y_ind    = y;



                                        for (int x = 3; x < width - 2; x++)
                                        {
                                            byte currentPiexl = Marshal.ReadByte(imgPtr, (int)(y * width + x));
                                            if (currentPiexl > maxPiexl)
                                            {
                                                maxPiexl = currentPiexl;
                                                X_ind    = x;
                                                Y_ind    = y;
                                            }
                                        }

                                        if (maxPiexl < acceptPointValue.slider.Value)
                                        {
                                            continue;
                                        }

                                        //重心法求光心,取邻域2个像素距离
                                        byte piexel0 = Marshal.ReadByte(imgPtr, (int)(Y_ind * width + X_ind - 2));
                                        byte piexel1 = Marshal.ReadByte(imgPtr, (int)(Y_ind * width + X_ind - 1));
                                        byte piexel2 = Marshal.ReadByte(imgPtr, (int)(Y_ind * width + X_ind + 1));
                                        byte piexel3 = Marshal.ReadByte(imgPtr, (int)(Y_ind * width + X_ind + 2));

                                        X_ind = (piexel0 * (X_ind - 2) + piexel1 * (X_ind - 1) + maxPiexl * X_ind + piexel2 * (X_ind + 1) + piexel3 * (X_ind + 2)) / (piexel0 + piexel1 + maxPiexl + piexel2 + piexel3);
                                        //Console.WriteLine("(x,y)=>({0},{1})", X_ind, Y_ind);

                                        //距离计算
                                        double halfHeightPic = 1111.35;
                                        double halfWidthPic  = 1266.60;
                                        //全部转换为mm
                                        double perPiexl = 3.45 / 1000.0;      //单位像素大小
                                        double f        = 8.596;              //8.596;//焦距
                                        double s        = 265;                //基线长度
                                        double beta0    = 90 * Math.PI / 180; //初始度数
                                        //double epsilon = 0 * Math.PI / 180;
                                        //double offset0 = -halfWidthPic* perPiexl;//待拟合
                                        double beta1;

                                        double _d, _f, d, offset;

                                        _f = f / Math.Cos(Math.Atan(Math.Abs(Y_ind - halfHeightPic) * perPiexl / f));
                                        //offset = offset0 + f * (Math.Tan(epsilon + Math.PI/2 - beta0) - Math.Tan(Math.PI/2 - beta0));
                                        offset = f / Math.Tan(beta0);
                                        //beta1 = Math.Atan(_f / (halfWidthPic*perPiexl + offset));
                                        beta1 = Math.Atan(_f / offset);
                                        _d    = s * _f / ((X_ind - halfWidthPic) * perPiexl + offset);
                                        d     = f * s / ((X_ind - halfWidthPic) * perPiexl + offset);

                                        double xx, yy, zz;
                                        xx = _d * Math.Tan(Math.PI / 2 - beta1);
                                        yy = _d * Math.Sin(Math.Atan(Math.Abs(Y_ind - halfHeightPic) * perPiexl / f));
                                        zz = d;

                                        double[,] xyz = new double[1, 3];
                                        xyz[0, 0]     = beta0 > Math.PI / 2 ? xx : -xx;
                                        xyz[0, 1]     = Y_ind > halfHeightPic ? yy : -yy;
                                        xyz[0, 2]     = zz;
                                        list.Add(xyz);
                                        Console.WriteLine("[{3}\t,{4}\t](x,y,z)=>({0}\t,{1}\t,{2}\t)", Math.Round(xyz[0, 0], 3), Math.Round(xyz[0, 1], 3), Math.Round(xyz[0, 2], 3), Y_ind, Math.Round(X_ind, 3));//math.round(x,3)保留3为小数
                                    }
                                    //保存list
                                    Util.PLYUtil ply = new Util.PLYUtil(".");
                                    ply.PLYWriter(list, "raw.ply");
                                }
                            }
                        }

                        Console.WriteLine("获取单张显示计算耗时:{0}", stopwatch2.ElapsedMilliseconds);
                    }
                    catch (SpinnakerException ex)
                    {
                        Console.WriteLine("Error: {0}", ex.Message);
                    }
                    break;
                }

                //
                // 结束捕获图像
                //
                // *** NOTES ***
                // 保持设备内存干净,而不用重启设备
                //
                cam.EndAcquisition();
            }
            catch (SpinnakerException ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }
        }