Algorytm redukcji efektu czerwonych oczu.

0

Witam,
Posiedziałem trochę w necie lecz trudno było mi znaleźć coś interesującego. Tj na pewno coś da się znaleźć tylko, że mi sie to nie udało :)
Interesuje mnie algorytm redukcji efektu czerwonych oczu. Oczywiście nie chodzi mi o wielokrotne błyskanie lampą w aparacie fotograficznym by źrenice się <ort>zwęrzyły </ort>ani o programy komputerowe, które wymagają by pokazać im gdzie jest oko :)
Chodzi o algorytm, który jest w stanie sam zlokalizować "czerwone oko" - chodzi mi właśnie o te zagadnienie lokalizacji.
Taki coś w działaniu widać na przykład w programie IrfanView -> effects -> red eye reduction. Choć w ich wykonaniu nie jest to idealne, ale cóż...
Oczywiście nie jest to taki proste by znaldować obszary o dostatecznej zawartości czerwonej składowej bo w takim przypadku "zredukowalibysmy" komuś na zdjęciu np. czerwoną kurtkę :D a nie o to chodzi.
To jest jakieś szukanie gwałtownych przejść tonalnych albo coś w tym stylu. Byłbym wsziędzny za podsuwanie jakichś sugestii albo materiałów.
Z góry dziękuję i pozdrawiam

0

hmm oczy sa okragle, mozesz dac pewien zakres tolerancji barwy i promienia oka, wtedy szukasz pixeli w danym przedziale barwnym ustalasz punkty graniczne np: za pomoca algorytmu wyznaczania otoczki i puzniej wyznaczasz srodek i sprawdzasz czy kazdy punkt mniejwiecej jest w takiej samej odleglosci od srodka czyli czy to okrag (elipsa) czy kurtka :P

0

w delphi to na te okragle rzeczy: wziete z noxx_math i tnoxxpowerdraw

type tpowerRGBTRIPLE=record
r : byte;
g : byte;
b : byte;
end;

function scancircleaverageRGB(bmp :tbitmap; x,y, radius : integer)    : tpowerRGBTRIPLE;
var
Rarray : array of single;
Garray : array of single;
Barray : array of single;
i : integer;
n : integer;
angle : integer;
begin
n := 0;
for i           :=0 to radius   do
for angle       :=0 to 359      do
n := n + 1;
setlength(Rarray,n);//round(noxx_math.pi*radius*radius));
setlength(Garray,n);
setlength(Barray,n);
n := -1;
for i           :=0 to radius   do
for angle       :=0 to 359      do
begin
n := n + 1;
Rarray[n] := scangetrvalue(bmp,round(x+radius*sin(angle*imopi)),round(y+radius*sin(angle*imopi)));
Garray[n] := scangetgvalue(bmp,round(x+radius*sin(angle*imopi)),round(y+radius*sin(angle*imopi)));
Barray[n] := scangetbvalue(bmp,round(x+radius*sin(angle*imopi)),round(y+radius*sin(angle*imopi)));
end;
result.r := round(average(Rarray));
result.g := round(average(Garray));
result.b := round(average(Barray));
end;

function scangetrvalue(bmp :tbitmap;x,y :integer) : byte;
var
  P : PByteArray;
 u : integer;
begin
u := x*3;
with bmp do
begin
P:=ScanLine[y];
result := P[u+2];
exit;
end;
result := 0;
end;

function scangetgvalue(bmp :tbitmap;x,y :integer) : byte;
var
  P : PByteArray;
 u : integer;
begin
u := x*3;
with bmp do
begin
P:=ScanLine[y];
result := P[u+1];
exit;
end;
result := 0;
end;

function scangetbvalue(bmp :tbitmap;x,y :integer) : byte;
var
  P : PByteArray;
 u : integer;
begin
u := x*3;
with bmp do
begin
P:=ScanLine[y];
result := P[u];
exit;
end;
result := 0;
end;

function average(an : array of single) : single;
begin
result := sum(an)/length(an);
end;

function sum(an : array of single) : single;
var
i : integer;
begin
result := 0;
for i:=0 to high(an) do
result := result + an[i];    //that's not a duration

end;
0

wiem, że to banalne pytanie i powinienm się wstydzić Ale jak ocenic czy dany kolor to mniej więcej czerwony? Mam programik pozwalający na "wycinanie" z fotki obszarów o natęrzeniu składowyc R G B mieszczących się w podanych prze mnie widełkach. Ale trudno mi tak dobrać by zostawił tylko to co jest czerwone. Bo w końcu każdy kolor składa się z czerwonej składowej. Mam zdjęcie linii lasera na fotce. Gdy sprawdzam kolor danego piksela z tej linii powiedzmy R:170 G:81 B:19 i daję temu programowi by pozostawił wszystko o takiej barwie z tolerancją do +/-10 to i tak wycina mi kawałek tej linii lasera. W dodatku ze względu na niską jakość matrycy CCD linia lasera w środku nie jest czerwona a biała co dodatkowo utrudnia sprawę.

0

rgb czerwony zielony niebieski jak dla jednego pikjsela r wyosi 100 a dal drugiego 200 to ten drugi jest bardziej czerwony niz ten drugi dalej nie pokumalem ;o!
rozkmina DDD:D

0

To nie jest takie proste jak sądzisz...
Jak coś ma R=200 to jest bardziej czerwone niż coś o R=100 Twoim zdaniem, heh.
Czyli R,G,B: 250,250,250 jest bardziej czerwone niż 170,81,19 - jesteś pewien, bo ja nie :D

0

TAKIE SA FAKTY D:D

0

Fakt :)
Czerwonego jest wiecej, ale my widzimy takze inne barwy, jakbys popatrzyl przez czerwony filtr to bys to widzial jako bardziej/mniej czerwone :)

Co do problemu..
Moglbys sprawdzac stosunek jednego do drugiego.. R/G, R/B i sprawdzic czy znajduje sie w ustaolnym przez CIebie przedziale, i przy okazji sprawdzac czy wartosc R znajduje sie w podanym przedziale.

0

Ma więcej składowej czerwonej to nie znaczy, że jest bardziej czerwone. Gdyby patrzeć przez czerwony filtr to racja - wydawałoby się bardziej czerwone. No ale przepraszam to zakrawa o żartowanie sobie.
Odnośnie określenia co jest rzeczywiście bardziej czerwone a nie o większym nasyceniu składowej czerwonej to zastosowałem po prostu r-((g+b) div 2) jeśli da wartość ujemną to trzeba zastąpić ją przez 0.

1 użytkowników online, w tym zalogowanych: 0, gości: 1