Skip to content

Instantly share code, notes, and snippets.

@goweiting
Created April 27, 2018 17:13
Show Gist options
  • Save goweiting/026528c84205f49a9705b8ebd2cebd3a to your computer and use it in GitHub Desktop.
Save goweiting/026528c84205f49a9705b8ebd2cebd3a to your computer and use it in GitHub Desktop.
LUT transfer function
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#define GLUT_KEY_ESCAPE 27
#ifndef GLUT_WHEEL_UP
#define GLUT_WHEEL_UP 3
#define GLUT_WHEEL_DOWN 4
#endif
#include "mat.h"
#include "vec.h"
#include "vol.h"
#define WIDTH 128
#define HEIGHT 256
static cVolumeData *volumeData = NULL;
static float brightness = 0.75;
float ratio = 2.f;
void Update(void) { glutPostRedisplay(); }
const vec3 red(1.f, 0.f, 0.f);
const vec3 green(0.f, 1.f, 0.f);
const vec3 blue(0.f, 0.f, 1.f);
const vec3 black(0.f, 0.f, 0.f);
const vec3 white = red + green + blue;
const vec3 yellow(1.f, 1.f, 0.6f);
const vec3 darkyellow(1.f, .6f, 0.f);
const vec3 pink(1.f, .7f, 0.8f);
const vec3 darkpink(.5f, 0.f, .2f);
const float max_density = 150.;
const float min_density = 1.;
float mat_alpha [WIDTH][HEIGHT];
vec3 mat_color [WIDTH][HEIGHT] ;
// simple linear transfer function between color defined by a,b
// and t between [0,1] that find the proportion of each color
vec3 linearTF(vec3 a, vec3 b, float t){
return a * (1 - t) + b * t;
}
// Generate matrices of color values for each vorxel
void setMat(){
for (int x=0; x<volumeData->GetWidth(); x++){
for (int y=0; y<volumeData->GetHeight(); y++){
float acc_alpha = 0.f;
vec3 acc_color = vec3(0.f,0.f,0.f);
for (int z=0; z<volumeData->GetDepth(); z++){
unsigned char val = volumeData->Get(x, y, z);
vec3 col;
float vorxel_alpha;
float density = val - min_density;;
// printf("%f\n",density);
if (density < 50.){
vorxel_alpha = 0.;
col = black;
} else if (density < 80 && density >= 50.) {
// skin
vorxel_alpha = (density/ 255.) *.1;
col = linearTF(black, green, vorxel_alpha*.4); // want it to be more black than blue
} else if (density < 90 && density >= 80) {
// fat
vorxel_alpha = (density / 255.)*.5;
col = linearTF(yellow, green, vorxel_alpha*2);
} else if (density < 110 && density >= 90) {
// soft bone
vorxel_alpha = (density / 255.) *.7;
col = linearTF(white, blue, vorxel_alpha);
} else if (density < 130 && density >= 110){
// bone
vorxel_alpha = (density / 255.) * .7 ;
col = linearTF(yellow, white, vorxel_alpha * .4);
} else {
// High density bone
vorxel_alpha = density / 255 * .5;
col = linearTF(white, red, vorxel_alpha * ratio); // transparency can be increased or decreased
}
acc_alpha = acc_alpha + (1. - acc_alpha) * vorxel_alpha;
acc_color = acc_color + col*((1.-acc_alpha) * brightness) ;
if (acc_alpha >=0.8){
break;
}
}
mat_alpha[x][y] = acc_alpha;
mat_color[x][y] = acc_color;
}
}
}
void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPointSize(2.0);
glBegin(GL_POINTS);
// call the function to set the color for the cells
setMat();
// for each heigh width to draw, accumulate intensity and alpha value along the depth
for (int x = 0; x < volumeData->GetWidth(); x++) // X
{
for (int y = 0; y < volumeData->GetHeight(); y++) // Y
{
vec3 acc_color = mat_color[x][y];
glColor3f(acc_color.r(), acc_color.g(), acc_color.b());
glVertex3f(x, y, 0);
}
}
glEnd();
glFlush();
glutSwapBuffers();
}
void KeyEvent(unsigned char key, int x, int y)
{
switch (key)
{
case GLUT_KEY_ESCAPE:
exit(EXIT_SUCCESS);
break;
// Changes the color of high density bone
case GLUT_KEY_UP:
ratio = (ratio == 1.) ? 1. : ratio + .01;
break;
case GLUT_KEY_DOWN:
ratio = (ratio == 0.) ? 0. : ratio - .01;
break;
}
printf("high density bones: %f\n", ratio);
}
void KeyEventSpecial(int key, int x, int y) { KeyEvent(key, x, y); }
int main(int argc, char **argv)
{
volumeData = new cVolumeData("volumeData"); // loading volume data
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("CAV Assignment 2 [BUILD: "__DATE__
"]");
glClearColor(0.5, 0.5, 0.5, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, HEIGHT, 0, -512, 512);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glutKeyboardFunc(KeyEvent);
glutSpecialFunc(KeyEventSpecial);
glutDisplayFunc(Draw);
glutIdleFunc(Update);
glutMainLoop();
delete volumeData;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment