PDA

View Full Version : Image Processing using Delphi



jcarranza
April 1, 2004, 18:52:21
Hi I'm trying to translate your VB example of "Doing Advance Image Processing" to Delphi 7. I think everything is OK but when I run the program I cannot perform the draw of the rectangle I mean it seems to work but I cannot see the overlay rectangle, and I'm wondering why. I have reviewed the code and the only differences between VB and Delphi are in the mouse events code I mean

In VB:

If Not UserCommited And (Button and vbLeftButton) Then

In Delphi

If Not UserCommited Then

Firts of all, I'm not used to program in VB thought I can understand almost everything but the statement "Button and vbLeftButton" is something that I cannot understand can you please explain me what you're performing there? I'm not really sure but maybe that is the main problem.

Anothe question, I've run your VB program and it works well but i don't understand the complete target of the program. If I understand well, you begin the program disabling LiveCapture so you can use LiveContinous mode for copying Image to a buffer and then work with this buffer for image processing right?, running the program I can select the ROI using the mouse but after that I don't know what to expect I cannot understand the correct use of cmdROICommited button. Can you please give me and explanation of what to expect and how to use the program?.

Thanks a lot.

PS: I'm sending you my translated Delphi code, of course I did the first steps for configuring the Imagin Control:


unit UnitROI2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleCtrls, ICImagingControl_TLB;

type
RECT=record
Left : integer;
Top : integer;
Right : integer;
Bottom : integer;
end;

TForm1 = class(TForm)
BIniciar: TButton;
BParar: TButton;
IC1: TICImagingControl;
BRoi: TButton;
procedure BIniciarClick(Sender: TObject);
procedure BRoiClick(Sender: TObject);
procedure BPararClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure IC1MouseDown(ASender: TObject; Button, Shift: Integer; XPos,
YPos: Smallint);
procedure IC1MouseUp(ASender: TObject; Button, Shift: Integer; XPos,
YPos: Smallint);
procedure IC1MouseMove(ASender: TObject; Button, Shift: Integer; XPos,
YPos: Smallint);
procedure IC1ImageAvailable(ASender: TObject; BufferIndex: Integer);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
DisplayBuffer : ImageBuffer;
UserROI : RECT;
UserROICommited : Boolean;
//Procedimientos
procedure ContinousMode(BufferIndex : integer; Region : RECT);
procedure CompareMode(BufferIndex : integer; Region : RECT);
function NormalizeRect(val : RECT):RECT;
function CompareRegion(Arr : OleVariant; Arr2 : OleVariant; Region : RECT; Threshold : integer):Boolean;
procedure DrawRectangleY8(Arr : OleVariant; Region : RECT);
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BIniciarClick(Sender: TObject);
begin
IC1.LiveStart;
BIniciar.Enabled := False;
BParar.Enabled := True;
BROI.Enabled := True;
end;

procedure TForm1.BRoiClick(Sender: TObject);
begin
If Not UserROICommited Then
begin
UserROICommited := True;
BRoi.Caption := 'Reset ROI'
end
Else
begin
UserROICommited := False;
BRoi.Caption := 'Set currente ROI';
end;
end;

procedure TForm1.BPararClick(Sender: TObject);
begin
BIniciar.Enabled := True;
BParar.Enabled := False;
BRoi.Enabled := False;
DisplayBuffer.ForceUnlock;
IC1.LiveStop;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
BIniciar.Enabled := False;
BParar.Enabled := False;
BRoi.Enabled := False;

If IC1.DeviceValid Then
BIniciar.Enabled := True;
IC1.Width := IC1.ImageWidth;
IC1.Height := IC1.ImageHeight;
DisplayBuffer := IC1.ImageBuffers.Item[1];
UserROI.Top := 0;
UserROI.Left := 0;
UserROI.Bottom := IC1.ImageHeight;
UserROI.Right := IC1.ImageWidth;
end;

procedure TForm1.IC1MouseDown(ASender: TObject; Button, Shift: Integer;
XPos, YPos: Smallint);
begin
If Not UserROICommited Then
begin
UserROI.Left := XPos;
UserROI.Top := IC1.Height - YPos;
end;
end;

procedure TForm1.IC1MouseUp(ASender: TObject; Button, Shift: Integer; XPos,
YPos: Smallint);
begin
If Not UserROICommited Then
begin
UserROI.Right := XPos;
UserROI.Bottom := IC1.Height - YPos;
end;
end;

procedure TForm1.IC1MouseMove(ASender: TObject; Button, Shift: Integer;
XPos, YPos: Smallint);
begin
If Not UserROICommited Then
begin
UserROI.Right := XPos;
UserROI.Bottom := IC1.Height - YPos;
end;
end;

procedure TForm1.IC1ImageAvailable(ASender: TObject; BufferIndex: Integer);
var
Region : RECT;
begin
Region := NormalizeRect(UserROI);
If Not UserROICommited Then
ContinousMode(BufferIndex, Region)
Else
CompareMode(BufferIndex,Region);
end;

//PROCEDIMIENTOS DE USUARIO.

procedure TForm1.ContinousMode(BufferIndex : integer; Region : RECT);
var
DisplayArr : OleVariant;
begin
DisplayBuffer.Unlock;
DisplayBuffer := IC1.ImageBuffers.Item[BufferIndex];
DisplayBuffer.Lock;

DisplayArr := DisplayBuffer.GetImageData;
DrawRectangleY8(DisplayArr,Region);
DisplayBuffer.ReleaseImageData(DisplayArr);

IC1.DisplayImageBuffer(DisplayBuffer);
end;

procedure TForm1.CompareMode(BufferIndex : integer; Region : RECT);
var
ArrOld, ArrNew : OleVariant;
IBOld, IBNew : ImageBuffer;
begin
IBOld := DisplayBuffer;
IBNew := IC1.ImageBuffers.Item[BufferIndex];
ArrOld := IBOld.GetImageData;
ArrNew := IBNew.GetImageData;

If CompareRegion(ArrOld,ArrNew,Region,10) Then
begin
DisplayBuffer.Unlock;
DisplayBuffer := IBNew;
DisplayBuffer.Lock;
DrawRectangleY8(ArrNew,Region);
IC1.DisplayImageBuffer(DisplayBuffer);
end;
IBOld.ReleaseImageData(ArrOld);
IBNew.ReleaseImageData(ArrNew);
end;

function TForm1.NormalizeRect(val : RECT):RECT;
var
Tmp : integer;
r : RECT;
begin
r := val;
If r.Top > r.Bottom Then
begin
Tmp:=r.Top;
r.Top := r.Bottom;
r.Bottom := Tmp;
end;

If r.Left > r.Right Then
begin
Tmp := r.Left;
r.Left := r.Right;
r.Right := Tmp;
end;

If r.Top < 0 Then
r.Top := 0;
If r.Left < 0 Then
r.Left := 0;
If r.Bottom >= IC1.ImageHeight Then
r.bottom := IC1.ImageHeight - 1;
If r.Right >= IC1.ImageWidth Then
r.Right := IC1.ImageWidth - 1;
NormalizeRect := r;
end;
function TForm1.CompareRegion(Arr : OleVariant; Arr2 : OleVariant; Region : RECT; Threshold : integer):Boolean;
var
x,y : integer;
GreyScaleDifference : extended;
PixelCount : integer;
begin
PixelCount := (Region.Bottom - Region.Top) * (Region.Right - Region.Left);
If PixelCount > 0 Then
begin
GreyScaleDifference := 0;
For y:=Region.Top To Region.Bottom do
For x:=Region.Left To Region.Right do
GreyScaleDifference := GreyScaleDifference + trunc(Abs(Arr[x,y] - Arr2[x,y]));
GreyScaleDifference := GreyScaleDifference / PixelCount;
If GreyScaleDifference > Threshold Then
CompareRegion := True
Else
CompareRegion := False;
end
Else
CompareRegion := False;
end;
procedure TForm1.DrawRectangleY8(Arr : OleVariant; Region : RECT);
const RECT_COLOR : integer = 255;
var
x,y : integer;
begin
For x:=Region.Left To Region.Right do
Arr[x,Region.Top]:=RECT_COLOR;
For x:=Region.Left To Region.Right do
Arr[x,Region.Bottom]:=RECT_COLOR;
For y:=Region.Top To Region.Bottom do
Arr[Region.Left,y]:=RECT_COLOR;
For y:=Region.Top To Region.Bottom do
Arr[Region.Right,y]:=RECT_COLOR;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
DisplayBuffer.Unlock;
IC1.LiveStop;
end;

end.

Stefan Geissler
April 2, 2004, 10:28:28
Hello,

First of all, Delphi is not support officially by IC Imaging Control. Second: My personal Delphi experiences are poor.

The IC1ImageAvailable procedure is not called, because the initialization of your control is not complete (as as i can see). The construtor of Tform1 should look like follows:


procedure TForm1.OnCreate(Sender: TObject);
begin
IC1.MemoryCurrentGrabberColorformat := ICY8;
IC1.LiveDisplay := False;
IC1.LiveCaptureContinuous := true;

UserROI.Top := 0;
UserROI.Left := 0;
UserROI.Bottom := IC1.ImageHeight;
UserROI.Right := IC1.ImageWidth;
DisplayBuffer := IC1.ImageBuffers.Item[1];
end;


The button parameter should be the mouse button (left, right, middle) and is bitwise “anded” in the Visual Basic sample, to make sure the left mouse button was pressed. I was not able to inspect this value in Delphi.

The access to the image data differs in Delphi to Visual Basic:

The following Delphi code snipped show how to access the image data, that are delivered by the ImageBuffer (Memorybuffer):


procedure TForm1.ICImagingControl1ImageAvailable(ASender: TObject;
BufferIndex: Integer);

var CurrentBuffer: ImageBuffer;
ImageData: OleVariant;
pPixel:Pointer;

begin

CurrentBuffer:= ICImagingControl1.ImageBuffers.Item[BufferIndex];
CurrentBuffer.Lock;

ImageData:= CurrentBuffer.GetImageData;

pPixel:=TVarData(ImageData).Varray^.data;

(* pPixel points directly to the beginning of the image pixel data *)

CurrentBuffer.ReleaseImageData(ImageData);

ICImagingControl1.DisplayImageBuffer(CurrentBuffer );
CurrentBuffer.UnLock;

end;


I have no translation of this Visual Basic sample to Delphi.