// 主体 void RunSingleCamera(AcquireMode acquireMode) { try { // 获取图像 AcquireImages(acquireMode); } catch (SpinnakerException ex) { Console.WriteLine("Error: {0}", ex.Message); } }
/// <summary> /// Set current acquire mode of the oscilloscope. /// </summary> public void SetAcquireMode(AcquireMode memoryDepth) { Write(":ACQuire:MODE " + memoryDepth.SetterDescription()); }
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); } }