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. |