public IEnumerator <ITask> QueryFrameHandler(webcam.QueryFrame req) { yield return(Arbiter.Choice(_scribblerPort.GetImage(req.Body.Format), delegate(brick.ImageResponse r) { try { var resp = new webcam.QueryFrameResponse() { Format = req.Body.Format, Size = new System.Drawing.Size(r.Width, r.Height), TimeStamp = r.Timestamp, }; if (req.Body.Format.Equals(MyroImageType.Color.Guid)) { resp.Frame = convertColorToRGB(r.Data, r.Width, r.Height); } else if (req.Body.Format.Equals(MyroImageType.Gray.Guid)) { resp.Frame = r.Data; } else if (req.Body.Format.Equals(MyroImageType.JpegColor.Guid) || req.Body.Format.Equals(MyroImageType.JpegColorFast.Guid)) { resp.Frame = r.Data; } else if (req.Body.Format.Equals(MyroImageType.JpegGray.Guid) || req.Body.Format.Equals(MyroImageType.JpegGrayFast.Guid)) { resp.Frame = r.Data; } else { throw new Exception("FlukeCam does not know how to convert this image type"); } req.ResponsePort.Post(resp); } catch (Exception e) { req.ResponsePort.Post(RSUtils.FaultOfException(e)); } }, delegate(Fault f) { req.ResponsePort.Post(f); })); }
public IEnumerator<ITask> QueryFrameHandler(webcam.QueryFrame req) { yield return Arbiter.Choice(_scribblerPort.GetImage(req.Body.Format), delegate(brick.ImageResponse r) { try { var resp = new webcam.QueryFrameResponse() { Format = req.Body.Format, Size = new System.Drawing.Size(r.Width, r.Height), TimeStamp = r.Timestamp, }; if (req.Body.Format.Equals(MyroImageType.Color.Guid)) resp.Frame = convertColorToRGB(r.Data, r.Width, r.Height); else if (req.Body.Format.Equals(MyroImageType.Gray.Guid)) resp.Frame = r.Data; else if (req.Body.Format.Equals(MyroImageType.JpegColor.Guid) || req.Body.Format.Equals(MyroImageType.JpegColorFast.Guid)) resp.Frame = r.Data; else if (req.Body.Format.Equals(MyroImageType.JpegGray.Guid) || req.Body.Format.Equals(MyroImageType.JpegGrayFast.Guid)) resp.Frame = r.Data; else throw new Exception("FlukeCam does not know how to convert this image type"); req.ResponsePort.Post(resp); } catch (Exception e) { req.ResponsePort.Post(RSUtils.FaultOfException(e)); } }, delegate(Fault f) { req.ResponsePort.Post(f); }); }
public void QueryFrameHandler(webcam.QueryFrame queryFrame) { if (_state.Frame == null) { queryFrame.ResponsePort.Post(new webcam.QueryFrameResponse()); } else if (queryFrame.Body.Format == Guid.Empty) { // raw image requested; BitmapData raw = null; try { raw = _state.Frame.LockBits( new Rectangle(Point.Empty, new Size((int)_state.ImageSize.X, (int)_state.ImageSize.Y)), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); int size = raw.Height * raw.Stride; webcam.QueryFrameResponse response = new webcam.QueryFrameResponse(); response.TimeStamp = _state.LastFrameUpdate; response.Frame = new byte[size]; response.Size = new Size(raw.Width, raw.Height); response.Format = Guid.Empty; System.Runtime.InteropServices.Marshal.Copy(raw.Scan0, response.Frame, 0, size); queryFrame.ResponsePort.Post(response); } finally { if (raw != null) { _state.Frame.UnlockBits(raw); } } } else { ImageFormat format = new ImageFormat(queryFrame.Body.Format); using (MemoryStream stream = new MemoryStream()) { Size size = new Size((int)queryFrame.Body.Size.X, (int)queryFrame.Body.Size.Y); if (size == _state.Frame.Size || size.Width == 0 || size.Height == 0 || size.Width >= _state.Frame.Width || size.Height >= _state.Frame.Height) { size = _state.Frame.Size; _state.Frame.Save(stream, format); } else { using (Bitmap temp = new Bitmap(_state.Frame, size)) { temp.Save(stream, format); } } webcam.QueryFrameResponse response = new webcam.QueryFrameResponse(); response.TimeStamp = _state.LastFrameUpdate; response.Frame = new byte[(int)stream.Length]; response.Size = size; response.Format = format.Guid; stream.Position = 0; stream.Read(response.Frame, 0, response.Frame.Length); queryFrame.ResponsePort.Post(response); } } }
public IEnumerator <ITask> OnHttpPost(HttpPost httpPost) { HttpListenerContext context = httpPost.Body.Context; NameValueCollection parameters = null; Fault fault = null; try { ReadFormData readForm = new ReadFormData(httpPost); _utilitiesPort.Post(readForm); yield return(Arbiter.Choice( readForm.ResultPort, delegate(NameValueCollection success) { parameters = success; }, delegate(Exception e) { LogError("Error reading form data", e); fault = Fault.FromException(e); } )); if (fault != null) { yield break; } string name = string.Empty; string deleteName = null; string expandName = null; int left = 0; int top = 0; int width = 0; int height = 0; int deleteY = 0; int deleteCb = 0; int deleteCr = 0; double threshold = 1.0; int minBlobSize = 0; bool showPartial = false; bool despeckle = false; bool updateSettings = false; bool save = false; foreach (string key in parameters.Keys) { if (key.StartsWith("Delete.")) { string[] segments = key.Split('.'); deleteName = segments[1]; deleteY = int.Parse(segments[2]); deleteCb = int.Parse(segments[3]); deleteCr = int.Parse(segments[4]); } else if (key.StartsWith("ExpandY.")) { string[] segments = key.Split('.'); expandName = segments[1]; deleteY = int.Parse(segments[2]); deleteCb = int.Parse(segments[3]); deleteCr = int.Parse(segments[4]); } else { switch (key) { case "Save": save = true; break; case "Threshold": threshold = double.Parse(parameters[key]); break; case "ShowPartial": showPartial = parameters[key] == "on"; break; case "Despeckle": despeckle = parameters[key] == "on"; break; case "UpdateSettings": updateSettings = true; break; case "MinBlobSize": minBlobSize = int.Parse(parameters[key]); break; case "New.Left": left = int.Parse(parameters[key]); break; case "New.Top": top = int.Parse(parameters[key]); break; case "New.Width": width = int.Parse(parameters[key]); break; case "New.Height": height = int.Parse(parameters[key]); break; case "New.Name": name = parameters[key].Trim(); break; default: break; } } } if (save) { yield return(Arbiter.Choice( SaveState(_state.SmallCopy), EmptyHandler, EmptyHandler )); } else if (!string.IsNullOrEmpty(deleteName)) { ColorDefinition definition = new ColorDefinition(deleteName, deleteY, deleteCb, deleteCr); RemoveColorDefinition remove = new RemoveColorDefinition(definition); OnRemoveColorDefinition(remove); } else if (!string.IsNullOrEmpty(expandName)) { ColorDefinition definition = new ColorDefinition(expandName, deleteY, deleteCb, deleteCr); ColorSet set = _state.Colors.Find(definition.Compare); if (set != null) { ColorDefinition existing = set.Colors.Find(definition.CompareColor); definition.SigmaCb = existing.SigmaCb; definition.SigmaCr = existing.SigmaCr; if (existing.SigmaY < 1) { definition.SigmaY = 2; } else { definition.SigmaY = 3 * existing.SigmaY / 2; } } UpdateColorDefinition update = new UpdateColorDefinition(definition); OnUpdateColorDefinition(update); } else if (updateSettings) { UpdateSettings update = new UpdateSettings( new Settings( threshold, showPartial, despeckle, minBlobSize ) ); OnUpdateSettings(update); } else { webcam.QueryFrameResponse response = null; yield return(Arbiter.Choice( _webcamPort.QueryFrame(), delegate(webcam.QueryFrameResponse success) { response = success; }, delegate(Fault failure) { LogError("Unable to query frame for update", failure); } )); if (response == null) { yield break; } int right = left + width; int bottom = top + height; byte[] data = response.Frame; int stride = data.Length / response.Size.Height; int rowOffset = left * 3; int offset; int r, g, b; int[] yProjection = new int[256]; int[] cbProjection = new int[256]; int[] crProjection = new int[256]; int count = 0; double yMean = 0; double cbMean = 0; double crMean = 0; for (int y = top; y < bottom; y++) { offset = rowOffset + y * stride; for (int x = left; x < right; x++) { b = data[offset++]; g = data[offset++]; r = data[offset++]; ColorDefinition pixel = new ColorDefinition(r, g, b, "pixel"); yProjection[pixel.Y]++; cbProjection[pixel.Cb]++; crProjection[pixel.Cr]++; count++; yMean += pixel.Y; cbMean += pixel.Cb; crMean += pixel.Cr; } } if (count <= 16) { LogError("The area was too small to generalize a color"); yield break; } yMean /= count; cbMean /= count; crMean /= count; double ySigma = CalculateStdDev(yMean, yProjection, count); double cbSigma = CalculateStdDev(cbMean, cbProjection, count); double crSigma = CalculateStdDev(crMean, crProjection, count); ColorDefinition definition = new ColorDefinition( name, (int)Math.Round(yMean), (int)Math.Round(cbMean), (int)Math.Round(crMean) ); definition.SigmaY = (int)Math.Max(1, Math.Round(2 * ySigma)); definition.SigmaCb = (int)Math.Max(1, Math.Round(2 * cbSigma)); definition.SigmaCr = (int)Math.Max(1, Math.Round(2 * crSigma)); if (!string.IsNullOrEmpty(expandName)) { definition.Name = expandName; UpdateColorDefinition update = new UpdateColorDefinition(definition); OnUpdateColorDefinition(update); } else { AddColorDefinition add = new AddColorDefinition(definition); OnAddColorDefinition(add); } } } finally { httpPost.ResponsePort.Post(new HttpResponseType(HttpStatusCode.OK, _state.SmallCopy, _transform)); } }
IEnumerator <ITask> DoVisionProcessing(VisionProcessingParameters parameters) { try { List <ColorSet> colors = parameters.Colors; Settings settings = parameters.Settings; int[] colorSetMap = parameters.ColorSetMap; webcam.QueryFrameResponse response = null; yield return(Arbiter.Choice( _webcamPort.QueryFrame(), delegate(webcam.QueryFrameResponse success) { response = success; }, LogError )); if (response == null) { yield break; } double threshold = settings.Threshold; int height = response.Size.Height; int width = response.Size.Width; int offset; int stride = response.Frame.Length / height; byte[] bytes = response.Frame; byte[,] indexed = new byte[width, height]; int segOffset; int segStride = width; byte[] segmented = new byte[width * height]; for (int y = 0; y < height; y++) { offset = stride * y; segOffset = segStride * y; for (int x = 0; x < width; x++) { int blu = bytes[offset++]; int grn = bytes[offset++]; int red = bytes[offset++]; int col = (((red + 7) & 0xF0) << 4) | ((grn + 7) & 0xF0) | (((blu + 7) & 0xF0) >> 4); int bestIndex = colorSetMap[col]; indexed[x, y] = (byte)bestIndex; segmented[segOffset++] = (byte)bestIndex; } } if (settings.Despeckle) { int[] votes; byte[,] despeckled = new byte[width, height]; offset = 0; for (int y = 0; y < height; y++) { offset = y * stride; for (int x = 0; x < width; x++, offset++) { votes = new int[colors.Count + 1]; int color; int leader = 0; if (x == 0 || y == 0 || x == width - 1 || y == height - 1) { leader = indexed[x, y]; votes[leader]++; } else { for (int iy = -1; iy < 2; iy++) { for (int ix = -1; ix < 2; ix++) { color = indexed[x + ix, y + iy]; votes[color]++; if (votes[color] > votes[leader]) { leader = color; } } } // // if there is a tie, then use the original color. // int bestVote = votes[leader]; for (int i = 0; i < votes.Length; i++) { if (i != leader && votes[i] == bestVote) { leader = indexed[x, y]; break; } } } despeckled[x, y] = (byte)leader; } } indexed = despeckled; } List <ColorArea> areas = new List <ColorArea>(); byte[,] copy = (byte[, ])indexed.Clone(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int curr = copy[x, y]; if (curr != 0) { ColorArea area = new ColorArea(colors[curr - 1].Name); area.Flood(copy, x, y); areas.Add(area); } } } areas = areas.FindAll( delegate(ColorArea test) { return(test.Area >= settings.MinBlobSize); } ); areas.Sort( delegate(ColorArea left, ColorArea right) { return(-left.Area.CompareTo(right.Area)); } ); Color[] outputColors = new Color[colors.Count + 1]; for (int i = 0; i < outputColors.Length; i++) { if (i == 0) { outputColors[i] = Color.Black; } else { ColorSet set = colors[i - 1]; ColorDefinition def = set.Colors[0]; outputColors[i] = Color.FromArgb(def.R, def.G, def.B); } } for (int y = 0; y < height; y++) { offset = y * stride; segOffset = y * segStride; for (int x = 0; x < width; x++) { int palIndex = segmented[segOffset++]; Color pixel = outputColors[palIndex]; bytes[offset++] = (byte)pixel.B; bytes[offset++] = (byte)pixel.G; bytes[offset++] = (byte)pixel.R; } } segmented = bytes; SegmentedImage image = new SegmentedImage(response.TimeStamp, width, height, segmented, indexed); _mainPort.Post(new UpdateSegmentedImage(image)); FoundColorAreas foundColors = new FoundColorAreas(); foundColors.TimeStamp = response.TimeStamp; foreach (ColorArea area in areas) { if (area.Area > 0) { area.Complete(); foundColors.Areas.Add(area); } } _fwdPort.Post(new UpdateColorAreas(foundColors)); } finally { _fwdPort.Post(new ProcessFrame(false)); } }
IEnumerator <ITask> DoCameraUpdateFrameHandler(cam.UpdateFrame update) { try { cam.QueryFrameResponse frame = null; Fault fault = null; yield return(Arbiter.Choice( _webCamPort.QueryFrame(new cam.QueryFrameRequest()), delegate(cam.QueryFrameResponse success) { frame = success; }, delegate(Fault f) { fault = f; } )); if (fault != null) { LogError(null, "Failed to get frame from camera", fault); yield break; } Bitmap bmp = new Bitmap( frame.Size.Width, frame.Size.Height, PixelFormat.Format24bppRgb ); BitmapData data = bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb ); Marshal.Copy(frame.Frame, 0, data.Scan0, frame.Frame.Length); bmp.UnlockBits(data); FormInvoke setImage = new FormInvoke( delegate() { if (!_form.IsDisposed) { _form.CameraImage = bmp; } } ); WinFormsServicePort.Post(setImage); Arbiter.Choice( setImage.ResultPort, delegate(EmptyValue success) { }, delegate(Exception e) { fault = Fault.FromException(e); } ); if (fault != null) { LogError(null, "Unable to set camera image on form", fault); yield break; } } finally { _mainPort.Post(new UpdateProcessing(false)); } }