Witam.
Napisałem (na bazie tego: http://www.algorytm.org/przetwarzanie-obrazow/filtrowanie-obrazow.html ) prosty algorytm do filtrowania obrazu (high pass, low pass itd). Problem w tym, że... nie działa ;(.
Teoria jest taka (przynajmniej ja tak to rozumiem z powyżej zalinkowanego artykułu):
Dzielimy cały obrazek na bloki o wymiarach 3x3 pixeli. Potem modyfikujemy środkowy pixel w każdym bloku (czyli o współrzędnych 2,2) w taki sposób, że:
- Mnożymy wszystkie pixele w danym bloku przez ich indywidualną maskę.
- Sumujemy wszystkie wyniki.
- Otrzymaną w ten sposób liczbę dzielimy przez sumę maski.
Mój kod:
- Konwertuje obrazek do formatu 24 bitowego BMP.
BMP:=TBitmap.Create;
BMP.Assign(IMG.Picture.Graphic);
BMP.PixelFormat:=PF24BIT;
- Ustalam wartość maski dla poszczególnych pixeli w bloku 3x3:
Mask[1,1]:=-1; Mask[2,1]:=-1; Mask[3,1]:=-1;
Mask[1,2]:=-1; Mask[2,2]:=9; Mask[3,2]:=-1;
Mask[1,3]:=-1; Mask[2,3]:=-1; Mask[3,3]:=-1;
MaskSum:=
(Mask[1,1] + Mask[2,1] + Mask[3,1] +
Mask[1,2] + Mask[2,2] + Mask[3,2] +
Mask[1,3] + Mask[2,3] + Mask[3,3]);
- Przelatuje cały obrazek odczytując kolejne bloki po 3x3 pixeli:
for Y:=1 to BMP.Height-2 do
begin
{LINIA GÓRNA}
Pixel[1,1]:=BMP.ScanLine[Y-1];
Pixel[2,1]:=BMP.ScanLine[Y-1];
Pixel[3,1]:=BMP.ScanLine[Y-1];
{LINIA ŚRODKOWA}
Pixel[1,2]:=BMP.ScanLine[Y];
Pixel[2,2]:=BMP.ScanLine[Y];
Pixel[3,2]:=BMP.ScanLine[Y];
{LINIA DOLNA}
Pixel[1,3]:=BMP.ScanLine[Y+1];
Pixel[2,3]:=BMP.ScanLine[Y+1];
Pixel[3,3]:=BMP.ScanLine[Y+1];
Inc(Pixel[2,1],1);
Inc(Pixel[2,2],1);
Inc(Pixel[2,3],1);
Inc(Pixel[3,1],2);
Inc(Pixel[3,2],2);
Inc(Pixel[3,3],2);
- Dla każdego bloku (a konkretnie środkowego pixela w takim bloku) wykonuje operację:
for X:=1 to BMP.Width-2 do
begin
RSum:=
((Pixel[1,1].rgbtRed * Mask[1,1]) + (Pixel[2,1].rgbtRed * Mask[2,1]) + (Pixel[3,1].rgbtRed * Mask[3,1]) +
(Pixel[1,2].rgbtRed * Mask[1,2]) + (Pixel[2,2].rgbtRed * Mask[2,2]) + (Pixel[3,2].rgbtRed * Mask[3,2]) +
(Pixel[1,3].rgbtRed * Mask[1,3]) + (Pixel[2,3].rgbtRed * Mask[2,3]) + (Pixel[3,3].rgbtRed * Mask[3,3]))
div
MaskSum;
Pixel[2,2].rgbtRed:=(RSum);
GSum:=
((Pixel[1,1].rgbtGreen * Mask[1,1]) + (Pixel[2,1].rgbtGreen * Mask[2,1]) + (Pixel[3,1].rgbtGreen * Mask[3,1]) +
(Pixel[1,2].rgbtGreen * Mask[1,2]) + (Pixel[2,2].rgbtGreen * Mask[2,2]) + (Pixel[3,2].rgbtGreen * Mask[3,2]) +
(Pixel[1,3].rgbtGreen * Mask[1,3]) + (Pixel[2,3].rgbtGreen * Mask[2,3]) + (Pixel[3,3].rgbtGreen * Mask[3,3]))
div
MaskSum;
Pixel[2,2].rgbtGreen:=(GSum);
BSum:=
((Pixel[1,1].rgbtBlue * Mask[1,1]) + (Pixel[2,1].rgbtBlue * Mask[2,1]) + (Pixel[3,1].rgbtBlue * Mask[3,1]) +
(Pixel[1,2].rgbtBlue * Mask[1,2]) + (Pixel[2,2].rgbtBlue * Mask[2,2]) + (Pixel[3,2].rgbtBlue * Mask[3,2]) +
(Pixel[1,3].rgbtBlue * Mask[1,3]) + (Pixel[2,3].rgbtBlue * Mask[2,3]) + (Pixel[3,3].rgbtBlue * Mask[3,3]))
div
MaskSum;
Pixel[2,2].rgbtBlue:=(BSum);
Inc(Pixel[1,1],1);
Inc(Pixel[2,1],1);
Inc(Pixel[3,1],1);
Inc(Pixel[1,2],1);
Inc(Pixel[2,2],1);
Inc(Pixel[3,2],1);
Inc(Pixel[1,3],1);
Inc(Pixel[2,3],1);
Inc(Pixel[3,3],1);
end;
Efekt to niestety masa kolorowych bezładnych kropek (wyglądających jak efekt renderowania "Szum RGB" z gimpa...).
Ktoś może mi pomóc i wskazać co robię źle?
Oto cały kod:
procedure TForm1.Button1Click(Sender: TObject);
var
BMP: TBitmap;
X,Y,MaskSum,RSum,GSum,BSum: Integer;
Pixel: array [1..3, 1..3] of ^RGBTriple;
Mask: array [1..3, 1..3] of Integer;
begin
BMP:=TBitmap.Create;
BMP.Assign(IMG.Picture.Graphic);
BMP.PixelFormat:=PF24BIT;
Mask[1,1]:=-1; Mask[2,1]:=-1; Mask[3,1]:=-1;
Mask[1,2]:=-1; Mask[2,2]:=9; Mask[3,2]:=-1;
Mask[1,3]:=-1; Mask[2,3]:=-1; Mask[3,3]:=-1;
MaskSum:=
(Mask[1,1] + Mask[2,1] + Mask[3,1] +
Mask[1,2] + Mask[2,2] + Mask[3,2] +
Mask[1,3] + Mask[2,3] + Mask[3,3]);
for Y:=1 to BMP.Height-2 do
begin
Pixel[1,1]:=BMP.ScanLine[Y-1];
Pixel[2,1]:=BMP.ScanLine[Y-1];
Pixel[3,1]:=BMP.ScanLine[Y-1];
Pixel[1,2]:=BMP.ScanLine[Y];
Pixel[2,2]:=BMP.ScanLine[Y];
Pixel[3,2]:=BMP.ScanLine[Y];
Pixel[1,3]:=BMP.ScanLine[Y+1];
Pixel[2,3]:=BMP.ScanLine[Y+1];
Pixel[3,3]:=BMP.ScanLine[Y+1];
Inc(Pixel[2,1],1);
Inc(Pixel[2,2],1);
Inc(Pixel[2,3],1);
Inc(Pixel[3,1],2);
Inc(Pixel[3,2],2);
Inc(Pixel[3,3],2);
for X:=1 to BMP.Width-2 do
begin
RSum:=
((Pixel[1,1].rgbtRed * Mask[1,1]) + (Pixel[2,1].rgbtRed * Mask[2,1]) + (Pixel[3,1].rgbtRed * Mask[3,1]) +
(Pixel[1,2].rgbtRed * Mask[1,2]) + (Pixel[2,2].rgbtRed * Mask[2,2]) + (Pixel[3,2].rgbtRed * Mask[3,2]) +
(Pixel[1,3].rgbtRed * Mask[1,3]) + (Pixel[2,3].rgbtRed * Mask[2,3]) + (Pixel[3,3].rgbtRed * Mask[3,3]))
div
MaskSum;
Pixel[2,2].rgbtRed:=(RSum);
GSum:=
((Pixel[1,1].rgbtGreen * Mask[1,1]) + (Pixel[2,1].rgbtGreen * Mask[2,1]) + (Pixel[3,1].rgbtGreen * Mask[3,1]) +
(Pixel[1,2].rgbtGreen * Mask[1,2]) + (Pixel[2,2].rgbtGreen * Mask[2,2]) + (Pixel[3,2].rgbtGreen * Mask[3,2]) +
(Pixel[1,3].rgbtGreen * Mask[1,3]) + (Pixel[2,3].rgbtGreen * Mask[2,3]) + (Pixel[3,3].rgbtGreen * Mask[3,3]))
div
MaskSum;
Pixel[2,2].rgbtGreen:=(GSum);
BSum:=
((Pixel[1,1].rgbtBlue * Mask[1,1]) + (Pixel[2,1].rgbtBlue * Mask[2,1]) + (Pixel[3,1].rgbtBlue * Mask[3,1]) +
(Pixel[1,2].rgbtBlue * Mask[1,2]) + (Pixel[2,2].rgbtBlue * Mask[2,2]) + (Pixel[3,2].rgbtBlue * Mask[3,2]) +
(Pixel[1,3].rgbtBlue * Mask[1,3]) + (Pixel[2,3].rgbtBlue * Mask[2,3]) + (Pixel[3,3].rgbtBlue * Mask[3,3]))
div
MaskSum;
Pixel[2,2].rgbtBlue:=(BSum);
Inc(Pixel[1,1],1);
Inc(Pixel[2,1],1);
Inc(Pixel[3,1],1);
Inc(Pixel[1,2],1);
Inc(Pixel[2,2],1);
Inc(Pixel[3,2],1);
Inc(Pixel[1,3],1);
Inc(Pixel[2,3],1);
Inc(Pixel[3,3],1);
end;
end;
IMG.Picture:=nil;
IMG.Picture.Bitmap:=BMP;
end;
dodanie znaczników <code class="delphi"> - furious programming