Z punktu widzenia wizji komputerowej, środek masy obiektu może być wykorzystywany do opisu cech klasyfikowanego obiektu. Samo jego położenie nie jest może szczególnie istotne, ale jego położenie względem innych kluczowych (charakterystycznych) punktów obiektu może już być decydujące w procesie klasyfikacji.
Prostym przykładem może być wykrywanie gestów dłoni - jeśli na obrazie zostaną wykryte punkty końców palców, a także środek masy dłoni, to wzajemne położenie końcówek palców względem środka masy może już w jakiś sposób opisywać ułożenie dłoni.
Rozważmy poniższy obrazek:
Obiekt O na obrazie I
Mamy tutaj obiekt O, umiejscowiony na obrazie I. Możemy sobie wyobrazić, że obiekt ten został wyznaczony po procesie segmentacji.
Jeśli obraz I zawiera obiekt O, przy czym obraz opisany jest za pomocą współrzędnych kartezjańskich (x,y), gdzie (x,y) należy do I, to możemy zdefiniować funkcję b charakteryzującą obiekt O:
Pole powierzchni Po obiektu O określa równanie:
Środek masy obiektu natomiast dany jest wzorem:
gdzie:
Ponieważ obraz komputerowy jest obrazem dyskretnym o skończonej rozdzielczości, operacja całkowania upraszcza się do operacji sumowania.
Implementacja obliczeń w języku C# z wykorzystaniem biblioteki EmguCV może wyglądać tak:
Code Snippet
- int b(int x, int y, Image<Gray, byte> img)
- {
- return img.Data[y, x, 0] == 0 ? 0 : 1;
- }
- int Area(Image<Gray, byte> img)
- {
- int d = 0;
- for (int y = 0; y < img.Height; y++)
- for (int x = 0; x < img.Width; x++)
- d += b(x, y, img);
- return d;
- }
- void CalculateMassCentre(Image<Gray, byte> img, out int x0, out int y0)
- {
- int area = Area(img);
- x0 = y0 = 0;
- for (int y = 0; y < img.Height; y++)
- for (int x = 0; x < img.Width; x++)
- {
- x0 += x * b(x, y, img);
- y0 += y * b(x, y, img);
- }
- x0 = x0 / area;
- y0 = y0 / area;
- }
i samo wywołanie:
Poniżej wyniki:
Code Snippet
- Bitmap bmp = new Bitmap(fileIn);
- Image<Bgra, byte> image = new Image<Bgra, byte>(bmp);
- Image<Gray, byte> gray = new Image<Gray, byte>(bmp.Size);
- gray.ConvertFrom<Bgra, byte>(image);
- int x0, y0;
- CalculateMassCentre(gray, out x0, out y0);
- image.Draw(new CircleF(new PointF(x0, y0), 5), new Bgra(0, 0, 255, 255), 4);
- CvInvoke.cvShowImage(fileIn, image.Ptr);
- CvInvoke.cvWaitKey(0);
- CvInvoke.cvDestroyWindow(fileIn);
Poniżej wyniki:
Prostokąt
Prostokąt z wyznaczonym środkiem masy
Otwarta dłoń
Otwarta dłoń z wyznaczonym środkiem masy
Dłoń w geście OK
Dłoń w geście ok z wyznaczonym środkiem masy













0 komentarze:
Prześlij komentarz