Friday, December 24, 2010

24 December 2010

It's Christmas eve! Received an email few days ago from HR stating that today's a half-day.

Decided to look into the gluLookAt method in OpenGL. Though this method is not available in OpenGL ES, I figured that it would help me in one way or another in terms of figuring out the issues causing the translation to not work properly. There is a method in the c++ library that we are using to create a viewing matrix (the camera in other words) - LookAtRH. I presume that it works in a similar way as the gluLookAt method.

Though I got to read through some sources, I am still kind of puzzled. Gonna have to spend some more time next week to do this.

Thursday, December 23, 2010

23 December 2010

Resumed work on getting the pan gesture for translation up. Tried out another method of translation after studying a similar application. This method does not apply the calculation of the frustum's length at a particular z-axis, which at first made me wonder why it worked so well on that application.

- (void)panGestureCaptured:(UIGestureRecognizer *)gesture
{
...
...
...

static CGPoint currentLocation;
static CGPoint previousLocation;
ModelTransformation *obj = [[ModelTransformation alloc] init];
int objIndex = [eaglView retrieveObjectWithUniqueColors:gesture];
Vertex3D tempCurrentPosition = [eaglView getNodePositionWithIndex:objIndex];
if(gesture.state == UIGestureRecognizerStateBegan)
{
currentLocation = [gesture locationInView:[gesture view]];
currentLocation = [self convertToGL:currentLocation];
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
previousLocation = CGPointMake(currentLocation.x, currentLocation.y);
currentLocation = [gesture locationInView:[gesture view]];
currentLocation = [self convertToGL:currentLocation];
CGPoint diff = CGPointMake(currentLocation.x - previousLocation.x, currentLocation.y - previousLocation.y);
obj.xTranslation = tempCurrentPosition.x + diff.x;
obj.yTranslation = tempCurrentPosition.y + diff.y;
obj.ifTranslate = YES;
obj.node = objIndex;
[eaglView setTransformation:obj];
[obj release];
}
}

- (CGPoint)convertToGL:(CGPoint)uiPoint
{
float newY = eaglView.frame.size.height - uiPoint.y;
float newX = eaglView.frame.size.width - uiPoint.x;
CGPoint ret;
switch ([UIDevice currentDevice].orientation) {
case UIDeviceOrientationPortrait:
ret = CGPointMake(uiPoint.x, newY);
break;
case UIDeviceOrientationPortraitUpsideDown:
ret = CGPointMake(newX, uiPoint.y);
break;
case UIDeviceOrientationLandscapeLeft:
ret.x = uiPoint.y;
ret.y = uiPoint.x;
break;
case UIDeviceOrientationLandscapeRight:
ret.x = newY;
ret.y = newX;
break;
}
return ret;
}

This seems to work really nicely with some of the models that we have. Some of them just do not seem to work well at all.

Wednesday, December 22, 2010

22 December 2010

Seems like I have missed out something critical too. There is also this Patient Position (0018, 5100) tag that we have to factor in as well. The axes of the patient based coordinate system varies at different patient positions. The following images should illustrate this well enough:

Fig. 1 - Head First-Supine (HFS)

Fig. 2 - Feet First-Supine (FFS)

Fig. 3 - Head First-Prone (HFP)

Fig. 4 - Feet First-Prone (FFP)


Fig. 5 - Imaging Equipment

The figures above can be found from here as well, and there are also some comprehensive explanations:
http://xmedcon.sourceforge.net/Docs/OrientationXMedConPatientBased


When facing the front of the imaging equipment (refer to Fig. 5),
- Head First is defined as the patient’s head being positioned toward the front of the imaging equipment.
- Feet First is defined as the patient’s feet being positioned toward the front of the imaging equipment.
- Prone is defined as the patient’s face being positioned in a downward (gravity) direction.
- Supine is defined as the patient’s face being in an upward direction.
- Decubitus Right is defined as the patient’s right side being in a downward direction.
- Decubitus Left is defined as the patient’s left side being in a downward direction.

Here are the following terms that can be found in the Patient Position (0018, 5100) tag:
- HFP (Head First-Prone)
- HFS (Head First-Supine)
- HFDR (Head First-Decubitus Right)
- HFDL (Head First-Decubitus Left)
- FFP (Feet First-Prone)
- FFS (Feet First-Supine)
- FFDR (Feet First-Decubitus Right)
- FFDL (Feet First-Decubitus Left)


After a short discussion with Zac yesterday, I decided to look a little more into the patient-based coordinate system, in particular, to find out where the origin is. Since the position and orientation of the dicom images are provided to us with respect to the patient-based coordinate system, we would have to know where the origin is in order to map it into our models in our application. Looked around for quite some time but I cannot seem to find any sources that talks about the origin of the patient-based coordinate system.

Zac and I then had a short discussion again, and somehow we realized that we do not have a need to know the origin of the patient-based coordinate system at all. We were only loading the specific object models, not the whole human body. Hence, we would only need to know where the images should face, and at which orientation using the following 3 tags in the dicom images:
- Patient Position
- Image Position
- Image Orientation

The newly renamed images now look like this:
IM-0001-0001_x-74.798828125y-268.798828125z-82.5r100c010pFFS.png

In the case above,
x = -74.798828125
y = -268.798828125
z = -82.5
r (row vector) = (1, 0, 0)
c (column vector) = (0, 1, 0)
p (Patient Position) = FFS (Feet First-Supine)

Finally, it is time for me to move on back to work on the pan gesture to translate feature.

Tuesday, December 21, 2010

21 December 2010

Time really flies. We would be ending our internship in just 9 more weeks, including this week. Gonna miss the people and this place a lot.

Read the PDF document which I chanced upon yesterday. The tag (0020, 0032) Image Position (Patient) specifies the x, y, and z coordinates of the upper left hand corner of the image. This is also the center of the first voxel (a 3-dimensional equivalent of a pixel) that is being transmitted. This position is relative to the patient-based coordinate system:

- The x-axis is increasing to the left hand side of the patient.
- The y-axis is increasing to the posterior side of the patient.
- The z-axis is increasing toward the head of the patient.

This link further illustrates the patient-based coordinate system. It has several pictures there too:
http://www.itk.org/Wiki/Proposals:Orientation

In each image frame, the Image Position (Patient) (0020,0032) specifies the origin of the image with respect to the patient-based coordinate system.

Managed to rename a set of 76 png images with the respective image positions, but something seems to be wrong. Even with the image position, I would need to know which direction the image should be facing, and at which orientation. This definitely has got something to do with the Image Orientation (Patient) (0020,0037) tag.

Read a number of sources on the web, and it is mentioned that Image Orientation tag specifies the direction cosines of the first row and the first column with respect to the patient. Did some searching on the web, but I still do not understand what that sentence is supposed to mean.

Towards the end of the day, I managed to find a link. From there, I got to understand the Image Orientation tag. This is the tag that identifies the direction in which the image should be facing as well as it's orientation. Here's the link:
http://www.medicalconnections.co.uk/wiki/Image_Orientation_Attributes

Now, I only have the png images named with the x, y and z coordinates. In addition to that, I would have to find a way to put in the direction cosines as well, if not, we would not be able to identify where the image should face and at which orientation. Got the renaming done at the end of the day. Now, the file names look like this:

IM-0001-0001_x-74.798828125y-268.798828125z-82.5r100c010.png

In the case above,
x = -74.798828125
y = -268.798828125
z = -82.5
row vector = (1, 0, 0)
column vector = (0, 1, 0)

Monday, December 20, 2010

20 December 2010

The office seems so quiet today, as if no one's working today. Weird. Oh well, holiday season?

Started the day by continuing the search for image converters. While doing that, I realized that on Windows, the .dcm images that I have cannot be viewed properly. I downloaded some image viewers, and all of them show a black patch at the top following by a white patch at the bottom. This explains why the converters are "not work properly" when I tried them out on Thursday last week.

Decided to do the manual conversion myself. Fortunately, there is this feature in OsiriX that allows exporting of the dicom images to jpeg format. From there, I then learnt how to make use of the Automator tool in OSX to do the conversion from jpeg to png. Learnt it here:
http://www.devdaily.com/mac-os-x/batch-convert-bmp-to-jpg-png-tiff-image-files-free

Got this done pretty quickly. The tough part comes the renaming of the images. I have to fish out the position information and put it into the name of the image. But before that, I would have to find out which of the dicom's metadata refers to the images position information. I am suspecting that it is under the tag (0020, 0032) Image Position (Patient). I am still not very sure though. Found this PDF document on the web:
http://medical.nema.org/dicom/2004/04_03PU.PDF

Got to read through that to find out more, and hopefully it helps. In that document, it is said that there is also another field, called the Image Orientation (Patient) (0020, 0037). It is mentioned that this field should be provided as a pair with the Image Position (0020, 0032) field. Getting a little confused here.