Author |
Topic |
|
AdrianKnowles
USA
35 Posts |
Posted - Sep 14 2017 : 02:28:33
|
Hi, I have some code that is meant to display an ROI on 3 different imageenviews. Some coordinate values are shared between the 3 ROIs.
The code below works as intended when I don't load any images. However once I load images then the ROI's become scaled incorrectly.
It seems that the 'shared' coordinates no longer work and the ROI's become scaled incorrectly. Am I doing anything silly here??
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, hyieutils, iexBitmaps, hyiedefs,
iesettings, iexLayers, iexRulers, Vcl.StdCtrls, ieview, imageenview, imageen,
ieopensavedlg;
type
TForm1 = class(TForm)
ImageEnview1: TImageEn;
ImageEnview2: TImageEn;
ImageEnview3: TImageEn;
Button1: TButton;
Load1: TButton;
Load2: TButton;
Load3: TButton;
OpenImageEnDialog1: TOpenImageEnDialog;
procedure Button1Click(Sender: TObject);
procedure ImageEnview1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Load1Click(Sender: TObject);
procedure Load2Click(Sender: TObject);
procedure Load3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
x1,y1, x2,y2,x3,y3,x4,y4: integer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
arect: TRect;
begin
ImageEnView1.MouseInteract := [miCropTool];
ImageEnView2.MouseInteract := [miCropTool];
ImageEnView3.MouseInteract := [miCropTool];
// Disable guide lines (on image thirds)
ImageEnView1.CropToolInteraction.DrawGuides := False;
ImageEnView2.CropToolInteraction.DrawGuides := False;
ImageEnView3.CropToolInteraction.DrawGuides := False;
// Make larger grips
ImageEnView1.CropToolInteraction.GripSize := 14; //20
ImageEnView2.CropToolInteraction.GripSize := 14;
ImageEnView3.CropToolInteraction.GripSize := 14;
x1:= 100;
y1:= 100;
x2:= 200;
y2:= 100;
x3:= 200;
y3:= 200;
x4:= 100;
y4:= 200;
ImageEnView1.SelectionBase := iesbBitmap;
ImageEnView2.SelectionBase := iesbBitmap;
ImageEnView3.SelectionBase := iesbBitmap;
ARect := Rect(x1,y1,x3,y3);
ImageEnView1.CropToolInteraction.SetBitmapPolygon( ARect );
ImageEnView1.Invalidate();
ARect := Rect(x1,y1,x3,y3);
ImageEnView2.CropToolInteraction.SetBitmapPolygon( ARect );
ImageEnView2.Invalidate();
ARect := Rect(x1,y1,x3,y3);
ImageEnView3.CropToolInteraction.SetBitmapPolygon( ARect );
ImageEnView3.Invalidate();
end;
procedure TForm1.ImageEnview1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
arect: TRect;
CopyRect: Trect;
View1X1,View1Y1, View1X2,View1Y2: integer;
View2X1,View2Y1, View2X2,View2Y2,View2X3,View2Y3 : integer;
View3X1,View3Y1, View3X2,View3Y2,View3X3,View3Y3 : integer;
// x1,y1, x2,y2,x3,y3,x4,y4: integer;
begin
//ImageEnView1.CropToolInteraction.Crop();
//Added below 3 lines//
if (ssLeft in shift) then
begin
// Item 0 is Top-Left, item 1 is Top-Right, item 2 is Bottom-Right and item 3 is Bottom-Left
ImageEnView1.SelectionBase := iesbBitmap;
ImageEnView2.SelectionBase := iesbBitmap;
ImageEnView3.SelectionBase := iesbBitmap;
X1:= Round(imageenview1.CropToolInteraction.RotatedPolygon[0].X );
Y1:= Round(imageenview1.CropToolInteraction.RotatedPolygon[0].y );
X2:= Round(imageenview1.CropToolInteraction.RotatedPolygon[1].x );
Y2:= Round(imageenview1.CropToolInteraction.RotatedPolygon[1].y );
X3:= Round(imageenview1.CropToolInteraction.RotatedPolygon[2].x );
Y3:= Round(imageenview1.CropToolInteraction.RotatedPolygon[2].y );
X4:= Round(imageenview1.CropToolInteraction.RotatedPolygon[3].x );
Y4:= Round(imageenview1.CropToolInteraction.RotatedPolygon[3].y );
View2X1:= Round(imageenview2.CropToolInteraction.RotatedPolygon[0].x );
View2Y1:= Round(imageenview2.CropToolInteraction.RotatedPolygon[0].y );
View2X3:= Round(imageenview2.CropToolInteraction.RotatedPolygon[2].x );
View2Y3:= Round(imageenview2.CropToolInteraction.RotatedPolygon[2].y );
View3X1:= Round(imageenview3.CropToolInteraction.RotatedPolygon[0].x );
View3Y1:= Round(imageenview3.CropToolInteraction.RotatedPolygon[0].y );
View3X3:= Round(imageenview3.CropToolInteraction.RotatedPolygon[2].x );
View3Y3:= Round(imageenview3.CropToolInteraction.RotatedPolygon[2].y );
ARect := Rect(View2X1,Y1,View2X3,Y3) ;
ImageEnView2.CropToolInteraction.SetBitmapPolygon( ARect );
ImageEnView2.Invalidate();
ARect := Rect(x1,View3Y1,x3,View3Y3);
ImageEnView3.CropToolInteraction.SetBitmapPolygon( ARect );
ImageEnView3.Invalidate();
end;
end;
procedure TForm1.Load1Click(Sender: TObject);
var
fn:string;
tags : TIEDicomTags;
begin
OpenImageEnDialog1.AutoSetFilterFileType := ioDicom;
if OpenImageEnDialog1.Execute then
begin
fn := OpenImageEnDialog1.FileName;
imageenview1.IO.LoadFromFile(fn);
ImageEnView1.Fit;
end;
end;
procedure TForm1.Load2Click(Sender: TObject);
var
fn:string;
tags : TIEDicomTags;
begin
OpenImageEnDialog1.AutoSetFilterFileType := ioDicom;
if OpenImageEnDialog1.Execute then
begin
fn := OpenImageEnDialog1.FileName;
imageenview2.IO.LoadFromFile(fn);
ImageEnView2.Fit;
end;
end;
procedure TForm1.Load3Click(Sender: TObject);
var
fn:string;
tags : TIEDicomTags;
begin
OpenImageEnDialog1.AutoSetFilterFileType := ioDicom;
if OpenImageEnDialog1.Execute then
begin
fn := OpenImageEnDialog1.FileName;
imageenview3.IO.LoadFromFile(fn);
ImageEnView3.Fit;
end;
end;
end.
|
|
xequte
38182 Posts |
Posted - Sep 14 2017 : 22:42:12
|
Hi
Before I debug this, your demo does not align even without images, is that intended?
Nigel Xequte Software www.xequte.com nigel@xequte.com
|
|
|
AdrianKnowles
USA
35 Posts |
Posted - Sep 15 2017 : 02:06:58
|
HI, I've attached an image showing the expected behaviour (empty viewer) and the changed behaviour once you have loaded images into each viewer
|
|
|
xequte
38182 Posts |
Posted - Sep 17 2017 : 19:17:27
|
Hi
RotatedPolygon values are specified in terms of the bitmap, so if the bitmaps are different sizes, then you will need to scale your x and y values appropriately, e.g. as a percentage of width or height, or in terms of screen (using TImageEnView.XBmp2Scr and TImageEnView.YBmp2Scr).
For example, here is your code that converts the bitmap values to screen values:
procedure TForm1.ImageEnView1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
arect: TRect;
CopyRect: Trect;
View1X1,View1Y1, View1X2,View1Y2: integer;
View2X1,View2Y1, View2X2,View2Y2,View2X3,View2Y3 : integer;
View3X1,View3Y1, View3X2,View3Y2,View3X3,View3Y3 : integer;
begin
if (ssLeft in shift) then
begin
// Item 0 is Top-Left, item 1 is Top-Right, item 2 is Bottom-Right and item 3 is Bottom-Left
X1:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[0].X ));
Y1:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[0].y ));
X2:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[1].x ));
Y2:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[1].y ));
X3:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[2].x ));
Y3:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[2].y ));
X4:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[3].x ));
Y4:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[3].y ));
View2X1:= Imageenview2.XScr2Bmp( Round(imageenview2.CropToolInteraction.RotatedPolygon[0].x ));
View2Y1:= Imageenview2.YScr2Bmp( Round(imageenview2.CropToolInteraction.RotatedPolygon[0].y ));
View2X3:= Imageenview2.XScr2Bmp( Round(imageenview2.CropToolInteraction.RotatedPolygon[2].x ));
View2Y3:= Imageenview2.YScr2Bmp( Round(imageenview2.CropToolInteraction.RotatedPolygon[2].y ));
View3X1:= Imageenview3.XScr2Bmp( Round(imageenview3.CropToolInteraction.RotatedPolygon[0].x ));
View3Y1:= Imageenview3.YScr2Bmp( Round(imageenview3.CropToolInteraction.RotatedPolygon[0].y ));
View3X3:= Imageenview3.XScr2Bmp( Round(imageenview3.CropToolInteraction.RotatedPolygon[2].x ));
View3Y3:= Imageenview3.YScr2Bmp( Round(imageenview3.CropToolInteraction.RotatedPolygon[2].y ));
ARect := Rect(View2X1,View2Y1,View2X3,View2Y3) ;
ImageEnView2.CropToolInteraction.SetBitmapPolygon( ARect );
ImageEnView2.Invalidate();
ARect := Rect(View3X1,View3Y1,View3X3,View3Y3);
ImageEnView3.CropToolInteraction.SetBitmapPolygon( ARect );
ImageEnView3.Invalidate();
end;
end;
Nigel Xequte Software www.xequte.com nigel@xequte.com
|
|
|
AdrianKnowles
USA
35 Posts |
Posted - Sep 19 2017 : 10:57:57
|
Hi Nigel, Many thanks for the assistance. Its still not working as intended although better.
As you can see from the video I posted to your email today when no image is loaded the ROI’s across the imageenviews work as intended. Once I load images (identical resolutions/formats etc...) then you see some scaling occurs.
procedure TForm1.ImageEnview1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
arect: TRect;
CopyRect: Trect;
View1X1,View1Y1, View1X2,View1Y2: integer;
View2X1,View2Y1, View2X2,View2Y2,View2X3,View2Y3 : integer;
View3X1,View3Y1, View3X2,View3Y2,View3X3,View3Y3 : integer;
begin
if (ssLeft in shift) then
begin
// Item 0 is Top-Left, item 1 is Top-Right, item 2 is Bottom-Right and item 3 is Bottom-Left
X1:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[0].X ));
Y1:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[0].y ));
X2:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[1].x ));
Y2:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[1].y ));
X3:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[2].x ));
Y3:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[2].y ));
X4:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[3].x ));
Y4:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[3].y ));
View2X1:= Imageenview2.XScr2Bmp( Round(imageenview2.CropToolInteraction.RotatedPolygon[0].x ));
View2Y1:= Imageenview2.YScr2Bmp( Round(imageenview2.CropToolInteraction.RotatedPolygon[0].y ));
View2X3:= Imageenview2.xScr2Bmp( Round(imageenview2.CropToolInteraction.RotatedPolygon[2].x ));
View2Y3:= Imageenview2.YScr2Bmp( Round(imageenview2.CropToolInteraction.RotatedPolygon[2].y ));
View3X1:= Imageenview3.XScr2Bmp( Round(imageenview3.CropToolInteraction.RotatedPolygon[0].x ));
View3Y1:= Imageenview3.YScr2Bmp( Round(imageenview3.CropToolInteraction.RotatedPolygon[0].y ));
View3X3:= Imageenview3.XScr2Bmp( Round(imageenview3.CropToolInteraction.RotatedPolygon[2].x ));
View3Y3:= Imageenview3.YScr2Bmp( Round(imageenview3.CropToolInteraction.RotatedPolygon[2].y ));
ARect := Rect(View2X1,Y1,View2X3,Y3) ;
ImageEnView2.CropToolInteraction.SetBitmapPolygon( ARect );
ImageEnView2.Invalidate();
ARect := Rect(x1,View3Y1,x3,View3Y3);
ImageEnView3.CropToolInteraction.SetBitmapPolygon( ARect );
ImageEnView3.Invalidate();
end;
end;
Kind regards, Adrian
attach/AdrianKnowles/2017919105653_19 Sept.zip 3091.56 KB |
|
|
AdrianKnowles
USA
35 Posts |
Posted - Sep 19 2017 : 11:00:06
|
I attached a .zip file to my previous pitch which contains the movie.
Thank you. |
|
|
xequte
38182 Posts |
Posted - Sep 19 2017 : 17:46:13
|
Hi Adrian
I'm not seeing that.
Please attach a zip of your test project and the three source images.
Nigel Xequte Software www.xequte.com nigel@xequte.com
|
|
|
AdrianKnowles
USA
35 Posts |
|
xequte
38182 Posts |
Posted - Sep 20 2017 : 17:53:09
|
OK, I'm not 100% clear on what the code is supposed to do here, but the big issue you are going to encounter is rounding errors. RotatedPolygon are double values so the frequent rounding while moving the mouse will change their values.
To counter that, I added some private values:
fView2X1: Double;
fView2X3: Double;
fView2Y3: Double;
fView3Y1: Double;
fView3Y3: Double;
Which you need to reset before using, or if the user manually changes that selection:
fView2X1 := -99;
fView2X3 := -99;
fView2Y3 := -99;
fView3Y1 := -99;
fView3Y3 := -99;
This is the code I used:
procedure TForm1.ImageEnview1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
arect: TRect;
CopyRect: Trect;
x1,y1, x2,y2,x3,y3,x4,y4: integer;
View1X1,View1Y1, View1X2,View1Y2: integer;
View2Y1: Integer;
View3X1,View3X3 : integer;
begin
if (ssLeft in shift) then
begin
// Item 0 is Top-Left, item 1 is Top-Right, item 2 is Bottom-Right and item 3 is Bottom-Left
X1:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[0].X ));
Y1:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[0].y ));
X2:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[1].x ));
Y2:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[1].y ));
X3:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[2].x ));
Y3:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[2].y ));
X4:= imageenview1.XBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[3].x ));
Y4:= imageenview1.YBmp2Scr( Round(imageenview1.CropToolInteraction.RotatedPolygon[3].y ));
// Only share y coord from point 0
if fView2X1 = -99 then
fView2X1:= Imageenview2.CropToolInteraction.RotatedPolygon[0].X;
View2Y1:= Imageenview2.YScr2Bmp( Y1 );
if fView2X3 = -99 then
fView2X3:= Round( Imageenview2.CropToolInteraction.RotatedPolygon[2].X );
if fView2Y3 = -99 then
fView2Y3:= Round( Imageenview2.CropToolInteraction.RotatedPolygon[2].Y );
// X coords from point 0 and 3 are shared
View3X1:= Imageenview3.XScr2Bmp( X1 );
if fView3Y1 = -99 then
fView3Y1:= Imageenview3.CropToolInteraction.RotatedPolygon[0].Y;
View3X3 := Imageenview3.XScr2Bmp( X3 );
if fView3Y3 = -99 then
fView3Y3:= Imageenview3.CropToolInteraction.RotatedPolygon[2].Y;
OneX .Text := IntToStr( X1 );
OneY .Text := IntToStr( Y1 );
ThreeX .Text := IntToStr( X3 );
THreeY .Text := IntToStr( Y3 );
TwoX .Text := IntToStr( Round( fView2X1 ));
TwoY .Text := IntToStr( Round( View2Y1 ));
FourX .Text := IntToStr( Round( fView2X3 ));
FourY .Text := IntToStr( Round( fView2Y3 ));
thirdx1 .Text := IntToStr( Round( View3X1 ));
thirdy1 .Text := IntToStr( Round( fView3Y1 ));
thirdx3 .Text := IntToStr( Round( View3X3 ));
thirdy3 .Text := IntToStr( Round( fView3Y3 ));
ARect := Rect( Round( fView2X1 ), Round( View2Y1 ), Round( fView2X3 ), Round( fView2Y3 )) ;
ImageEnView2.CropToolInteraction.SetBitmapPolygon( ARect );
ImageEnView2.Invalidate();
ARect := Rect( Round( View3X1 ), Round( fView3Y1 ), Round( View3X3 ), Round( fView3Y3 ));
ImageEnView3.CropToolInteraction.SetBitmapPolygon( ARect );
ImageEnView3.Invalidate();
end;
end;
Nigel Xequte Software www.xequte.com nigel@xequte.com
|
|
|
|
Topic |
|
|
|