Jak zrobić rozmycie gaussa?

0

Witam, jestem słaby z programowania, a mam zrobić program, który powoduje, że po naciśnięciu przycisku na obrazie dokonywane jest rozmycie Gaussa. Mam to zrobić na bazie programu, który już napisałem.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, jpeg, ExtCtrls, ComCtrls;

type
  Kolory=Array[1..3]of byte;
  TForm1 = class(TForm)
    Image1: TImage;
    Button1: TButton;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Image5: TImage;
    Image6: TImage;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

Function ColToRGB(Kolor:TColor):Kolory;
Var
  RedGreenBlue:Kolory;
Begin
  ColorToRGB(Kolor);
  RedGreenBlue[1]:=($000000FF and Kolor);
  RedGreenBlue[2]:=($0000FF00 and Kolor) Shr 8;
  RedGreenBlue[3]:=($00FF0000 and Kolor) Shr 16;
  Result:=RedGreenBlue;
End;

procedure TForm1.Button1Click(Sender: TObject);
  Var
    k,i,j:Integer;
    Color:TColor;
    Btmp:TBitmap;
    x,y,z,R,G,B:Byte;
    ReGrBl:Kolory;
begin
  Btmp:=TBitmap.Create;
  Btmp.Assign(Image1.Picture.Graphic);
  Image1.Picture.Bitmap:=Btmp;
  for i:=0 to 500 do
  for j:=0 to 500 do
    Begin
    Color:=Image1.Canvas.Pixels[i,j];
    ReGrBl:=ColToRGB(Color);
    Color:=RGB(ReGrBl[1],0,0);
    Image2.Canvas.Pixels[i,j]:=Color;
    Color:=Image1.Canvas.Pixels[i,j];
    Image3.Canvas.Pixels[i,j]:=Color;
    Color:=Image1.Canvas.Pixels[i,j];
    Color:=RGB(ReGrBl[3],ReGrBl[3],ReGrBl[3]);
    Image4.Canvas.Pixels[i,j]:=Color;
    Color:=Image1.Canvas.Pixels[i,j];
    Color:=Image1.Canvas.Pixels[i,j];
    Image5.Canvas.Pixels[i,j]:=clWhite;
    x:=(ReGrBl[1]+ReGrBl[2]+ReGrBl[3]) div 3;
    If x<100 then Image5.Canvas.Pixels[i,j]:=clBlack;
    End;
  Btmp.Free;
end;

end.

Program ten wczytuje obraz, dokonuje kilku zmian jak np. binaryzacji. Ja chcę aby obraz trzeci był rozmywany efektem gaussa, jednocześnie wykorzystując już jakieś wcześniej napisane komendy. Podpowie ktoś jak to zrobić? Najlepiej aby kod był jak najprostszy. Bardzo proszę o pomoc.

3

Wykorzystanie właściwości Canvas.Pixels jest rozwiązaniem najwolniejszym ze wszystkich możliwych; O wiele szybszym rozwiązaniem jest użycie właściwości ScanLine, więc z niej skorzystaj; Przy okazji pozbędziesz się tej kupki zmiennych lokalnych;

Kolejna sprawa to te pętle - dlaczego liczba ich iteracji jest hardkodowana? Podasz mniejszy obraz i poleci Access Violation; Klasa TBitmap ma takie właściwości jak Width i Height, więc z nich skorzystaj (tylko nie zapomnij odjąć 1 - piksele indeksowane są od 0);

Poza tym kod jest brzydki - przetwarzasz obraz w zdarzeniu kliknięcia w przycisk... Zmień to - najpierw stwórz sobie osobne metody dla wszystkich operacji przetwarzania obrazu, które w parametrze przyjmować będą obiekt bitmapy (jeden efekt to jedna metoda); Następnie w osobnej metodzie utworz w pamięci obiekt bitmapy, załaduj surowy obraz z pliku i przekazuj go po kolei do wszystkich metod przetwarzających; Na koniec zapisz obraz z pamięci do pliku docelowego i usuń obiekt z pamięci.

0

Dzięki za rady, ale nie o to chodzi w mojej prośbie. Potrzebuje w tym programie (dokładnie w tym) mieć jeszcze obraz poddany rozmyciu Gaussa. Możesz mi doradzić coś w tej kwestii? Jak to zrobić najprościej jak się da?

0

Najprościej jak się da to wpakować cały kod implementujący rozmycie Gaussa w zdarzeniu Button1Click, pod istniejącymi pętlami; Ale to rowiązanie będzie paskudne, a kod bardzo mocno nieczytelny oraz niezgodny z zasadą pojedynczej odpowiedzialności; Już teraz jest duży bałagan, a po dodaniu nowego kodu będzie jeszcze większy :]

0

O to właśnie mi chodzi, jak napisać taki kod pod tymi pętlami? Chcę tylko żeby program działał.

0

No nie mam tego kodu, chce go jakoś napisać, ale mowię ze sie na tym nie znam. Ogólnie nie umiem wiele ponad napisanie tej komendy warunkowej z If.

0

Szukałeś czegokolwiek na ten temat? Masz tu teorie i nawet gotowca www.algorytm.org/przetwarzanie-obrazow/filtrowanie-obrazow.html

0
BB19 napisał(a):

Dzięki za rady, ale nie o to chodzi w mojej prośbie. Potrzebuje w tym programie (dokładnie w tym) mieć jeszcze obraz poddany rozmyciu Gaussa. Możesz mi doradzić coś w tej kwestii? Jak to zrobić najprościej jak się da?

Rozmycie Gausa to jeden z najprostszych algorytmów stosowanych w grafice. Nawet rysowanie liniii jest bardziej skomplikowane.

Edit: link jest już wyżej

0

@vpiotr Wiem, że to niby jest proste, bo inaczej nikt nie dał by tego do zrobienia osobie, która jeszcze nie zna się na programowaniu. Dla Ciebie to prościzna bo jesteś w tym dobry i masz doświadczenie, a dla mnie to już nie bardzo.
@szopenfx Czytałem tą stronę, żeby w ogóle zrozumieć co to jest rozmycie gaussa. Ale ten kod jest dla mnie za bardzo skomplikowany, nie rozumiem go. Widzę, że niby tą macierzą GAUSS1 się jakoś uwydatnia punkty, dla których przeprowadzana jest ta operacja. Ale nie wiem jak to zastosować u mnie.

0

Z czym masz problem? Przeczytałeś artykuł?
Mógłbym się teraz produkować rozbijając na części pierwsze algorytm, ale nie ma sensu bo jest to już opisane - jeśli nie rozumiesz pewnych zwrotów, lub kawałków kodu to pomogę, ale nie będę się rozczulał nad kimś, kto nie zada sobie trudu przynajmniej do sprecyzowania prostego pytania; CO NIE POZWALA MI IŚĆ DALEJ!?

0

Zgodnie z tym co jest napisane i jak dobrze to rozumiem to liczę tą średnią. Czyli waga filtra w danym miejscu razy wartość danego koloru w RGB - tzn. dla poszczególnej składowej RGB. Ale nie wiem nawet jak to zapisać.

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