unit HistoUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ComCtrls, StdCtrls, Spin, Math, TypesUnit;

type
  THistogram = array[0..255] of Word;

  THistoForm = class(TForm)
    ImageH: TImage;
    Label1: TLabel;
    Shape1: TShape;
    TrackBar1: TTrackBar;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    SpinEdit1: TSpinEdit;
    procedure ImageHMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure ImageHClick(Sender: TObject);
    procedure Shape1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure TrackBar1Change(Sender: TObject);
    procedure SpinEdit1Change(Sender: TObject);    
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    Histogram: THistogram;
    HMax: Word;
    Step: Integer;
    Follow: Boolean;
    LeftMax: Integer;
    RightMin: Integer;
    pBimodality: Integer;
    BimodalityDrawn: Boolean;
    procedure CountBimodality;
    procedure DrawBimodality;
  public
    property Bimodality: Integer read pBimodality;
    constructor Create(AOwner: TComponent; H: THistogram; Cap: String); reintroduce;
  end;

implementation

uses MainUnit;

{$R *.dfm}

constructor THistoForm.Create(AOwner: TComponent; H: THistogram; Cap: String);
var i: Integer;
begin
  inherited Create(AOwner);
  ClientHeight:=293;
  Histogram:=H;
  Caption:=Cap + ' - histogram';

  ImageH.Canvas.Pen.Color:=clGray;
  HMax:=0;
  for i:=1 to 255 do
    if Histogram[HMax]<Histogram[i] then
      HMax:=i;
  Step:=RoundUp(Histogram[HMax]/234);

  LeftMax:=0;
  RightMin:=0;
  pBimodality:=0;
  CountBimodality;
  Label1.Caption:='Bimodalita: '+IntToStr(Bimodality);

  Follow:=False;
  BimodalityDrawn:=False;

  TrackBar1Change(Self);
end;


procedure THistoForm.CountBimodality;
var i, j, HBimEnd, LM, RM: Integer;
begin
  i:=0;
  HBimEnd:=Round(Histogram[HMax]/cBimodalityLessThen);
  while Histogram[i] < HBimEnd do
    i:=i+1;
  HBimEnd:=i;

  for i:=0 to HBimEnd do begin
    LM:=i;
    for j:=i-1 downto 0 do
      if Histogram[j] > Histogram[LM] then
        LM:=j;

    RM:=i;
    for j:=i+1 to HBimEnd do
      if Histogram[j] < Histogram[RM] then
        RM:=j;

    if Histogram[LM]-Histogram[RM] > Bimodality then begin
      LeftMax:=LM;
      RightMin:=RM;
      pBimodality:=Histogram[LM]-Histogram[RM];
    end;
  end;
end;


procedure THistoForm.DrawBimodality;
var Tr: Integer;
begin
  ImageH.Canvas.Pen.Color:=clRed;
  Tr:=Round(255-Histogram[LeftMax]*255/Step/TrackBar1.Position);
  if Tr >= 0 then begin
    ImageH.Canvas.MoveTo(Max(0,LeftMax-5),Tr);
    ImageH.Canvas.LineTo(Min(255,LeftMax+5),Tr);
    ImageH.Canvas.MoveTo(LeftMax,Max(0,Tr-5));
    ImageH.Canvas.LineTo(LeftMax,Min(255,Tr+5));
  end;

  Tr:=Round(255-Histogram[RightMin]*255/Step/TrackBar1.Position);
  if Tr >= 0 then begin
    ImageH.Canvas.MoveTo(Max(0,RightMin-5),Tr);
    ImageH.Canvas.LineTo(Min(255,RightMin+5),Tr);
    ImageH.Canvas.MoveTo(RightMin, Max(0,Tr-5));
    ImageH.Canvas.LineTo(RightMin, Min(255,Tr+5));
  end;
  ImageH.Canvas.Pen.Color:=clGray;
  ImageH.Repaint;
end;


procedure THistoForm.ImageHMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if Follow then begin
    Shape1.Left:=X;
    SpinEdit1.Value:=X+1;
  end;
end;


procedure THistoForm.ImageHClick(Sender: TObject);
begin
  Follow:=True;
end;


procedure THistoForm.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Follow:=False;
end;


procedure THistoForm.TrackBar1Change(Sender: TObject);
var i, Up: Integer;
begin
  ImageH.Canvas.FillRect(Rect(0,0,255,255));
  for i:=0 to 255 do begin
    ImageH.Canvas.MoveTo(i,255);
    Up:=Round(255-Histogram[i]*255/Step/TrackBar1.Position);
    if Up < 0 then Up:=0;
    ImageH.Canvas.LineTo(i,Up);
  end;
  if BimodalityDrawn then
    DrawBimodality;
end;


procedure THistoForm.SpinEdit1Change(Sender: TObject);
begin
  Shape1.Left:=SpinEdit1.Value-1;
end;


procedure THistoForm.Button1Click(Sender: TObject);
begin
  if ClientHeight = 293 then begin
    ClientHeight:=327;
    Shape1.Visible:=True;
    Button1.Caption:='Zavři prahování';
    Follow:=True;
    end
  else begin
    ClientHeight:=293;
    Shape1.Visible:=False;
    Button1.Caption:='Prahování';
    Follow:=False;
  end;
end;


procedure THistoForm.Button2Click(Sender: TObject);
begin
  MainForm.Thresholding(SpinEdit1.Value);
end;


procedure THistoForm.Button3Click(Sender: TObject);
begin
    if Bimodality = 0 then begin
      ShowMessage('Histogram není bimodální.');
      Exit;
    end;

    if BimodalityDrawn then begin
      BimodalityDrawn:=False;
      TrackBar1Change(Self);
      Button3.Caption:='Ukaž bimodalitu';
      Label1.Visible:=False;
      end
    else begin
      BimodalityDrawn:=True;
      DrawBimodality;
      Button3.Caption:='Skryj bimodalitu';
      Label1.Visible:=True;
    end;
end;


procedure THistoForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:=caHide;
end;

end.
