ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Obtaining measurements demo

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
John Posted - Oct 03 2011 : 08:40:41
Slightly modifying the measurements demo based on the fact that the embedded standard on the xrays in a millimeter ruler and not a area, I do the following.

I load into ImageEnVect1 an xray with a millimeter ruler embedded to obtain standard lengths. Using the measurement demo as a model I do the following:

a) I set MouseInteract := [miSelect];
b) I measure a 20 millimeter length on the embedded ruler
c) The OnSelection event is then called

procedure TformXrayMeasure.ImageEnVect1SelectionChange(Sender: TObject);
var
tempCalibrationLength: Double;
begin
if tempCalibrationLength = 0 then
begin
tempCalibrationLength := ImageEnVect1.GetSelectionLen;

with ImageEnVect1 do
begin
mUnit := ieuMillimeters;
SetScaleFromSelectionLen(20);
Deselect;
MouseInteractVt := [miDragLen];
end;

MessageDlg('You can now measure lengths.',
mtConfirmation, [mbOk], 0 );
SpeedButtonCalibrate.Enabled := False;
end
end;

The problem is that if I then measure 10 millimeters on the embedded ruler the result is not 10 millimetter, but rather 5 millimeters ( plus or minus some small fraction of a millimeter) not 10 millimeters.

Suggestions?

TIA

John
10   L A T E S T    R E P L I E S    (Newest First)
fab Posted - Oct 20 2011 : 00:11:05
quote:
Instead of drawing a line and getting the length by either the above proceedure or using miDragLen. Is there a mechanism to select two points/markers ( similar to your "Marker" demo) and from those two points/markers determine the distance between them?


It is not possible automatically. Anyway you can still put two objects (for example two images) and calculate the distance between them.
John Posted - Oct 16 2011 : 15:37:57
Fabrizio

1. I had set MUnit := ieuMillimeters which explains the unit labeling with MouseInteractVt := [miDragLen].

2. I obtain the correct calibration by using the following calibration code.

Uses tempPixesPerMM: Double;

procedure TformXrayMeasure.Calibrate;
var
lx, ly: double;
tempRect: TRect;
len: double;
begin
ImageEnVect1.GetObjRect(ImageEnVect1.SelObjects[tempObjIndex], tempRect);
lx := abs(tempRect.Right - tempRect.Left);
ly := abs(tempRect.Bottom - tempRect.Top);
len := sqrt(lx * lx + ly * ly);

tempPixelsPerMM := len/20;
ImageEnVect1.SetScaleFromPixels(Trunc(len), 20);

if MessageDlg('Do you wish to remove the calibration line?',
mtConfirmation, [mbYes, mbNo], 0 ) = mrYes then
begin
ImageEnVect1.RemoveObject(ImageEnVect1.SelObjects[0]);
end;

ImageEnVect1.CancelInteracts;
end;

3) I obtain the length of a selected line via the following code.

procedure TformXrayMeasure.SpeedButtonGetLengthClick(Sender: TObject);
var
lx, ly: double;
tempRect: TRect;
len: double;
begin
if ImageEnVect1.ObjectsCount > 0 then
begin
if tempObjIndex >= 0 then
begin
ImageEnVect1.GetObjRect(ImageEnVect1.SelObjects[tempObjIndex], tempRect);
lx := abs(tempRect.Right - tempRect.Left);
ly := abs(tempRect.Bottom - tempRect.Top);
len := sqrt(lx * lx + ly * ly);

showmessage('Length of obj = ' + FloatToStr(len/tempPixelsPerMM));
end
end;
end;


Related question.

Instead of drawing a line and getting the length by either the above proceedure or using miDragLen. Is there a mechanism to select two points/markers ( similar to your "Marker" demo) and from those two points/markers determine the distance between them?

I appreciate your efforts

John
fab Posted - Oct 16 2011 : 10:22:07
About miDragLen, have you set MUnit? You should set:

ImageEnVect1.MUnit := ieuMILLIMETERS;

In my tests ruler length and miDragLen values corresponds.

quote:
I looked at the OnPresentMeasurement event, but the help file does not define whether the "Value" variable is length or pixels and there is no information on the ValType

"Value" is the value to show. For example it is the measured length (in the measure unit you have chosen).
John Posted - Oct 16 2011 : 10:09:24
Fabrizio

Using the code you supplied earlier in this thread, I can drawn a line through 20 millmeters of a millimeter ruler embedded in an ImageEnVect image, determine the number of pixels in the line and then determine the number of pixels per millimeter for the specific image.

The current issue is as follows: if I set
ImageEnVect1.MouseInteractVt := [miDragLen];
the length displayed in the label as the measurement is made is labeled as millimeters and does not correspond to the embedded millimeter ruler.

Question 1) Exactly what does the displayed miDragLen measurement represent? The physical length of the line in millimeters? A pixel count measurement of the line length divided by a predefined pixels per millimeter length?

Question 2) Is there a mechanism to convert the measurement displayed in the miDragLen text to a millimeter measurement based on the pixels per millimeter standard that I previously established using the embedded millimeter ruler?

I looked at the OnPresentMeasurement event, but the help file does not define whether the "Value" variable is length or pixels and there is no information on the ValType

I appreciate your efforts and await your reply

John
John Posted - Oct 04 2011 : 21:16:50
That is exactly what I was looking to accomplish.

Thank you very much.

John
fab Posted - Oct 04 2011 : 01:25:21
quote:
The problem is that when I load an xray, (althought it has a vertical millimeter ruler embedded in the film), I do not know how many pixels are represented by the distance between millimeter 1 and 10.


You can know the distance, in pixels, of the ruler with:
var
  lx, ly: double;
  r: TRect;
  len: double;
begin
  ImageEnVect1.GetObjRect(ImageEnVect1.SelObjects[0], r);
  lx := abs(r.Right-r.Left);
  ly := abs(r.Bottom-r.Top);
  len := sqrt(lx * lx + ly * ly);
  ...now "len" contains the ruler length in pixels...

end;
John Posted - Oct 03 2011 : 22:17:12
Fabrizio

Since the embedded millimeter ruler in the xray images has a know width, I can actually use the code represented with the "MeasureIt" demo to calibrate the values used with ImageEnVect1.MouseInteractVt := [miDragLen];

I am still confused, however, about calibrating the drag measurement functionality with the SetScaleFromPixels function.

The help file defines the function as SetScaleFromPixels(px:integer; mm:double). As I understand it, the first variable "px" is the number of pixels represented by the length of the second variable. I my situation I define ImageEnVect1.mUnit := ieuMillimeters and mm = 10 for a total of 10 millimeters which can be easily read from the millimeter ruler embedded in the xray image;

The problem is that when I load an xray, (althought it has a vertical millimeter ruler embedded in the film), I do not know how many pixels are represented by the distance between millimeter 1 and 10.

The question thus becomes, how to determine the number of pixels between millimeter 1 and 10 on the embedded ruler so that I can correctly define the scale using the SetScaleFromPixels function?

Sorry for the confusion. I certainly appreciate any clarification that you can provide.

John
fab Posted - Oct 03 2011 : 12:58:11
quote:
My thought was to use the LMDSysInfo.ScreenHeight property which returns the number of pixels in the screen height. From there I can get pixels per millimeter by dividing LMDSysInfo.ScreenHeight/screen Height in mm.


Sorry, I don't understand very well. What has to do the screen with the image?
ImageEn just converts a length in pixels to a length in another measure unit, and this can be done adjusting Scale and DPI (of the background image). This is done automatically by SetScaleFromSelectionLen or by SetScaleFromPixels. No other ways or info are available.

quote:
Does ImageEn contain another mechanism to obtain the number of pixels contained in the reference length (which is vertical in orientation)?


SetScaleFromPixels, no other. Put a ruler over the reference length, and pass the ruler length to SetScaleFromPixels.
John Posted - Oct 03 2011 : 12:44:16
Fabizio

I looked at SetScaleFromPixils but my question was how to determine the number of pixels encompassed by the reference length measurement which is vertically oriented?

My thought was to use the LMDSysInfo.ScreenHeight property which returns the number of pixels in the screen height. From there I can get pixels per millimeter by dividing LMDSysInfo.ScreenHeight/screen Height in mm.

Does ImageEn contain another mechanism to obtain the number of pixels contained in the reference length (which is vertical in orientation)? Or do you have a better suggestion to obtain the pixel count for the reference length?

TIA

John
fab Posted - Oct 03 2011 : 10:42:10
Hi,
SetScaleFromSelectionLen gets a perimeter, not a segment length.
Please try SetScaleFromPixels(number_of_pixels, measure_length) instead.