Witam wszystkim na wstępie mojego pierwszego posta na forum. Jestem w trakcie pisania aplikacji, która potrafi wykryć poszczególne obiekty na obrazie pobieranym na bieżąco z kamery na podstawie analizy ich kształtów. Gdy obiekt zostanie wykryty, program obrysowuje jego kontury na zdjęciu. Skupić muszę się na detekcji "strzałek" i okręgów. Udało mi się już dotrzeć do momentu, w którym po zastosowaniu kilku filtrów przetwarzających obraz jestem w stanie wykryć trójkąty (groty "strzałek" i okręgi na obrazie). Problem w tym, że kamera, z której pobierany jest obraz nie zawsze będzie na dany obiekt patrzyła pod kątem prostym. W przypadku trójkątów nie jest to problem, bo wciąż widać trójkąt jedynie z innymi wartościami kątów w nim zawartych, co innego z okręgami - obserwowanie ich pod innym kątem da mi obraz różnego rodzaju elips, które też powinny być wykryte, jednak nie potrafię rozgryźć jak to zrobić. Zamieszczę kluczowe fragmenty kodu mojej aplikacji, żeby wyjaśnić jak ona działa.

 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge;
using AForge.Video.DirectShow;
using AForge.Imaging.Filters;
using AForge.Math.Random;
using AForge.Imaging;
using AForge.Math.Geometry;

Pobieram obraz kamery, konwertuję go do Bitmapy, którą po przeskalowaniu poddaje wstępnej obróbce prostym filtrem w celu wyeliminowania tła.

 void cam_NewFrame(object sender, AForge.Video.NewFrameEventArgs EventArgs)
        {
            Bitmap sourceImage = (Bitmap)EventArgs.Frame.Clone();
            
            pictureBox1.Image = ApplyRGBFilter(sourceImage);
        }

Kod "ApplyRGBFilter"

 
 private Bitmap ApplyRGBFilter(Bitmap sourceImage)
        {
            ResizeBilinear filter2 = new ResizeBilinear(450,338);
            Bitmap sourceImageRS = filter2.Apply(sourceImage);
            ColorFiltering filter = new ColorFiltering();
            filter.Red = new IntRange(0, 64);
            filter.Green = new IntRange(0, 64);
            filter.Blue = new IntRange(0, 64);
            Bitmap processedImage = filter.Apply(sourceImageRS);
            


//W którym to, po "odhaczeniu" odpowiedniego CheckBoxa realizuje się funkcja odnalezienia okręgów i zaznaczenia ich na obrazie: 

if (checkBox6.Checked)
            {
                
                SimpleShapeChecker ShapeChecker = new SimpleShapeChecker();
                BlobCounter blobCounter = new BlobCounter();
                blobCounter.ProcessImage(processedImage);
                Blob[] blobs = blobCounter.GetObjectsInformation();
                Graphics g = Graphics.FromImage(processedImage);
                Pen redPen = new Pen(Color.Red, 2);
               
                
                {
                    for (int i = 0, n = blobs.Length; i < n; i++)
                    {
                        List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);

                        DoublePoint center;
                        double radius;

                        if (ShapeChecker.IsCircle(edgePoints, out center, out radius))
                        {
                            g.DrawEllipse(redPen,
                                (int)(center.X - radius),
                                (int)(center.Y - radius),
                                (int)(radius * 2),
                                (int)(radius * 2));
                        }
                    }
                }

                redPen.Dispose();
                g.Dispose();
//analogiczny if z trójkatami
            }
return processedImage;

Okręgi rozpoznawane są dobrze, program obrysowuje ich kontury czerwonym kolorem, jednak wystarczy minimalne odchylenie kamery od obiektu (planszy ze znakami) i nie jest rozpoznawany już żaden owalny obiekt. Tak jak pisałem, z trójkątami tego problemu nie ma (wciąż pozostają trójkątami po odchyleniu). Czy ktoś ma pomysł, jak powyższy kod przekształcić tak, aby można było zidentyfikować na obrazie także elipsy? Nie jestem żadnym specem od programowania, w znacznej mierze opieram się na wszystkim, co znalazłem w sieci, czego rezultatem jest podany kod, jednak jeśli chodzi o problem, ciężko cokolwiek praktycznego znaleźć.