Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: sprawdzenie czy na obrazku znajduje się jakiś okrąg
Forum PHP.pl > Forum > PHP
bialko0019
Witam. W sumie nie wiem czy do dobrego działu dałem temat, ponieważ nie mam pomysłu i jestem otwarty na języki programowania. Mam obrazek. Załóżmy ten:

Założenie jest takie - szukam współrzędnych pozycji okręgu, który może być niedoskonały - czyli tak jak na obrazku troche poszarpane itd, ale jak by nie patrzeć - jest to jakiś okrąg. Kolejną rzeczą jest to, że zawsze kolory obrazka to czarno-biały. Nie mam pomysłu, a chciałbym wykryć współrzędne, gdzie ten okrąg się znajduje. Ma ktoś jakikolwiek pomysł? ;-) Jestem otwarty na propozycje ;-)
Daimos
Jeśli zawsze jest jeden okrąg i jakieś śmieci dookoła to problemu większego nie ma.
Szukasz największego skupiska koloru białego, następnie rysujesz poziomą kreskę przez cały okrąg (czyli tylko po białych pikselach), obracasz ją o 360stopni (stopniowo, co kilka, z uwagą, aby poruszać się tylko po białym) i wiadomo, że najdłuższa linia będzie Twoim okręgiem. Środek wtedy też masz.
Jak będą też inne figury, to może myć problem, ale obracając tak linię, możesz już stwierdzić, czy to okrąg.

Tak na szybko, nie bawiłem się nigdy w zaawansowane rozpoznawanie grafik, ale na logikę, to powinno działać wink.gif
bialko0019
No jasne, dzięki tylko podpowiedzcie mi, jeśli zacznę sprawdzać skupiska białych kropek jadąc pętlą każdy piksel i sprawdzając skupiska ktorych powiekższa jest większa niż kilkadziesiąt pikseli to będzie to wydajne ? Chyba, że jakoś inaczej można by podejść ? Sprawdzać np. tylko środek obrazka bo tam będzie ta kropka ;-P

Chciałbym by było to bardzo wydajne bo ten obrazek to jedna klatka z filmu ;-) Może
acidm
Ja bym poruszał się po liniach siatki w poszukiwaniu koła.Grubość sita mniejsza od koła którego szukasz.Gdy znajdziesz dany fragment analizujesz go dokladniej.Ale nie wiem czy analizowanie klatek filmu w locie w php jest dobrym pomysłem ,w tej kwestii się nie wypowiadam.
bialko0019
W życiu, w php`ie ;-) Można by ajax`em ale jak jest np. 20 klatek na sekunde to php tego nie przemieli ;-) Tzn będzie się ciąć wink.gif Temat jest w tym dziale bo nie wiem czego użyć najlepiej ;-) Myślałem bardziej o javascripcie, hmm myslisz zeby zrobić grubą siatkę i sprawdzać ? ;-p
acidm
Linie siatki cienkie ale w odstępach od siebie minimalnie mniejszych od średnicy tego koła czyli maksymalnie dużych ale na tyle małych żeby wychwyciły koło.W sektorach gdzie wykryjesz piksele analiza siatką o większej ilości oczek, tak żeby sprawdzania było mniej niż piksel po pikselu.
bialko0019
Już prawie, prawie. Zrobiłem sobie taki schemat

A więc mam siatkę. Znajduje które kwadraty są zapełnione w np. 45%. To trzeba było by wyliczyć metodą prób i błędów. To są zaznaczone na zółto.
Następnie w każdym z nich znajduje najdalej wychylone punkty, i w ten sposób rysuję wielokąt. ( czerwony ).
Następnie rysuję w nim koło i środek tego koła to w przybliżeniu położenie środka docelowego białego kółka ;-)

W sumie bardzo mi się podoba, przełożę to na kod i dam znać. Jednak mam problem - można narysować okrąg na wielokącie ( wypukłym ) mając wpsółrzędne wierzchołków tego wielokąta, oraz jaki to jest wielokąt ( 5kąt, 6kąt itd ) questionmark.gif ;-))
acidm
Optymalizujemy szukanie grupy pikseli :
-sprawdzamy po liniach pionowych siatki , gdy znajdujemy grupę w jednej linii szukamy w linii obok , jak mamy w linii drugiej przechodzimy do sprawdzania poziomego
-sprawdzamy linie poziome ale tylko w okolicach linii pionowych gdzie są już wykryte piksele
- mamy już sektory które należą do naszej grupy pikseli więc sprawdzamy sąsiednie sektory czy nie są połączone z naszą grupą jak tak dodajemy do zbioru
-na naszym zbiorze możemy już operować pod kątem okręgu, wyliczamy środek bierzemy najkrótszy promień kreślimy koło i porównujemy ilość pikseli w kole czy jest duża jak tak to kreślimy drugi okrąg poza naszym kołem (najdłuższy promień +30%) i sprawdzamy czy tam nie ma pikseli z naszego kola jak nie ma albo jest mało to jest ok


-po liniach siatki nie musimy poruszać w sposób ciągły , można co jakiś odcinek , w przypadku wykrycia pikseli zwiększamy częstotliwość sprawdzania w pobliżu znalezionych pikseli ( łącznych detekcji będzie wtedy mniej)
Daimos
A ja bym dalej skupił się na szukaniu najdłuższych odcinków, mając już Twoją siatkę, znajdziesz "mniej więcej" okrąg i rysujesz na nim kreski, jak tutaj:



Te żółte linie można stopniowo bardziej zagęszczać, w momencie kiedy robią się dłuższe. Dzięki temu, kiedy znajdziesz najdłuższe odcinki, to będą Twoje wyznaczniki środka okręgu.

-- edit

W sumie można jeszcze bardziej optymalnie sprawdzać:

1. Zamiast siatki, sprawdzasz piksele co np. 50px (zakładając, że okrąg jest zawsze większy). Dzięki temu otrzymujesz siatkę w formie kropek, przynajmniej +90% do wydajności. Sprawdzanie odbywa się np. od lewej do prawej i później przeskok do nowego wiersza,
2. W momencie kiedy znajdziesz biały piksel, to rysujesz linię pomocniczą szukając kolejnych białych,
3. Udało się narysować linię pomocniczą, więc idziesz np. 3px w dół i znowu rysujesz linię pomocniczą po białych px, aż do skutku, kierując się tym co napisałem na samej górze,
4. wybierasz kilka najdłuższych lini pomocniczych i rysujesz na nich pionowe, w pobliżu środka,
5. koniec, najdłuższe linie wyznaczą Ci środek i wielkość

Można kombinować i kombinować, ale nie wiem czy javascript tutaj też się nada. Chyba, że nie zależy Ci na szybkości działania, wtedy jak najbardziej javascript i robić odstępy na rysowanie.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.