예제 #1
0
        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));
            }
        }
예제 #2
0
 public UpdateColorAreas(FoundColorAreas body)
     : base(body)
 {
 }