using OpenCvSharp; using OpenCvSharp.Extensions; using PaintDotNet.Setting; using StageController; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Metis.AutoAnalysis { public class AutoFocusWorkflow { private static bool _isWorking; public static double m_CurrentValue; public static void Stop() { _isWorking = false; } public static void AutoFocusFast(AxisController stage, Func CurrentImage) { if (_isWorking) return; _isWorking = true; int round = 0;//翻转次数 double pulse = FocusingParameter.getRuleFocus().StepLength / 4;//最小步长1.25um double lastValue = 0.0; int dir = -1; //方向 double trip = 0.0; // _mask = CreateMask(CurrentImage()); try { while (_isWorking) { //Console.Write("Before focus:"); stage.WaitMoveDone(); //Console.Write("自动聚焦:"); Thread.Sleep(40); try { Bitmap m_bitmap = CurrentImage(); m_CurrentValue = getMeanValueOfBitmap(m_bitmap); //Console.WriteLine(string.Format("{0:f3} Z:{1:f3}", m_CurrentValue, stage.Z)); } catch (Exception ex) { return; } if (round > 1) return; else if (lastValue == 0) ; else if (m_CurrentValue > lastValue) { round = 1; } else { //Console.WriteLine("Reverse:" + (dir > 0 ? "+" : "-")); round++; dir = -dir; } lastValue = m_CurrentValue; trip += pulse * dir; if (Math.Abs(trip) > pulse * 10) { Console.WriteLine("Trip of Z out of autofocus range."); return; } stage.Up(pulse * dir); } } catch { } finally { // Console.Write("End focus:"); stage.WaitMoveDone(); //m_CurrentValue = getMeanValueOfBitmap(CurrentImage()); //Console.WriteLine(string.Format("聚焦完成:{0:f3} Z:{1:f3}", m_CurrentValue, stage.Z)); _isWorking = false; // stage.LockZ(); } } static Mat _mask; private static Mat CreateMask(Bitmap img) { Mat converted = BitmapConverter.ToMat(img); Mat imageGrey = new Mat(); try { if (converted.Channels() == 3) OpenCvSharp.Cv2.CvtColor(converted, imageGrey, OpenCvSharp.ColorConversionCodes.RGB2GRAY); else if (converted.Channels() == 1) imageGrey = converted; } catch (Exception) { imageGrey = converted; } //stage.SetSpeedZ(40); Mat mask = new Mat(); Cv2.Threshold(imageGrey, mask, 0, 255, ThresholdTypes.Triangle); var kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(20, 20)); Cv2.Dilate(mask, mask, kernel); //Cv2.Erode(mask, mask, kernel); return mask; } private static Mat CreateMask(Mat imageGrey) { Mat mask = new Mat(); Cv2.Threshold(imageGrey, mask, 0, 255, ThresholdTypes.Triangle); var kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(20, 20)); Cv2.Dilate(mask, mask, kernel); return mask; } /// /// 获取输入图片的清晰度 /// /// /// private static double getMeanValueOfBitmap(Bitmap bitmap) { Mat converted = BitmapConverter.ToMat(bitmap); Mat imageGrey = new Mat(); Mat imageSobel = new Mat(); try { if (converted.Channels() == 3) OpenCvSharp.Cv2.CvtColor(converted, imageGrey, OpenCvSharp.ColorConversionCodes.RGB2GRAY); else if (converted.Channels() == 1) imageGrey = converted; } catch (Exception) { imageGrey = converted; } OpenCvSharp.Mat meanValueImage = new OpenCvSharp.Mat(); OpenCvSharp.Mat meanStdValueImage = new OpenCvSharp.Mat(); _mask = CreateMask(imageGrey); //求灰度图像的标准差 值越大越好 OpenCvSharp.Cv2.MeanStdDev(imageGrey, meanValueImage, meanStdValueImage, _mask); return meanStdValueImage.At(0, 0); } } }