noviembre 13, 2006
Video-Tutorial del Visor Volumétrico de Imágenes Médicas
La presentación quedó un poco grande pues con el Wink no pude usar una paleta de colores que presentara de manera decente todas las frames del video, asi solo es tener paciencia a que el navegador cargue la presentación. Por esta razón solo se explican las funcionalidades básicas, en posteriores ocasiones si es posible pondré tutoriales sobre otras funciones más específicas, cuando pueda encontrar una buena paleta de colores para el Wink.
Aún no se si es debido a la máquina donde realicé el video o es debido al programa Wink que se degrado levemente la calidad de las imágenes, es decir que todo se ve mas claro en el programa real, pero para fines demostrativos la calidad del tutorial es más que buena.
Les sugiero que vean de que se trata este programa, vean el Tutorial y
podrán formarse un juicio de la relevancia que tiene una aplicación de este tipo.
Ahora si, vean el poder de Delphi + GLScene + Varios Algoritmos Matemáticos y de Tratamiento de Imágenes en acción!!!
noviembre 08, 2006
Distribuciones Estadísticas
En esta unidad de Delphi se encuentra la implementación como una jerarquia de clases para el manejo de una buena cantidad de distribuciones estadísticas.
El hecho de que sea una jerarquia de clases le agrega una gran versatilidad a lo que ya de por sí es una herramienta estadística muy poderosa, ya que se pueden extender sus funcionalidades tan solo agregando nuevas clases a la jerarquia o bien sobreescribiendo algunos métodos que aparecen en las clases ancestras como métodos virtuales.
Una distribución muy común es la Chi Cuadrada, ó Ji Cuadrada, muy útil para hacer pruebas de hipótesis, analisis de dependencias, correlaciones, entre otras cosas. El siguiente ejemplo muestra lo sencillo que es hacer cálculos sobre la distribución usando esta herramienta:
Pero esta es solo una de las muchas distribuciones disponibles, entre las distribuciones continuas se encuentran la Normal, Gamma, Beta, F, T de Student, Exponencial, y muchas otras, y además tambien ofrece distribuciones discretas como la hipergeométrica, Binomial, Poisson, etc.
Las posibilidades que ofrece esta herramienta son muchisimas, pues las distribuciones estadísticas tienen muchos usos en cuestiones de predictibilidad, analisis de relaciones y dependencias entre diferentes datos, definitivamente estar familiarizado con conceptos estadísticos te puede dar una gran ventaja sobre otros programadores pues puedes ofrecer productos que brinden mucha más información útil a tus clientes y con esto tener un excelente valor agregado en tus programas.
noviembre 03, 2006
El Himno de Firebird
octubre 29, 2006
Encuesta 2006 sobre Delphi
Por cierto que ya empieza Noviembre y todavia no hay noticias de quien será el comprador de la linea de los IDEs... suspenso... suspenso...
octubre 24, 2006
EasyMVC
Pero en realidad muchas veces desarrollar así de rápido trae como consecuencia de que si se hace sin orden el mantenimiento de una aplicación medianamente compleja muchas veces es insostenible, terminas haciendo lo mismo muchas veces, corregir errores es una tarea titánica que generalmente nunca terminas por hacer bien, y de pensar en dedicar un tiempo a optimizar código mejor ni hablamos.
EasyMVC es un framework de desarrollo para Delphi que pretende traer algo de orden a ese caos, está basado en el conocido modelo MVC Modelo-Vista-Controlador en el que el chiste es separar la forma en como se presentan los datos, de la manera en como se administran y de la manera en como se almacenan, este modelo ha probado su efectividad en diversos proyectos en otros lenguajes como PHP, Ruby, Java, Python, etc. En el ambiente de Delphi existen algunos Frameworks disponibles en sourceforge para su descarga, de entre estos EMvc destaca por la documentación que lo acompaña y la integración completa que tiene con el IDE.
Aún si no eres un asiduo a trabajar con Frameworks te recomiendo que le heches un ojo al código fuente de este proyecto, tiene buenos trucos que le puedes aprender, como el pesado uso que hace de las interfaces y la manera en como se integra con las diferentes versiones de Delphi.
octubre 11, 2006
Dilbert y House
Si haz seguido esta bitácora ya te habrás dado cuenta que soy un fan de la serie de Dilbert, es una lástima que en México ya no la transmitan mas por la cadena FOX, particularmente esta tira me ha hecho reir bastante sobre todo porque refleja algo que sucede muy comunmente en el ámbito corporativo, tal vez más de uno de los programadores nos identificamos con este personaje.
En lo personal si veo televisión, pero desde niño no me he enganchado con ninguna serie, las pocas veces que llegué a ver Dilbert me identifiqué de inmediato con el personaje, y la inventiva que tiene el señor Scott Adams; Otra serie que me ha enganchado es "House M.D" algunos capítulos de la serie me han parecido brillantes, tal vez porque alguna vez pensé en estudiar medicina es que me llama tanto la atención este programa y tengo ahi todavia esa espinita de conocer un poco más sobre como funciona el cuerpo humano. El escritor de esta serie resulta ser Matt Witten hermano del famóso Físico-Matemático Edward Witten, así que el ingenio esta de sobra en este programa.
Hay varias probaditas de la serie andando por youtube, yo siempre recomiendo a mis amigos la de las Descargas Ilegales, cuando se presenta con los pacientes cuando solicita la presencia de uno de sus colaboradores, y la manera en como conforta a una moribunda, ninguno tiene pierde en fin, hay muy buenos cortos de la serie por ahi, si conocen alguno bueno, compartanlo!!!
septiembre 12, 2006
Programando a ciegas...literalmente...
Siempre había tenido la fatalista idea de que nadie tiene la vida ni la suerte comprada, y me había cuestionado a mi mismo que pasaría si algún infortunio me impidiera trabajar en lo que siempre he hecho, y en mis cavilaciones había llegado a la conclusión de que de llegar a perder la vista tendría que dejar la programación y dedicarme a alguna otra cosa, y es que no me imaginaba como poder hacer diseños de interfaces, revisar código, interactuar con diferentes aplicaciones para mantener un sistema de software sin contar con los benditos ojos.
Pues Marco me ha dejado ora si que con el ojo cuadrado, el es un programador de Delphi que es ciego, y tiene un gran sentido del humor respecto a su condición, en su blog ha publicado muy interesantes artículos sobre accesibilidad, nos enseña como es que el hace para hacer el diseño de los formularios, y como es que programa en general en el IDE.
Creo que el ejemplo de Marco nos debe de inspirar a muchos a hacer mejor las cosas, siempre las personas que tienen alguna discapacidad suelen sorprendernos con lo que es capaz de lograr la voluntad del ser humano; mis respetos y toda mi admiración para este ejemplar programador.
septiembre 08, 2006
nuevos turbos, nuevas versiones
Hacia ya mucho tiempo que no tocaba esta bitácora; mucho trabajo me ha mantenido un tanto al margen de lo que se ha suscitado en el ambiente.
Ahora resulta que en el poco tiempo de mi ausencia Borland ha sacado a la luz sus nuevos Turbos, haciendonos a algunos remembrar los viejos tiempos del desarrollo sobre el otrora heroico Turbo Pascal. Yo no he tenido oportunidad de probarlos pero para los que si se han descargado mas de una de las personalidades de los Turbos y quieren poder instalar mas de uno a la vez (como decían los ingenieros de la DevCo que por cuestiones técnicas no sería posible) nuestro amigo Andy (Andreas) ha liberado una aplicación llamada TurboMerger que permite instalar mas de un Turbo en tu máquina, y lo mas curioso del caso es que Andy dice haber preguntado a Nick Hodges (quien ahora trabaja en la DevCo como director de mercadeo de Delphi) si es que era contra la licencia de los Turbos lo de instalar mas de una personalidad y este respondió que no, que al parecer era una dificultad técnica que ahora Andy ha subsanado elegantemente, recordemos que Andy también es el autor del DelphiSpeedUp del que ya habíamos hablado anteriormente en otro artículo. Y también tiene en su haber una paquete llamado DDevExtensions que permiten agregar en el BDS una paleta de componentes similar a la que traía Delphi 6-7 (para los nostálgicos y los que no terminan de acostumbrarse a la nueva barra de componentes), personalmente ahora prefiero la nueva barra, una vez que te acostumbras te haces adicto, nunca había tardado menos para encontrar un componente específico como con esta nueva barra. También el hecho de que Andy no haya infringido la licencia de los turbos al crear este TurboMerger, nos lleva a pensar si también no infringiríamos la licencia si es que llegamos a poder instalar componentes con algún truco en las versiones Explorer de estos. En fin, en definitiva este chamaco Andy es un escapao' muy muy talentoso y supongo que este a un pelito de rana calva de que lo llamen a trabajar a la Devco.
También se ha liberado la versión 1.0 de GLScene, por fin!!! Felicidades a todo el equipo.
Y esta en la calle al momento el RC4 de Firebird 2.0, ya le he dado algunos catorrazos y hasta el momento funciona bien, tiene una enorme cantidad de mejoras al nivel del dialecto SQL; ahora es mucho más sencillo hacer muchas cosas para las que antes había que hacer maroma y media. Las posibilidades que se abren con cada funcionalidad que le agregan al lenguaje son muchisimas, todavia recuerdo cuando yo pensaba que el que se hubiera agregado la función coalesce no significaba la gran cosa para mi, y ahora la uso a diestra y siniestra, incluso me pregunto como es que antes podía sobrevivir sin tenerla en Interbase 6.0. ¡¡¡¡Como cambian las cosas!!!!
junio 12, 2006
El HotFix 5 de BDS 2006 es una maravilla
Todavia de manera no totalmente oficial se ha dado a conocer un parchecillo que arregla esta contrariedad, y sobra decir que ha sido un logro de los mas aplaudidos en los foros de Borland por la comunidad de desarrolladores. Requiere tener instalado el UpdatePack 2, pero funciona mas que bien, ahora extraño menos a la versión 6 que es con la que trabajaba antes de migrar todo mi trabajo a Delphi 2006. Si sigue por ese camino le auguro un buen futuro a la nueva "DevCo", atendiendo a las necesidades reales y mas que tangibles de los usuarios es como haces que se hable bien de ti y de tus productos.
Provisionalmente se encuetra disponible en un servidor FTP, supongo que mas adelante se agregué a la sección de correcciones oficiales de Borland.
junio 02, 2006
Pascal suena en tu celular !!!
Recientemente me encontré con este IDE llamado MIDLETPascal el cual permite escribir aplicaciones que corren bajo el J2ME (Java Micro Edition) así que estos programas pueden ejecutarse en los teléfonos celulares que permiten correr aplicaciones Java.
El lenguaje es un Pascal muy sencillo y fácil de aprender y dominar en poco tiempo; y las funcionalidades a las que permite tener acceso no son pocas... Tan solo estudiando la ayuda que trae el IDE es fácil entender la gran mayoria de los tipos de aplicaciones que se pueden desarrollar y los tipos de controles que se pueden utilizar, menues, botones, listas desplegables, cajas de edición, y el poder acceder a servicios web, mensajería SMS. Además de poder programar Juegos de diferentes tipos (incluso 3D), sin mayores complicaciones. Aquí hay una api que permite abstraer muchas funcionalidades que se necesitarían para realizar un juego con MidLetPascal.
La versión de uso personal es gratis pero la versión comercial tiene un precio muy accesible para quien lo llegase a requerir.
¿Y poder comprimir las aplicaciones resultantes? también es posible usando ProGuard
mayo 13, 2006
CVS Snapshot de GLScene al 10 de mayo
Como puntos destacables están el que en este snapshot viene el paquete de instalación tanto para Delphi 2006 como para Lazarus, cabe mencionar que se han hecho grandes avances en el desarrollo sobre Lazarus. Creo que esto va a potenciar bastante el uso de Lazarus para aplicaciones gráficas.
En lo particular yo aún encuentro un poco "molesto" el trabajo con Lazarus, el ide aún me parece un tanto inestable y de comportamientos erráticos... me ha pasado por la cabeza iniciar una aplicación real de gestión sobre este IDE pero hasta ahora lo que he visto que se ha hecho me parece muy modesto en comparación con las posibilidades que ofrece Delphi.
En fin, larga vida a Lazarus!! pero que sea una vida de verdadero aprovechamiento, ojalá no se quede como el hermanito "wanabe" de Delphi.
mayo 04, 2006
Extendiendo la VCL sin usar herencia ni registrando componentes nuevos
Existen algunas practicas que permiten variar el comportamiento de los componentes que trae Delphi por defecto sin hacer derivaciones de las clases registradas, lo cual permite que sin instalar nada en el IDE tengamos el resultado que deseamos. Una de esas técnicas la describo un poco en el artículo Alternativas a los Skins y es la técnica de las clases sobrepuestas, pero en Delphi 2006 esta no es la única opción... existe una técnica mas estilizada y que se apega más a las buenas costumbres orientadas a objetos.
En BDS 2006 y desde Delphi 8 existe una extensión del lenguaje de Object Pascal llamada Class Helpers esta nueva característica nos permite definir nuevos comportamientos para alguna clase previamente definida de manera natural y su práctica nos ofrece muchos beneficios. Vamos a un ejemplo:
Muchos de nosotros usamos la funcion Trim() de Delphi que elimina los espacios en blanco al principio y al final de una cadena, y solemos usarla en controles como el caso del TEdit con código como este:
Edit1.Text := Trim(Edit1.Text);
Pero, ¿no sería mas claro y elegante que el control Edit1 tuviera un método Ajustar() que hicera eso directamente sobre el control?, veamos como implementariamos eso, primero definimos la clase que servira como ayudante de la clase TEdit.
TMiEdit = class helper for TEdit
public
procedure Ajusta;
end;
He llamado a la clase auxiliar TMiEdit ya que en esta técnica la clase auxiliar no tiene que llevar el mismo nombre de la clase a la que estamos ayudando, y ahora definimos el método nuevo:
procedure TMiEdit.Ajusta;
begin
Text := Trim(Text);
end;
Observen que como esta clase es una ayudante de TEdit puedo acceder a las propiedades de la misma clase TEdit, en este caso la propiedad Text, ahora para hacer uso del nuevo método no tengo que crear nuevas instancias solo usar un objeto común de la clase TEdit de este modo:
procedure TForm2.Button1Click(Sender: TObject);
begin
Edit1.Ajusta;
end;
Pero tambien se pueden modificar métodos de la clase afectada, por ejemplo si quisieramos hacer que al llamar al método Clear del TEdit este en vez de poner una cadena nula pusiera por defecto un cero, hariamos algo como esto:
TMiEdit = class helper for TEdit
public
procedure Clear; overload;
end;
procedure TMiEdit.Clear;
begin
Text := '0';
end;
begin
Edit1.Clear;
end;
En este caso estamos sobrecargando el método Clear pero al ser este un método re-definido en la clase ayudante se toma este último por defecto.
Esto suele sernos útil en casos donde por ejemplo tenemos que ajustar controles como el TDBGrid para que soporte la ruedita del ratón, o para que cambie de casilla con la tecla Enter, o para Editar campos Memo en las celdas, etc... usando el control TDBGrid de toda la vida.
Las limitaciones que tiene esta técnica son que desde las clases ayudantes no se puede tener acceso a propiedades o métodos declarados como estrictamente privados o estrictamente protegidos, asi como tampoco permite la definición de datos adicionales, es decir que no se pueden declarar variables de campos en estas clases auxiliares; lo único que se permite es que se púeden definir variables de clase (una nueva característica tambien), es decir variables que serán comunes a todas las instancias de la clase ayudada, esto es útil para por ejemplo poder llevar la cuenta de cuantas instancias de X clase se han creado y de alguna manera implementar variantes del patrón de diseño singleton sobrecargando el constructor de la clase.
abril 24, 2006
Delphi SpeedUp for BDS
Aqui está el instalador del plugin, pero creo que aún más interesante es el poder acceder al código fuente del que se pueden aprender enormidades, estos fuentes estan comprimidos en formato 7Zip.
Este plugin esta basado en las librerias FastCode y FastMove, echandoles un ojo puede uno ver el portento de trabajo en ensamblador que se le ha dedicado. Yo lo he instalado en BDS2006 y si he notado un incremento en el desempeño del IDE, ya me dirán si es un común en todas las configuraciones.
marzo 07, 2006
Alternativas a los skins
Algunos usan sus propios componentes, es decir su propio TEditSkineado, TPanelEskineado, etc, el problema con eso es que obviamente cuando los usas te obligas a reescribir tu aplicacion o al menos pasarle un experto que cambie los nombres de las clases de los controles que ahora serán del nuevo tipo; y tambien con eso ya te estas
Otros como VCLSkin son mas flexibles, con solo poner un simple componente en tu formulario principal te cambia la apariencia de la aplicación por completo, abarcando incluso cuadros de dialogo y demás chunches propios de windows
Aqui vamos a discutir una alternativa al uso de estas herramientas que son de pago (aunque algunas realmente valen lo que cuestan si la apariencia es tan importante para ti), y lo haremos usando una técnica ancestral que nos provee Delphi y a la que se le llama "Clases Sobrepuestas". Es increible cuanto mejora la apariencia de una ventana tan solo usando colores agradables y redondeando las esquinas de los componentes contenedores, aqui va el ejemplo vamos a estudiar como hacer que esto en diseño:
se vea en ejecución como esto:
Sin usar componentes de terceros y sin tener que cambiar los componentes que ahora estas usando en tu aplicación común y corriente de Delphi.
La idea es muy simple, vamos a hacer una unidad que será la que pongas al final de la sección uses de tu forma en la parte de la interfase; ahora, esto es importante, la unidad que contenga las clases sobrepuestas debe ser la última en la lista del uses, sino podria no funcionar el truco, por lo menos no para las clases que esten contenidas en las unidades que se encuentren despues de la nuestra.
Primero creamos una nueva unidad llamada GTPaneles.pas, y definamos algunos parámetros configurables al gusto de cada quien...
const
CnstArco = 35;
CnstBotonNormal = clMoneyGreen;
CnstBotonPress = clGray;
CnstTagDisable = 99;
la constante CnstArco definirá que tan pronunciados queremos que sean los arcos de las esquinas redondeadas, las siguientes dos constantes definen los colores que tendrán los botones en los estados normal y cuando estan presionados, y por último definimos un valor para diferenciar a aquellos componentes a los que no quisieramos que se les aplique el proceso de "embellecimiento", esta técnica la usa VCLSkin, donde si a algun panel no quisieras que se le aplique el Skin solo basta con poner el valor 99 en la propiedad Tag de dicho componente.
Yo suelo utilizar la propiedad Tag de los componentes para algunos trucos al nivel de la interface de las aplicaciones, si ese es tu caso tambien tendrías que hacer algunos malabares para que esto no te ocasione problemas
Para ejemplificar el trabajo lo haremos con la clase TPanel, y mostraremos la parte mas simple del asunto, aqui hacemos la sobreposición de la clase:
TPanel = class(ExtCtrls.TPanel)
protected
procedure Paint; override;
end;
Definamos un par de procedimientos genéricos que usaremos despues en la implementacion de los métodos de las clases sobrepuestas:
Este procedimiento borra el fondo donde se ha de dibujar el control y prepara el terreno para dibujar nuestra obra de arte.
procedure QuitarFondo(Control: TControl; Dest: TCanvas);
var
SaveIndex: Integer;
DC: HDC;
Position: TPoint;
begin
with Control do
begin
if Parent = nil then
Exit;
DC := Dest.Handle;
SaveIndex := SaveDC(DC);
{$IFDEF PDJ_2}
GetViewportOrgEx(DC, @Position);
{$ELSE}
GetViewportOrgEx(DC, Position);
{$ENDIF}
SetViewportOrgEx(DC, Position.X - Left,
Position.Y - Top, nil);
IntersectClipRect(DC, 0, 0, Parent.ClientWidth,
Parent.ClientHeight);
Parent.Perform(WM_ERASEBKGND, Integer(DC), Integer(0));
Parent.Perform(WM_PAINT, Integer(DC), Integer(0));
RestoreDC(DC, SaveIndex);
end;
end;
Este otro dibuja ya formalmente los rectangulos redondeados de modo que de la perspectiva 3D.
procedure DibujaRedondeado(const C: TCanvas; R1:
TRect; Color: TColor);
var R2: TRect;
begin
//Guardamos el Rectangulo original
R2 := R1;
with C do
begin
Pen.Width := 1;
//Dibujamos la sombra
inc(R1.left, Pen.Width);
inc(R1.top, Pen.Width);
pen.Color := clbtnhighlight;
Brush.Style := bsSolid;
Brush.Color := Color;
RoundRect(R1.Left, r1.top, r1.Right, r1.Bottom,
CnstArco, CnstArco);
pen.Color := color;
Brush.Style := bsclear;
inc(R1.left, Pen.Width);
inc(R1.top, Pen.Width);
RoundRect(R1.Left, r1.top, r1.Right, r1.Bottom,
CnstArco, CnstArco);
//Dibujamos la base...
pen.Color := clBlack;
Brush.Style := bsclear;
r1 := R2; //Recuperamos el rectangulo original...
RoundRect(R1.Left, r1.top, r1.Right, r1.Bottom,
CnstArco, CnstArco);
Brush.Style := bsSolid;
end;
end;
Despues de eso solo basta con codificar la nueva versión del método Paint del componente mandando a llamar a los dos métodos que ya vimos:
procedure TPanel.Paint;
begin
if (Tag <> CnstTagDisable) then
begin
QuitarFondo(Self, Canvas);
DibujaRedondeado(Canvas, GetClientRect, Color);
end else inherited;
end;
Para el caso de los botones y los TGroupBoxes el procedimiento es similar con la variante de desplegar el texto o el caption del componente en cuestión, e incluso se puede hacer una variante que dibuje tambien los Glyphs de los botones, pero yo por lo menos mi versión la he dejado hasta ahi; si alguien continua con este desarrollo hagamelo saber. También sobre BDS 2006 se pueden hacer uso de los nuevos eventos OnMouseEnter y OnMouseLeave para dar más efectos a los componentes.
En la sección de archivos de este blog esta disponible para descargar un demo completo de lo aqui explicado, seguro que con un poco mas de dedicación se puede ampliar la unidad para que soporte mas clases y con mejor apariencia.
¿cuestion de inspiración??
Esto que algunos llaman suerte creo que esta más bien orientado a la inspiración... pero tambien esa inspiración pudiera estar conllevada con el ambiente, la situación social, economico, familiar que el susodicho programador haya tenido en su momento. Porque es bien sabido que por mas brillante que suela uno ser, en un momento de aflicción o sobrecogimiento no se rinde igual, ni fluyen las ideas con tanta facilidad como cuando todo en la vida es miel sobre hojuelas.
Seria bueno que se comentara aqui que tanto piensan que influye realmente el entorno en el desempeño de un programador, que tanto influye el tener un buen sueldo, una buena esposa (porque no?), minimos problemas en general para tener un destacable desempeño creativo.
Ahora que si a inspiraciones vamos, yo debo declararme como un fan de la música de trova y en mi opinión es una música de inspiración sublime. Para muestra un botón, aqui está un fragmento de una canción de "El Mago" Abel Velasquez, ya me dirán si esto no es inspiración; son palabras que muchas veces no sabe uno a ciencia cierta como decir, descritas de la manera mas sublime, asi que tomen nota... con dedicación especial para mi chaparra...
febrero 23, 2006
Libros, libros y mas libros....
http://www.elib.hbi.ir/computer/comp-index.htm
Muchos titulos de los que ahi aparecen ahora forman parte de mis libros de consulta de primera mano.
febrero 14, 2006
Delphi guapachoso!!!
La letra del tema creo que sería solo para entendidos del Delphi, no me imagino que una ama de casa común que la llegue a escuchar en la radio sepa que quiere decir eso de :
...para que no tenga igual le exporte una interface, ya es un objeto COM y lo herede de otra clase...
pero tambien meditandolo creo que hay muchas canciones modernas a las que no se les entiende gran cosa y son super-exitos, asi que ojalá que a estos cuates les vaya de P.M. y que pronto hagan su primer millón como dicen los Bacilos.
La canción la pueden descargar aqui, y para quienes no esten tan familiarizados ABM son las iniciales de Altas-Bajas-Modificaciones algo que es lo común y de lo que muchos nos regodeamos con el slogan de la canción: "Mi ABM es el mejor"
febrero 08, 2006
Otra comparativa de velocidad de DB's
http://www.sqlite.org/cvstrac/wiki?p=SpeedComparison
Creo que es muy buena referencia para los que luego preguntan que tal es Firebird comparado contra PosgreSQL por citar un ejemplo.
enero 21, 2006
Mi visor volumétrico de imágenes médicas
Esta dividido en dos partes, la parte de analisis bidimensional de las imágenes, en donde se puede de una manera muy simple y práctica adecuar los niveles de brillo y contraste en los colores de la imágen, efectuar mediciones milimétricas dentro de la imagen al tamaño real del objeto del que fue tomada, cambiar los tonos y los niveles, efectuar acercamientos a ciertas areas (Zoom), etc...
Y la parte de vision volumétrica, la cual es la que permite hacer la exploración 3D de los cuerpos que se representan en dichas imágenes médicas, pudiendose aplicar, planos de corte, transparencias, eliminacion de cuerpos basado en la densidad mostrada en las imágenes, rotaciones, traslaciones, etc...
Aquí algunos screenshots de la aplicación. Pueden dar click en las imágenes para verlas en tamaño completo.
DICOM es un estandar en la medicina en cuanto a la forma en como se almacenan y tratan las imágenes médicas, y practicamente todos los equipos modernos de radiografía, tomografía, ultrasonido o resonancia magnética trabajan con imágenes en formato DICOM, por lo que ahora es muy común que al paciente se le entregue ademas o en vez de las tradicionales placas de sus estudios, un CD con las imágenes en formato DICOM, con lo cual este programa puede construir todo el modelo tridimensional sin problema alguno y mostrarselo al paciente en el propio consultorio del médico.
Generalmente esto es posible solo con equipos y software muy caro y el ambito esta restringido a los radiologos que cuentan con este equipo, pero ahora con esta aplicación, la idea es que cualquier médico en su consultorio pueda obtener la imágen volumetrica de los analisis que reciben sus pacientes. y asi incluso mostrarle al paciente el modelo real en 3D de su propio cuerpo en el mismo consultorio, tal vez para mostrar la evolución de alguna fractura o algún otro padecimiento.
Otra aplicación que se me ocurrió es en el ámbito académico, con esta aplicación los alumnos podrán obtener una mejor idea de lo que significan las imágenes médicas así como poder hacer exploraciones mas a detalle de sus estudios pues las posibilidades son infinitas cuando se tiene una vision tridimensional de las cosas a verse forzado a hacer un análisis puramente en 2D.
En este momento nos encontramos al final de la etapa de desarrollo de este producto, pero aún tenemos espectativas que se pueden contemplar para este, tales como el reconocimiento de organos automático dentro del volumen para poder hacer discriminaciones basadas no solo en la densidad de lo que se ve sino en las texturas de los tejidos, etc... asi como la construccion biplanar de modelos para simplificar y abaratar aun mas el proceso para un radiologo de obtener el estudio.
En fin, esas son solo algunas cosas que se me han ocurrido, espero que a partir de esto se me ocurran mas. Y estoy ávido tambien de que quienes lean esto me puedan dar más ideas de todo tipo, de programación, estilo, cientificas, comerciales, etc. Así que pueden sentirse con entera libertad de publicar sus comentarios al respecto.
enero 18, 2006
De vacaciones pero trabajando...
De momento me encuentro de vacaciones, disfrutando del jarochismo en mi estado natal de Veracru' señores, ya extrañaba las arpas, jaranas y marimbas tipicas de esta región, ciertamente no hay lugar como el hogar.
Pero pues hasta en vacaciones no puedo dejar de programar, he aprovechado este viaje para saludar a viejos amigos de la Maestría de Inteligencia Artificial y a la vez pedirles consejo y asesoría para algunos proyectos que traigo entre manos, espero que el tiempo que me quede por aca me alcance para poder despejar el mar de dudas que tengo sobre algunos escabrozos temas como Redes Bayesianas para la minería de datos y Redes Neuronales para un proyecto de reconocimiento de patrones.
También estoy aprovechando estos dias de desasosiego para terminar de estudiar algunas conferencias de la última DevCon son muchas conferencias y con lo agitados que suelen ser los dias de trabajo no hay mucho tiempo para estudiar los videos y presentaciones que estan disponibles para su descarga. Hasta ahora me han parecido muy interesantes las conferencias de Marco Cantú entre otras.
Tambien cuando deja uno de estar en linea por un tiempo quedan muchas cosas por revisar en foros y blog's para ponerse al día, por eso me pareció muy interesante este plugin de búsqueda para Firefox que permite buscar en los grupos de noticias de Borland, uno de los mas grandes y mejores repositorios de respuestas a miles de preguntas sobre el ambiente de la programación.
Bueno por el momento así estan las cosas, ahora permitanme que tengo un asunto pendiente que arreglar con el XBox de mi hermano y el Halo 2
enero 04, 2006
Por fin sobrecarga de operadores en Delphi
Por ejemplo, para implementar como una estructura el manejo de números fraccionarios usabamos algo como esto:
TFraccionario = record
numerador, denominador: integer;
end;
Ahora tenemos la posibilidad de agregar operadores que se encarguen de la transferencia de información asi como de las operaciones entre las estructuras, por ejemplo agregando el operador implicit :
TFraccionario = record
numerador, denominador: integer;
class operator implicit( Value: TFraccionario): string;
end;
y su implementación:
class operator TFraccionario.implicit(Value:
TFraccionario): string;
begin
Result := IntToStr(Value.Numerador) + '/'+
IntToStr(Value.Denominador);
end;
Ahora podemos asignar una variable de tipo TFraccionario a una simple y sencilla cadena asi:
var
R1 : TFraccionario;
S: string;
begin
R1.Numerador := 2;
R1.Denominador := 6;
S := R1; //Aqui S valdria literalmente "2/6"
Y también a la inversa, podemos definir un comportamiento de operador para cuando queremos asignar una cadena a una variable de tipo TFraccionario
class operator implicit( Value: string) : TFraccionario;
Y lo implementamos haciendo un parseo muy simple para la cadena, al fin de cuentas nadamas estamos ilustrando un ejemplo, no es la idea poner un parser completo sino mostrar el funcionamiento de los operadores
class operator TFraccionario.implicit(Value: string):
TFraccionario;
var p : integer;
begin
Result.numerador := 0;
Result.denominador := 0;
p := Pos('/',Value);
if P = 0 then exit;
Result.numerador := StrToIntDef(Copy(Value,1,P-1),0);
Result.denominador := StrToIntDef(Copy(Value,P+1,
Length(Value)),0);
end;
Y una vez hecho esto ya podemos asignar cadenas a variables de tipo TFraccionario, de esta manera:
var
R1 : TFraccionario;
begin
R1 := '2/6';
Pero, ¿como sumariamos 2 números fraccionarios usando directamente el operador +?, pues bien para eso pondríamos una definición de operador llamada add dentro de la misma estructura del registro, ahora la declaración del tipo completo sería:
TFraccionario = record
numerador, denominador: integer;
class operator implicit( Value: TFraccionario): string;
class operator implicit( Value: string) : TFraccionario;
class operator add( v1, v2 : TFraccionario): TFraccionario;
end;
Y la implementación del operador (si mis maestros de la primaria no me engañaron) sería algo como esto:
class operator TFraccionario.add(v1, v2: TFraccionario):
TFraccionario;
begin
if (V1.denominador = V2.denominador) then
begin
Result.denominador := V1.denominador;
Result.numerador := V1.numerador + V2.numerador;
end
else
begin
Result.numerador := (V1.numerador * V2.denominador) +
(V1.denominador * V2.numerador );
Result.denominador := V1.denominador * V2.denominador;
end;
end;
Si, si, ya se que tambien se podría simplificar el número a su mínima expresión una vez efectuada la suma, pero prefiero dejarlo así por ahora para que no se complique en demasía el algoritmo y podamos admirar el trabajo con los operadores en vez de eso.
Ahora a poner a prueba el trabajo que hicimos, y a hacer también porque no algunos experimentos, primero veamos como podemos inicializar dos números fraccionarios a partir de un par de cadenas y sumemos ambos números y mostremos el resultado de la operación también en una cadena, para hacer uso de todos los operadores que hicimos, para eso ponemos un TButton en el formulario y le codificamos esto en el evento OnClick:
procedure TForm2.Button1Click(Sender: TObject);
var
R1,R2 : TFraccionario;
begin
R1 := '2/6';
R2 := '3/6';
Caption := R1 + R2; //Esto devuelve "5/6" en el caption
end;
¡Bastante práctico!, ¿no es cierto?... ¿pero ahora si en vez de que se aplicara la operación entre ambos números fraccionarios lo que nos interesara fuera obtener la concatenación de sus representaciones como cadenas???, bien en ese caso lo que hay que hacer es tratar a ambas variables como cadenas para que el operador que nosotros definimos pierda su efecto y en vez de esto se aplique el operador predeterminado para el trabajo con cadenas, en este caso la concatenación:
Caption := string(R1) + string(R2); //Esto devuelve "2/63/6"
¡Fantástico!, y ¿podríamos hacer combinaciones?? es decir,¿ aplicar el operador con secuencias de operandos de diferentes tipos??... Si, claro y también esto ofrece un gran poder, solo hay que ver esto:
Caption := R1 + R2 + '1/6'; //Esto devuelve "6/6" !!!
¡Estupendo!!...de la misma manera podriamos definir muchos mas operadores para el trabajo con números fraccionarios, por ejemplo:
- Add +
- Substract -
- Multiply *
- Divide /
- Negative -
- Equal =
- NotEqual <>
- LessThan <
- LessThanOrEqual <=
- GreaterThan >
- GreaterThanOrEqual >=
Con lo que hemos visto hasta ahora es fácil imaginarse como sería la implementación del resto de los operadores, suerte y a practicar esta nueva funcionalidad.