Witam
Potrzebuje napisać programik który pozwoli mi porównać 2 zdjęcia, a dokładnie taka sytuacja:
mam zdjęcie wzorcowe pewnego elementu program przechwytuje obraz z kamery i ma porównać czy zdjęcie i wzorzec są podobne.
Czy ktoś może mi poradzić jak się do tego zabrać?
Zmartwię się i napiszę: zakładam, że robisz program wykrywający ruch. Jeśli się mylę, to nie martw się moją wypowiedzią. Nawet przy braku ruchu, dwa zdjęcia z kamery, zwłaszcza prostej, do komunikacji w internecie są różne. Musiałbyś obliczać ile procent się zmieniło i powyżej ustalonej granicy rozpoczynać wykonanie jakiejś funkcji.
decus: a w jakim stopniu opanowałeś Delphi/Pascala?
http://pdiff.sourceforge.net/, korelacja obrazków (http://en.wikipedia.org/wiki/Digital_image_correlation)
możesz też samemu napisać algorytm, mniej elastyczny, więc mniej skuteczny, ale fajniejsza zabawa - przetworzyć obrazki do odcieni szarości, pozbyć się szumu i szczegółów (np. rozsądnie* szeroką medianą), ewentualnie zmniejszyć oba obrazki (może być zamiast mediany), następnie
- odjąć je od siebie, policzyć różniące się piksele, jeśli ich liczba przekracza jakiś procent wszystkich pikseli, to uznać, że obrazki się różnią, lub
- wygenerować (rozsądnie* szerokie) krawędzie (np. przeciągnąć pochodną po całym obrazku) w obu obrazkach i jak wyżej, odjąć od siebie i policzyć % różniących się pikseli, lub
- policzyć współczynnik korelacji obrazków
każde z powyższych wymaga co najmniej dobrej znajomości języka, w którym chcesz dane rozwiązanie zaimplementować, więc zastanów się, czy nie zamachujesz się motyką na słońce...
- rozsądnie oznacza metodą prób i błędów, uzależnioną od rozmiarów obrazków
trzeba wiedziec jak sie rozni jedenobraz od drugiego
nie sposób zaprzeczyć ;-)
A nie wystarczyłoby po prostu robić zrzuty z kamerki co sek.i dany image porównywać z tym image co był zrobiony na początku sposobem
if zdjecie1.Canvas.Pixels[wys,szer] = Temp[T].Canvas.Pixels[wys,szer] then ...
i jeśli dany obraz się znacznie rózni od pierwszego to znaczy ze został wykonany jakiś ruch. No ale to by działało chyba tylko przy jednym oświetleniu bo między dniem a nocą to by się te image różniły:)
lankusiek napisał(a)
A nie wystarczyłoby po prostu robić zrzuty z kamerki co sek.i dany image porównywać z tym image co był zrobiony na początku sposobem
if zdjecie1.Canvas.Pixels[wys,szer] = Temp[T].Canvas.Pixels[wys,szer] then ...
i jeśli dany obraz się znacznie rózni od pierwszego to znaczy ze został wykonany jakiś ruch. No ale to by działało chyba tylko przy jednym oświetleniu bo między dniem a nocą to by się te image różniły:)
Nigdy nie widziałeś obrazów z kamer? To jest dość mocno skompresowany film i jestem pewny, że nawet identyczne obrazki w kolejnych klatkach na pewno by się od siebie różniły. Dodatkowo, należy doliczyć jeszcze ruch Słońca i związany z nim układ cieni, zachmurzenie (jak Słońce "schowa" się za chmurami, to w kilka sekund cały obraz może się zmienić i będziesz miał jakieś 20% ciemniejszą scenerię).
To jest dość mocno skompresowany film i jestem pewny, że nawet identyczne obrazki w kolejnych klatkach na pewno by się od siebie różniły.
Wiem ,że by się różniły ale można dodać jakąś tolerancje. jak znaczącej nie będzie różnicy między obrazkami to nie będzie ruchu.
ŁF przecież napisał o korelacji, więc poczytaj trochę o niej. Współczynnik korelacji to jest właśnie twoja tolerancja.
{
Funkcja, będzie porównywać dwa obrazki w formacie BMP, a następnie zwróci w ilu procentach
są ze sobą identyczne.
Image1 i Image2 to obiekty klasy TImage zawierające obrazy w formacie BMP.
}
function Porownaj(Image1, Image2: TImage) : integer;
var x, y: integer;
liczba: LongInt;
punkt1, punkt2: PByteArray;
procent: double;
const max_roznica=5;
begin
liczba:=0;
for y:=0 to image1.Picture.Bitmap.height-1 do begin
punkt1:=image1.Picture.Bitmap.scanline[y];
punkt2:=image2.Picture.Bitmap.scanline[y];
for x:=0 to image1.Picture.Bitmap.width-1 do
if abs(punkt1[x]-punkt2[x])>max_roznica then
inc(liczba);
if image1.Picture.Bitmap.height*image1.Picture.Bitmap.width>0 then
procent:=100*(liczba/(image1.Picture.Bitmap.height*
image1.Picture.Bitmap.width))
else
procent:=0;
Result := 100-round(procent);
end;
end;
{Wywołanie}
Label1.Caption:= 'Podobieństwo w '+ IntToStr(Porownaj(Image1,Image2))+' procentach';
@Opis - to bardzo naiwny algorytm. wystarczy, że przeciętnie kontrastowe obrazki będą przesunięte o 1px i już będziesz mieć okolice 100% różnicy. obrazki należy wcześniej obrobić (tak jak napisałem lub w podobny sposób), lub porównanie zrobić w zupełnie inny sposób.
btw. image1.Picture.Bitmap.height*image1.Picture.Bitmap.width>0 jest zupełnie niepotrzebne, masz dwie pętle for które zapewniają Ci spełnienie tego warunku, zresztą i tak kiedy h=0 i w=0 to wynik zwracany przez funkcję jest niezdefiniowany...