Język: C# z biblioteką EmguCV.
Cześć, mam problem nad którym już bardzo długo siedzę. Wydaje się proste - chodzi o to, aby z wgranego obrazu wysegmentować (zaznaczyć) obszary z wklęsłymi elementami - np. litera C itd.
Mam już oczywiście zakodowane wgrywanie obrazu:
Image<Bgr, byte> imageInput; // Obraz źródłowy
// Otwieranie obrazu
public void fileTopMenuOption__Open_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
imageInput = new Image<Bgr, byte>(dialog.FileName);
pictureBoxNew.Image = imageInput.Bitmap;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Co do samego przetwarzania segmentacji - udało mi się jakoś dać kod, który daje radę ze znajdowaniem tekstu na obrazie, ale chyba trochę podszedłem do tego od złej strony... Chciałem najpierw znaleźć litery, a potem po szczegółowym filtrze znaleźć te o wklęsłych kształtach. Daje jakby co kod z tego, jakby komuś mogło pomóc, ale sam nie jestem co do tego przekonany:
Image<Gray, byte> sobel = imageInput.Convert<Gray, byte>().Sobel(1, 1, 3).AbsDiff(new Gray(0.0)).Convert<Gray, byte>().ThresholdBinary(new Gray(50), new Gray(255));
Mat SE = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, new Size(10, 2), new Point(-1, -1));
sobel = sobel.MorphologyEx(Emgu.CV.CvEnum.MorphOp.Dilate, SE, new Point(-1, -1), 1, Emgu.CV.CvEnum.BorderType.Reflect, new MCvScalar(255));
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
Mat m = new Mat();
CvInvoke.FindContours(sobel, contours, m, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
List<Rectangle> list = new List<Rectangle>();
for (int i = 0; i < contours.Size; i++)
{
Rectangle brect = CvInvoke.BoundingRectangle(contours[i]);
double ar = brect.Width / brect.Height;
if (ar > 2 && brect.Width > 15 && brect.Height > 8 && brect.Height < 100)
{
list.Add(brect);
}
}
Image<Bgr, byte> imgout = imageInput.CopyBlank();
foreach (var r in list)
{
CvInvoke.Rectangle(imageInput, r, new MCvScalar(0, 0, 255), 2);
CvInvoke.Rectangle(imgout, r, new MCvScalar(0, 255, 255), -1);
}
imgout._And(imageInput);
pictureBoxNew.Image = imageInput.Bitmap;
pictureBoxResult.Image = imgout.Bitmap;
To teraz powiem o czym myślałem od początku:
- przekonwertować obraz na binarny (no z tym daję radę :))
- znaleźć wszystkie krawędzie (detekcja)
- znaleźć elementy o pasujących kształtach i je wyszczególnić
Zadanie jest bardzo trudne, więc jak ktoś pomoże to będzie po prostu bogiem! Dziękuję! :D