Sunteți pe pagina 1din 45

Grupo de Visión Artificial

Procesamiento de Imágenes
Biomédicas (PIB)
Autor: Isaac Peñalosa Solana
Tutor: Carlos Platero Dueñas
1 INTRODUCCIÓN ..................................................................................................................4

2 COMO HACER UNA AYUDA .............................................................................................5

2.1 CARACTERÍSTICAS DEL FORMATO TEXTO: ......................................................................5

2.2 CARACTERÍSTICAS DE WINHELP:....................................................................................6


2.2.1 ESCRIBIR EL TEXTO DEL ARCHIVO DE AYUDA PRINCIPAL..........................................6
2.2.2 AÑADIR PIES DE PÁGINA A LA PANTALLA DE ÍNDICE DE CONTENIDOS ......................6
2.2.3 INSERTAR PIES DE PÁGINA A LA PANTALLA DE AYUDA DEL TEMA1 ..........................7
2.2.4 DUPLICAR LA PANTALLA DE AYUDA DEL TEMA 1 .....................................................7
2.2.5 GUARDAR EL DOCUMENTO ........................................................................................8
2.2.6 ESCRIBIR UN ARCHIVO DE PROYECTO DE AYUDA ......................................................8
2.2.7 CONSTRUIR EL FICHERO DE AYUDA ...........................................................................9
2.2.8 EJECUTAR WINHELP CON EL NUEVO ARCHIVO DE AYUDA ........................................9

2.3 CARACTERÍSTICAS DE HTMLHELP .................................................................................9


2.3.1 CON EDITORES DE AYUDA, COMO HTML HELP EDITOR............................................9
2.3.1.1 Crear el proyecto de ayuda.............................................................................................. 10
2.3.1.2 Editar los contenidos ....................................................................................................... 11
2.3.1.3 Editar las páginas de ayuda ............................................................................................. 13
2.3.1.4 Editar el índice ................................................................................................................ 13
2.3.1.5 Compilar y crear el proyecto ........................................................................................... 14
2.3.2 CON VISUAL STUDIO ...............................................................................................16
2.3.2.1 Crear un nuevo proyecto ................................................................................................. 16
2.3.2.2 Editar los ficheros generados .......................................................................................... 17
2.3.2.3 Compilar el proyecto y generar la solución..................................................................... 20

3 COMO MAXIMIZAR UN CUADRO DE DIALOGOS ...................................................21

3.1 MÉTODOS DE LA CLASE CDLGANCHOR .........................................................................21

3.2 MÉTODOS DE LA CLASE CDLGMAN ................................................................................22

3.3 PASOS PARA MAXIMIZAR EL DIALOGO ...........................................................................22


3.3.1 CREAR UN PROYECTO MFC BASADO EN CUADRO DE DIÁLOGOS ............................22
3.3.2 POSIBILIDAD DE MAXIMIZAR EL DIALOGO ...............................................................23
3.3.3 AGREGAR LAS CLASES AL PROYECTO ......................................................................23
3.3.4 REESCRIBIR LOS FICHEROS .CPP Y .H .......................................................................24

3.4 PEQUEÑO EJEMPLO DE MAXIMIZACIÓN .........................................................................26

4 ADQUISICIÓN DE VIDEO EN WINDOWS ....................................................................27

4.1 CAPTURAR VIDEO CON UNA CÁMARA USANDO C# .........................................................27


4.1.1 VIDEO FOR WINDOWS ..............................................................................................27
4.1.2 PRIMERO SE VERÁ COMO SE HACE EN C++, DESPUÉS EN C# ...................................27

4.2 CAPTURAR VIDEO USB DIRECTX....................................................................................33


4.2.1 INTRODUCCIÓN ........................................................................................................33
4.2.2 PASOS A SEGUIR .......................................................................................................33
4.2.3 REQUERIMIENTOS ....................................................................................................34

5 VISUALIZADOR DE HALOCOUNT, CLASE CPICTURE...........................................35

5.1 LA FUNCIÓN VISUALIZARIMAGEN (CSTRING NOMBREIMAGEN) ..................................35

6 OBJETOS COM ...................................................................................................................37

6.1 CONSTRUYENDO UNA APLICACIÓN .................................................................................37


6.1.1 ELEMENTOS DE MATLAB BUILDER PARA UN PROYECTO COM ............................37
CLASES ....................................................................................................................................37
6.1.2 CREANDO UN PROYECTO .........................................................................................38
6.1.3 GESTIONANDO LOS FICHEROS M-FILE Y MEX-FILE ...............................................40
6.1.4 COMPILANDO EL PROYECTO ....................................................................................40
6.1.4.1 Build Status ..................................................................................................................... 40
6.1.5 EMPAQUETADO Y DISTRIBUCIÓN DEL COMPONENTE ...............................................41

6.2 CREACIÓN DE OBJETOS COM EN MATLAB ....................................................................42


6.2.1 GENERACIÓN DEL CÓDIGO:......................................................................................43
6.2.2 CREACIÓN DE LA DEFINICIÓN DE INTERFACES: .......................................................44
6.2.3 COMPILACIÓN C++: .................................................................................................44
6.2.4 ENLAZADO Y RELACIÓN DE RECURSOS: ..................................................................44
6.2.5 REGISTRO DEL COMPONENTE: .................................................................................44
1 Introducción

Este proyecto pertenece Grupo de Visión Artificial (GVA) de la Escuela


Universitaria de Ingeniería Técnica Industrial de la UPM, en la cátedra del ELAI de
dicha escuela.
El objetivo principal de este grupo es el desarrollo de software para el
procesamiento de imágenes biomédicas.
Con el uso de la informática se han desarrollado distintas aplicaciones para
ayudar a los médicos y hacer sus labores más sencillas.
En este preproyecto, nos proponemos realizar el desarrollo, documentación y
mejora de “HaloCount”. Aplicación cuya finalidad es la del análisis de la calidad del
esperma Humano mediante técnicas SDC (Sperm Chromatin Dispersion).
En el tema de la documentación, se utilizará HTML Help. Explicando paso a
paso como realizar una buena ayuda para las aplicaciones, en este caso para Halocount.
Se explicará cómo utilizar códigos reutilizables en nuestros GUI’s, para la
maximización de diálogos. Se vera cómo descargarlo, y por último un ejemplo de
código para ver como funciona, así como poder descargar y utilizar el código para
visualizar imágenes en la aplicación Halocount.
También se explica como capturar video desde un dispositivo WebCam
conectado vía USB. Para capturar imágenes que posteriormente procesaremos con la
aplicación Halocount. El procesamiento de las imágenes está en este momento en pleno
desarrollo por lo que se expondrá en el proyecto final.
Por último explicaré como realizar objetos .COM desde Matlab y cómo
utilizarlos en programas implementados en C++.
2 COMO HACER UNA AYUDA
En esta parte se verá que es una ayuda y como se pueden hacer dependiendo del
formato en que se quieran hacer.
Las ayudas son archivos de texto, texto enriquecido o Web que permiten al
usuario conocer mejor el funcionamiento y los pasos a seguir para ejecutar el programa.
Cuando se hace un programa, siempre se debe incluir con el una ayuda por si el
usuario tiene alguna duda o le surge un problema, para que pueda solucionarlo.
Existen distintos tipos de ayudas según el formato que tengan, pueden ser .txt,
.doc, .chm, .hlp.

2.1 Características del formato texto:


Si es de tipo texto sólo es un documento de consulta y se incluirá en la
instalación del programa.
Los otros dos tipos en apariencia son prácticamente iguales a diferencia del
formato que tengan.
2.2 Características de WinHelp:
Existen diversas herramientas para la creación de ficheros de ayuda de
Windows, tales como RoboHelp o ForeHelp.
Para escribir un fichero de ayuda, no hace falta programar en C++. Los pasos
necesarios son los siguientes:

2.2.1 Escribir el texto del archivo de ayuda principal


Para ello se utiliza Microsoft Word (o cualquier editor de texto compatible con
RTF)

Es preciso asegurarse de que se han aplicado correctamente los estilos de doble


subrayado y de texto oculto, y de que se han insertado el salto de página en el lugar
adecuado.

2.2.2 Añadir pies de página a la pantalla de índice de contenidos


La pantalla de índice de contenidos es el primer tema de ayuda del sistema. Hay
que insertar los siguientes pies de página al comienzo del titulo del tema, usando las
siguientes marcas personalizadas de pie de página:
Al terminar, el documento deberá parecerse al siguiente:

2.2.3 Insertar pies de página a la pantalla de ayuda del tema1


La pantalla de ayuda del tema 1 es la segunda pantalla temática del sistema de
ayuda. Para crearla es preciso insertar los pies que se indican, utilizando las marcas de
pie de página siguientes:

2.2.4 Duplicar la pantalla de ayuda del tema 1


Se tiene que copiar la sección completa del documento , que corresponda a la
pantalla de ayuda del tema 1, incluido el pie de pagina, e insertarlo tantas veces como
temas sean necesarios, cambiando las referencias del tema 1 por 2, 3…
Al finalizar ese paso el documento debería quedar así:

2.2.5 Guardar el documento


Se deberá guardar el documento con el nombre deseado pero con formato de
texto enriquecido, es decir .rtf.

2.2.6 Escribir un archivo de proyecto de ayuda


Ahora hay que crear con Visual C++, el archivo EjemploAyuda.hpj
Que contendrá:

[OPTIONS]

CONTENTS=HID_CONTENTS

TITLE=SIMPLE: Programa de ayuda

COMPRESS=true

WARING=2

[FILES]

EjemploAyuda.rtf
Este archivo especifica el identificador de contexto de la pantalla índice de
contenidos y el nombre del fichero RTF que contiene el texto de ayuda. Es preciso que
el fichero de ayuda esté guardado con formato texto (ASCII).

2.2.7 Construir el fichero de ayuda


Desde Windows ejecutar Microsoft Help Workshop (HCRTF) situada por
omisión en archivos de programa/ Microsoft Visual Studio/Common/Tools. Después
abrir el fichero EjemploAyuda.hpj y pulsar en el botón <<Save and Compile>>.
Con esto se ejecuta el compilador de ayudas de Microsoft. El resultado es
EjemploAyuda.hlp que se guarda en el mismo directorio donde tengamos guardado el
proyecto de ayuda.

2.2.8 Ejecutar WinHelp con el nuevo archivo de ayuda


Desde el explorador de Windows abrir el archivo EjemploAyuda.hlp.
Se mostrara la pantalla de índice de contenidos

2.3 Características de HTMLHelp

Las ayudas HTMLHelp se pueden hacer de dos formas distintas, con Visual
Studio.NET, o con editores de ayuda como HTMLHelp WorkShop

2.3.1 Con editores de ayuda, como HTML Help editor


Con este editor se crean todos los archivos para el proyecto de ayuda, de esta
manera la ayuda quedara independiente del programa se deberá incluir en la instalación
del mismo para que el usuario tenga acceso a ella, también se podrá incluir en el
programa como una barra de herramientas o como un botón en el dialogo principal del
programa escribiendo el código necesario con Visual Studio.
A la hora de crear un proyecto de ayuda con HTMLHelp WorkShop los pasos a
seguir son los siguientes:
2.3.1.1 Crear el proyecto de ayuda
Para crear el proyecto se debe abrir el programa HTMLHelp WorkShop
Una vez se haya abierto. Archivo nuevo proyecto, se especifica la ubicación
donde se desea guardar y después se crean los ficheros que se quiere incluir en el
proyecto tabla de contenidos, índice y los archivos html.

Después nos quedara una cosa así:


2.3.1.2 Editar los contenidos
Para editar los contenidos se sitúa en la pestaña de contenidos:

Para añadir un tema se hace clic en el botón insertar una cabecera y aparecerá

Donde se debe escribir el nombre del titulo, después clic en <<Add>> para
añadir la pagina htm con el tema y aparecerá:
Aquí se debe escribir el fichero o la URL de la página htm que contiene el tema,
que mas tarde se editará.
Para editar los temas se hará igual pero haciendo clic en insertar página
añadiendo la URL de la pagina Web con el tema
Una vez insertado las cabeceras y los temas quedara algo así:
2.3.1.3 Editar las páginas de ayuda
Para escribir la ayuda del programa, necesitaremos de un editor de páginas Web
como Microsoft FrontPage, ya que cada página de la ayuda es un fichero de tipo .htm.
Al tratarse de un fichero .htm ser pueden incluir en ellas texto, imágenes, links,
etc.

2.3.1.4 Editar el índice


Para editar el índice se hará de igual manera que al editar los contenidos, pero
haciendo clic en el botón insertar keyword .
Aparecerá el siguiente diálogo:

Dónde se escribirá la palabra deseada que se relacionara con la página Web


deseada haciendo clic en <<Add>>.

2.3.1.5 Compilar y crear el proyecto


Cuando estén escritas todas las páginas de la ayuda, en el editor de ayuda se
debe compilar el proyecto para crear el fichero compilado de ayuda que tendrá
extensión .chm y el usuario solo deberá abrir este fichero para ver la ayuda desde el
explorador de archivos o desde el propio editor haciendo clic en el botón ver archivo
compilado.
En las ventanas de ayuda hay dos partes diferenciadas, en la izquierda se ven tres
pestañas distintas en las cuales se ven el contenido, el índice para buscar palabras, y una
búsqueda para realizar la búsqueda por temas.
Y la parte derecha es donde se ve la ayuda, dependiendo de cómo haya sido
escrita se podrá navegar por ella sin necesidad de utilizar la parte de la izquierda, a no
ser que se desee hacer una búsqueda por palabras.
2.3.2 Con Visual Studio

2.3.2.1 Crear un nuevo proyecto


Al crear el proyecto en el que se valla a trabajar, se añade la ayuda contextual,
con esto se agrega al proyecto los ficheros necesarios para hacer la ayuda y un botón en
al cuadro de diálogos del programa.
Para esto se hace lo siguiente:
En el asistente para crear nuevas aplicaciones se selecciona la característica de
que sea basada en cuadro de diálogos.
Y en las características avanzadas se debe seleccionar la ayuda
contextual en el formato deseado, en este caso con formato HTML.

Con esto se habrá generado un proyecto MFC basado en cuadro de diálogos con
ayuda contextual de formato HTML.

2.3.2.2 Editar los ficheros generados


Se generarán los siguientes ficheros:
Para editar esta ayuda se hará desde el visual Studio escribiendo el código
necesario y el texto para la ayuda.
2.3.2.3 Compilar el proyecto y generar la solución

Una vez se han editado todas las páginas de ayuda, el índice y la tabla de
contenidos, el proyecto se debe compilar para ver si existe algún error, si los hay habrá
que depurarlos y si no los hay, se genera la solución y ya tendremos el proyecto de
ayuda creado.
Para compilar el proyecto se hará:

Nos preguntará lo siguiente:

A lo que se responderá que sí. Si no existen errores se generara la solución y


estará terminado el proyecto de ayuda.
3 COMO MAXIMIZAR UN CUADRO
DE DIALOGOS

En ésta parte del preproyecto explicare cómo se puede maximizar una aplicación
basada en cuadro de diálogos.
Existen distintas formas de maximizar una aplicación basada en cuadro de
diálogos mediante código reutilizable que se puede encontrar fácilmente en Internet en
sitios como http://www.codeproject.com buscando “resizable”
Yo utilicé dos clases: CDlgMan y CDlgAnchor que encontré en
http://www.codeproject.com/dialog/dlgresizearticle.asp.
Esta solución tiene dos ventajas. La primera es que se puede usar la clase en una
aplicación MFC o no-MFC. La segunda es que se puede añadir/quitar dinámicamente
los controles mientras se crea la aplicación.
La clase CDlgMan es la encargada de guardar los tamaños de los controles de la
ventana y la posición de los mismos y la clase CDlgAnchor se ocupa de reajustar todos
los controles del cuadro de diálogos según el tamaño de la ventana.

3.1 Métodos de la clase CDlgAnchor


Esta es la clase encargada de ensanchar los controles fijándolos a uno o más
bordes de la ventana. Al ensanchar un control se asegura que queda en la misma
posición relativa con respecto a los bordes de la ventana.
3.2 Métodos de la clase CDlgMan
Esta clase es la encargada de guardar la posición y el tamaño de la ventana y de
restaurarla.

3.3 Pasos para maximizar el dialogo

3.3.1 Crear un proyecto MFC basado en cuadro de diálogos


Con Visual Studio se crea un proyecto nuevo con la característica de que sea una
aplicación basada en cuadro de diálogos, para esto se hará lo siguiente:
3.3.2 Posibilidad de maximizar el dialogo
Ahora en las características del GUI se debe añadir la posibilidad de que el
dialogo se pueda maximizar y minimizar para esto se hace lo siguiente:

3.3.3 Agregar las clases al proyecto


Ahora se deben copiar los dos ficheros de las clases al proyecto para poder
utilizarlas, para esto se copian los dos ficheros cabecera, dlganchor.h y dlgman.h. en la
carpeta donde este guardado el proyecto a realizar.
Después con Visual Studio, en el explorador de soluciones agregan los
elementos existentes haciendo clic con el botón derecho sobre los ficheros de cabecera.
3.3.4 Reescribir los ficheros .cpp y .h
En el fichero del dialogo MiprogranaDlg.cpp se deben incluir las librerías necesarias
para que se maximice el diálogo, éstas son:
// Incluido para maximizar las ventanas
#include "windows.h"
#include "commctrl.h"
#include "windowsx.h"
#include "resource.h"
#include "anchor.h"
#include "dlgman.h"

En el fichero del dialogo MiprogramaDlg.h se añade lo siguiente:

protected:

void CMiProgramaDlg::OnSize(UINT nType, int cx, int cy);

public:

afx_msg void OnSize(UINT nType, int cx, int cy);

Después también en MiprogranaDlg.cpp se debe sobrescribir el método OnInitDialog y


OnDestroy para inicializar la clase y agrandar o acoplar los controles deseados y
guardar la posición y tamaño añadiendo lo siguiente:
CDlgAnchor dlgAnchor;
CDlgMan dlgMan;
// class that help to load/save size and position of dialog
// window and all child controls

void CMiProgramaDlg::OnSize(UINT nType, int cx, int cy)


{
CDialog::OnSize(nType, cx, cy);
dlgAnchor.OnSize();
// InvalidateRect(hwndDlg, NULL, FALSE);

}
Aquí es donde se pone este código para agrandar y/o acoplar los controles que se quiere
de la lista del archivo de cabecera. Se puede usar la función Add para los controles
dinámicamente creados. Y por último se necesita llamar al método OnSize y Save para
ejecutar la rutina y grabar la posición y tamaño de la ventana.

BOOL CMiProgramaDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Agregar el elemento de menú "Acerca de..." al menú del
sistema.
//SetTimer(1,4000,NULL);
// IDM_ABOUTBOX debe estar en el intervalo de comandos del
sistema.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
dlgAnchor.Init(this->m_hWnd);
dlgAnchor.Add(IDC_STATIC_TODO, ANCHOR_ALL);
dlgAnchor.Add(IDC_STATIC, ANCHOR_TOP|ANCHOR_LEFT);
dlgAnchor.OnSize();

CMenu* pSysMenu = GetSystemMenu(FALSE);


if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX,
strAboutMenu);
}
}
// Establecer el icono para este cuadro de diálogo.
// El marco de trabajo realiza esta operación
// automáticamente cuando la ventana principal de la
// aplicación no es un cuadro de diálogo
SetIcon(m_hIcon, TRUE); // Establecer icono grande
SetIcon(m_hIcon, FALSE);// Establecer icono pequeño
checker = false;
// TODO: agregar aquí inicialización adicional
return TRUE; // Devuelve TRUE a menos que establezca el foco en
un control

void CMiProgramaDlg::OnDestroy()
{
CDialog::OnDestroy();
dlgMan.Save();

}
3.4 Pequeño ejemplo de maximización
Como he explicado antes en el funcionamiento de las clases, el método de la
clase CDlgAnchor tiene por argumentos el ID del control y los ejes al que se quieren
fijar, así si se escribe:
dlgAnchor.Add(IDC_BUTTON1, ANCHOR_LEFT|ANCHOR_BOTTOM);
dlgAnchor.Add(IDC_BUTTON2, ANCHOR_RIGHT|ANCHOR_TOP);
dlgAnchor.Add(IDC_BUTTON3, ANCHOR_ALL);

El botón 1 quedará fijo a la izquierda y abajo.


El botón 2 quedará fijo a la derecha y arriba.
El botón 3 quedará fijo a todas partes.
4 Adquisición
Windows
de video en

Existen diferentes maneras para capturar video en Windows. A continuación voy


a explicar dos maneras diferentes, que encontré.

4.1 Capturar video con una cámara usando C#


Aquí se mostrara como capturar video con una cámara USB usando “Video for
Windows”.

4.1.1 Video for Windows


Video for Windows permite a una aplicación capturar y procesar video. En la
actualidad muchas de las funciones que realizaba “video for Windows” son realizadas
por Directx, para C# se puede usar Managed Directx, que implementa las interfaces
para este lenguaje, para hacer esto se tiene que descargar Directx 9.0 SDK, que esta
disponible para descargar gratuitamente en el sitio Web de Microsoft.
Pero si se desea un programa sencillo sin tener que descargar los más de 100MB
de Directx SDK se puede usar video for Windows que puede capturar hasta 30 cuadros
por segundo, el problema es que solo se puede usar para cámaras que soporten VFW ya
que los nuevos dispositivos de captura solo soportan WDM (Windows Driver Model).

4.1.2 Primero se verá como se hace en C++, después en C#

Primero se incluyen las librerías necesarias:

#include <vfw.h>
Entonces el código es:

HWND HwnDc;

HwnDc=capCreateCaptureWindow((LPSTR)”Nombre”, WS_CHILD|WS_VISIBLE,
xi,yi,Ancho,Alto, hwnd, nDI);

SendMessage(hwnDc,WM_CAP_DRIVER_CONNECT,0,0L);

SendMessage(hwnDc,WM_CAP_SET_PREVIEW_RATE,66,0L);

SendMessage(hwnDc,WM_CAP_SET_PREVIEW,true,0L);

Lo que se hace paso a paso es:

Se crea la ventana de captura, que es donde se va a mostrar el video con:

HwnDc=capCreateCaptureWindow((LPSTR)”Nombre”, WS_CHILD|WS_VISIBLE,
xi,yi,Ancho,Alto, hwnd, nDI);

El primer parámetro es el nombre de la ventana, puede ser cualquiera, después viene el


estilo de la ventana:

WS_CHILD|WS_VISIBLE

En este caso del tipo child o visible.

Luego vienen los parámetros que indican posición inicial en “x” y “y” (xi, yi) y el alto y
ancho de la ventana (Ancho, Alto).

Ahora se tiene que decir dónde va a ir la ventana dónde se va a mostrar el video, eso
puede ser en una forma, un Picture box o un botón, se indica el objeto con su manejador
o “Handle”, va indicado con la variable “hwnd”.

Ahora se tiene que conectar la ventana con el driver de la cámara eso se hace
con:

SendMessage(hwnDc,WM_CAP_DRIVER_CONNECT,0,0L);

Se le indica la ventana con hwnDc, se le dice que se conecte al driver con


WM_CAP_DRIVER_CONNECT y la siguiente variable (que en este caso es 0), es el
índice del driver al que se tiene conectar, puede variar de 0 a 10, como es 0, entonces se
conectara al primer driver que encuentre.
Luego se le dice la velocidad con la que se mostrar el video:

SendMessage(hwnDc,WM_CAP_SET_PREVIEW_RATE,66,0L);

Se le indica la ventana con “hwnDc”, con WM_CAP_SET_PREVIEW_RATE se le


indica que se va a modificar la velocidad de muestra con,
WM_CAP_SET_PREVIEW_RATE y se le indica la velocidad en milisegundos, en este
caso 66 que es la máxima que se puede usar.

Para empezar a mostrar video se usa:

SendMessage(hwnDc,WM_CAP_SET_PREVIEW,true,0L);

El parámetro WM_CAP_SET_PREVIEW indica que se va a mostrar el video y la


variable “true” indica que empiece a mostrarlo, si fuera “false” dejaría de hacerlo, pero
el programa sigue capturando video con el driver, solo que no se muestra la
información.

La intención de mostrar como se hace en C++, es también como se usa en C# el


PInvoke que se usara para llamar esas funciones.

Primero se crea un proyecto en Visual Studio.NET.

Después de crear el proyecto se agrega una clase a la que se llama Video.cs

Entonces se adicionan las siguientes declaraciones a la nueva clase:

private int hwndc ;


private const int WS_CHILD = ( int ) 0x40000000 ;
private const int WS_VISIBLE = ( int ) 0x10000000 ;
private const short WM_USER = ( short ) 0x00000400 ;
private const int WM_CAP_DRIVER_CONNECT = WM_USER + 10 ;
private const int WM_CAP_DRIVER_DISCONNECT = WM_USER + 11 ;
private const int WM_CAP_SET_PREVIEW = WM_USER + 50 ;
private const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52 ;
Los valores de estas pueden encontrarse en la librería “vfh.h”

Ahora las funciones se encuentran implementadas en las DLL user32 y avicap32,


entonces usando Pinvoke en C# se adiciona:

[ DllImport ( "avicap32.dll" )]

public extern static int capCreateCaptureWindowA ( string lpsNombre ,


int dwStilo , int xpi , int ypi , int Ancho , int Alto , int
hwndParent , int nID );

[ DllImport ( "user32.dll" )]

public extern static int SendMessageA ( int hWnd , int wMsg , short
wParam , int lParam );

Con lo anterior se tiene ya la implementación de las funciones en C#.

Ahora se crearan tres métodos: Ventana, Conectar y Capturar los tres devolverán un
valor tipo bool, entonces se adiciona:

public bool ventana ( int Handle )


{
hwndc = capCreateCaptureWindowA ( "Ventana de Captura" , WS_VISIBLE |
WS_CHILD , 0 , 0 , 320 , 240 , Handle , 0 );
if ( hwndc != 0 )
return true ;
else
return false ;
}
public bool conectar ()
{
int r1 ;
r1 = SendMessageA ( hwndc , WM_CAP_DRIVER_CONNECT , 0 , 0 );
if ( r1 != 0 )
return true ;
else
return false ;
}
public bool capturar ()
{
int r1 , r2 ;
r1 = SendMessageA ( hwndc , WM_CAP_SET_PREVIEWRATE , 66 , 0 );
if ( r1 != 0 )
{
r2 = SendMessageA ( hwndc , WM_CAP_SET_PREVIEW , 1 , 0 );
if ( r2 != 0 )
return true ;
else
return false ;
}
else
return false ;
}

Lo que realizan cada una de las funciones ya esta explicado, lo que hay que
aclarar es que:
En el método ventana, el parámetro de entrada es el handle o manejador de el
objeto dónde se va a mostrar el video, que la ventana tiene de ancho 320 píxeles y de
alto 240 y que su origen estará en la posición 0,0 del objeto donde irá.
El método conectar conecta la ventana al primer driver que encuentra, así que el
único driver instalado debe ser el de la cámara que se va a usar, si no se quiere tener
problemas, pero se puede variar el penúltimo parámetro de la función:
SendMessage(hwnDc,WM_CAP_DRIVER_CONNECT,0,0);

Entre 0 y 10 para buscar el driver de la cámara que se va a usar si se tiene más de un


driver instalado.

Entonces en la forma principal para mostrar el video en un Picture Box de nombre


pbVideo se adiciona el siguiente código:

Video cap = new Video ();

System . IntPtr Handle ;

Handle = this . pbVideo . Handle ;

if ( cap . ventana ( Handle . ToInt32 ()) == true )


{

if ( cap . conectar () == true )


{

if ( cap . capturar () == false )

MessageBox . Show ( "No se pudo iniciar la captura" );

else

MessageBox . Show ( "No se pudo encontrar el driver" );

else

MessageBox . Show ( "No se pudo crear ventana de captura" );


Entonces lo que realiza es:
Crea una instancia de la clase:

Video cap = new Video ();

Se obtiene el handle o manejador del Picture Box:

System . IntPtr Handle ;

Handle = this . pbVideo . Handle ;

Entonces se realiza la captura en este orden:


• Crea la ventana.
• Se conecta la ventana al driver.
• Muestra el video.
Que se realiza con:
if ( cap . ventana ( Handle . ToInt32 ()) == true )
{

if ( cap . conectar () == true )


{

if ( cap . capturar () == false )

MessageBox . Show ( "No se pudo iniciar la captura" );

else

MessageBox . Show ( "No se pudo encontrar el driver" );

El handle se debe convertir a entero ya que la función y el método así lo requieren.

Eso es todo, la verdad la idea era mostrar como usar las funciones de “Video for
Windows” en C#, aunque se tiene que admitir que es una manera algo obsoleta por así
llamarlo, es muy sencillo y casi todas las WebCam pueden usarse con este método.

Este código en C++, esta basado en código de Millán Andrés Sánchez.


4.2 Capturar video USB directX

A continuación se muestra otra manera de capturar video desde una cámara Web
pudiendo elegir la conexión de la cámara, S-Video, Composite, TV-Tuner o USB

4.2.1 Introducción

Esta es una aplicación para capturar video en directo desde varios dispositivos
como una tarjeta de captura la entrada de video o una WebCam conectada al USB. La
mayoría de las funciones del API usan DirectX SDK.

El código esta basado en código de Dillip Kumar Kara

4.2.2 Pasos a seguir

• Crear una aplicación basada en cuadros de diálogos.


• Insertar un Picture control de tamaño 320 x 240 píxel.
• En las propiedades del Picture control poner tipo rectángulo y color negro.
• Añadir los ficheros “CaptureVideo.cpp” y “CaptureDevice.h” al proyecto.
• Añadir “CaptureVideo.h” en el fichero de cabecera de implementación.
• Crear un objeto de la clase “CCaptureVideo” usando el Class Wizard.
• Enlazar las librerías strmbasd.lib, wmvcore.lib, wmstub.lib en los settings del
proyecto.
Ahora, usando el objeto, llamar a la función InitializeVideo (HWND hWnd)
para inicializar el video.

HRESULT hr = capVideo.InitializeVideo (hWnd);

Dónde hWnd es el handle del Picture control.

• StartSVideo () – Para capturar desde SVideo.


• StartCompositeVideo () - Para capturar desde Composite Video.
• StartTVTuner () - Para capturar desde TVTuner.
• StartWebcam () - Para capturar desde WebCam.

A continuación muestro el diagrama de Rational Rose al hacer ingeniería inversa


para mostrar las clases del proyecto y las relaciones entre ellas.

Importante:

No olvidarse de des inicializar el video usando UnInitializeVideo () antes de


destruir la aplicación.

4.2.3 Requerimientos

• Tarjeta de Captura de.


• Cámara USB.
• Instalar DirectX, que esta disponible en Microsoft. Se puede descargar DirectX
9.0 de Microsoft.
• Para desarrolladores instalar DirectX 9.0 SDK. Se puede descargar
• DirectX 9.0 SDK de Microsoft.
5 Visualizador
clase CPicture
de HaloCount,

Para mostrar la imagen en HaloCount Mihai Spulber compañero del proyecto


utilizó una función que se llama visualizarImagen (CString nombreImagen).
Ahora explico el funcionamiento de la misma.

5.1 La función visualizarImagen (CString nombreImagen)

Esta función carga la imagen con el path y la muestra en la ventana principal de


la aplicación. La exposición de la imagen es estática; sin importar el tamaño original de
la imagen.
El código de esta función es:

void CVistaAnaClaSDCDlg::visualizarImagen(CString nombreImagen)

CSize sizenew(477,392);

CPoint point(20,20);

pdc = GetDC();

picture.Load(nombreImagen);

sizeoriginal = picture.GetSize(pdc);

picture.Draw(pdc,point,sizenew);

Como se puede ver en el código primero se declara un tamaño (de la clase


CSize), un tamaño estático, entonces la primera posición en la ventana dónde se
mostrará la imagen (de la clase CPoint).
Después de esto se usan las variables pdc para coger el handle del dispositivo de
muestra (usando la función GetDC ()).
Ahora todas las pre-peticiones están hechas, se puede cargar y mostrar la
imagen. Por esta razón se usa un objeto Picture (de la clase CPicture).
La clase CPicture se ha construido para ofrecer a los programadores
posibilidades de cargar y mostrar imágenes con formatos diferentes (JPG, GIF, BMP y
PNG).
Ésta clase puede ser incluida en todo tipo de proyectos en los que se deban
mostrar imágenes, y el propósito principal es ofrecer a programadores la posibilidad de
trabajar más fácilmente con la clase IPicture en MFC .NET. La ventaja de usar esta
clase es que pueden mostrarse imágenes con resolución buena guardadas con formato
comprimido (por ejemplo JPG), comparado con la clase Standard de MFC CBitmap.

Este código de la clase CPicture se puede encontrar en Internet en


http://www.codeproject.com/bitmap/pictureshow.asp

Ésta es una clase muy simple de usar y fácil de implementar añadiéndola al


proyecto, y no hace falta ser un freaky del tratamiento de imágenes. Usa una interface
IPicture como lo hace Internet Explorer.
6 Objetos COM
En esta parte del preproyecto se explicará paso a paso como construir un
componente COM, construyendo la aplicación y creando los objetos.
Más adelante en el proyecto se realizara un visualizador de imágenes como el de
HaloCount pero implementado con esta filosofía.

6.1 Construyendo una aplicación


Usar MATLAB Builder para crear un componente COM es un proceso simple que
requiere una secuencia de 4 pasos.

• “Crear un proyecto”
• “Gestionar los ficheros M-Files y MEX-Files”
• “Compilar el proyecto”
• “Empaquetado y distribución del componente”

6.1.1 Elementos de MATLAB Builder para un proyecto COM

Un proyecto consiste de todos los elementos necesarios para construir una


aplicación para distribuir usando COM Builder. Los componentes COM de COM
Builder, son objetos COM accesibles desde Visual Studio6.0, .NET, o algún otro
lenguaje que soporta COM.
COM es un acrónimo de “Modelo de Objeto de Componente”, que es un objeto
estándar de Microsoft para la interoperatibilidad.
Cada objeto COM expone una o más clases al entorno de programación del
Visual Studio. Cada clase contiene un conjunto de métodos de funciones llamadas,
correspondientes a las funciones implementadas en el archivo de Matlab original
incluido en el proyecto del componente.

Clases
Cuando se crea un componente, se debe proporcionar uno o más nombres de
clase. El nombre de componente representa el nombre del fichero DLL para ser creado.
Un nombre de clase denota el nombre de la clase que realiza una llamada en un método
específico en tiempo de ejecución. El parentesco entre el nombre del componente y el
nombre de la clase, y los métodos (funciones de Matlab) van dentro una clase particular,
es puramente organizacional.
Como regla general, cuando se compilan muchas funciones de Matlab, esa clase
ayuda a determinar las diferentes categorías de funciones, para crear una clase separada
para cada categoría. El nombre de cada clase sería descriptivo.
Versiones
Los componentes COM también soportan un simple mecanismo de control de
versiones. A cada componente se le asigna un número de versión.
Este número se añade automáticamente dentro del nombre de fichero DLL y de
la información de registro de sistema. Como regla general, la primera versión de un
componente es 1.0 (valor por defecto). Los cambios hechos al componente antes de su
distribución se guardan bajo el mismo número de versión.
Después del desarrollo completo y su distribución, se debe cambiar el número de
versión para los siguientes cambios, Así se pueden manejar fácilmente las diferentes
versiones. El sistema diferencia las clases de versiones diferentes del mismo
componente, aunque tengan el mismo nombre.

6.1.2 Creando un proyecto


Para empezar a crear un proyecto se debe entrar la ventana de comandos de
Matlab y escribir comtool en la línea de comandos. Aparecerá la ventana del
constructor de objetos COM de Matlab:
Ahora se debe seleccionar FileÆNew Project y aparecerá la ventana de New
Project Settings.

Component name: sirve para dar el nombre del componente DLL creado en el
proceso de construcción. Después de escribir el nombre de componente,
automáticamente se introduce un nombre de Clase idéntico al nombre de componente.
Si se prefiere se puede cambiar el nombre de la clase para que sea más descriptivo.
Aunque el nombre del componente y de la clase puede ser el mismo, el nombre de
componente no puede se igual al el nombre de algún fichero M o MEX añadidos al
proyecto más tarde.
Para añadir una clase a su componente se debe introducir el nombre de clase en
el apartado Class name y hacer clic en <<Add>>. La clase añadida ahora aparecerá en
la lista de Clases.
Version: Por defecto el valor de la versión del Proyecto es 1.0.
Project directory: especifica dónde se van a guardar los archivos del proyecto.
El directorio de proyecto se genera automáticamente a partir del nombre de su directorio
actual y el nombre del componente.
Create a singleton MCR indica a Matlab Compiler que debe generar el código
de tal forma que sólo cree una instancia del MCR por aplicación. Si el usuario
selecciona esta opción al crear el componente y usa este componente en una aplicación
de Visual Studio, cada instancia del componente no tiene como resultado la creación de
un nuevo componente MCR, sino que, las instancias siguientes usarán el mismo MCR.

Después de aceptar estas opciones en la ventana de diálogo New Project


Settings, haciendo clic en OK, se vuelven parte del Workspace del proyecto y son
salvados en el fichero de proyecto junto con los nombres de algunos ficheros M o MEX
que posteriormente se añaden. El fichero llamado <nombre_componente .cbl> se
guarda automáticamente en el directorio del proyecto.

6.1.3 Gestionando los ficheros M-File y MEX-File


Después de crear un proyecto se activan los menús Project, Build y
Component.

Para añadir los ficheros sólo se tiene que hacer clic en Add File… y seleccionar
el fichero, para quitarlo clic en Remove file una vez seleccionado el fichero a borrar, en
la ventana de proyecto. Si se desea editar el fichero .m pulsar la opción Edit File…

6.1.4 Compilando el proyecto


Después de definir las opciones del proyecto y de añadir los archivos .M
deseados, ya es posible construir una DLL para su distribución. Seleccionando
BuildÆCOM Object se invoca al compilador de Matlab, el cual escribe los ficheros
fuente intermedia en ..\..\src y si fuera necesario creará los ficheros de distribución en
..\..\distrib.

6.1.4.1 Build Status


El panel de Build Status muestra la salida del proceso e informa de los
problemas encontrados.
Uno de ficheros aparecidos en el directorio ..\..\distrib será una DLL. El
componente DLL es registrado automáticamente en su sistema.
Para limpiar el panel de Build Status, seleccionar BuildÆClear Status. La
salida de construcción del proceso se guarda en el fichero ..\..\build.log.
Para abrir dicho archivo, seleccionar Build -> Open Build Log. El Build Log
proporciona un registro del proceso de construcción que puede verse aún después de
haber limpiado el panel de Build Status. Éste archivo puede ser útil a la hora de buscar
apoyo técnico, ya que contiene toda la información sobre el proceso.

6.1.5 Empaquetado y distribución del componente


Una vez se ha compilado con éxito el Componente y el objeto COM funciona
correctamente en los ejemplos de prueba, está todo listo para empaquetar el componente
para su distribución.
Seleccionar ComponentÆPackage Component para crear un ejecutable de
auto-extracción, con .exe, para ejecutar en la máquina de destino. Éste ejecutable
contiene los siguientes ficheros:

Archivo Función

_instal.bat Fichero con las opciones de ejecución


para el ejecutable de auto-extracción.

<nombreComponente_versión>.dll Componente compilado

MCRinstaller.exe Ejecutable de auto-extracción.


Componente de la biblioteca de
utilidades en tiempo de ejecución;
fichero que indica la dependencia de
plataforma debe corresponder la
plataforma de la Máquina de destino.

<nombre_componente>.ctf Archivo de dependencias de plataforma.

MCRINSTALLER.exe instala Componente de Matlab en tiempo de ejecución (MCR),


(MATLAB Component Runtime) que se necesita instalar en la máquina de destino con
cada versión.
6.2 Creación de objetos COM en Matlab

Figure A-1: Creating a Stand-Alone COM Object with the MATLAB Compiler

El proceso de crear un componente COM es automático. El usuario suministra


los ficheros .m al proceso e información adicional (nombre del componente, nombres de
clase, y número de versión).
Éste proceso implica generación de código, compilación, enlazado, y registro del
componente terminado.
El siguiente esquema representa los pasos del proceso de construcción y los
ficheros intermedios generados, en la que se puede ver que la función principal de la
interfaz del objeto es la interfaz IUnknown:
En la siguiente imagen se muestran los ficheros creados en cada paso durante el
proceso, desde la compilación hasta el registro del final DLL.

Figure A-2: M-Build Steps and Intermediate Files Created

A continuación muestro los pasos a seguir:

6.2.1 Generación del código:


El primer paso en la construcción del proceso, es el que genera todo código
fuente e incluye los ficheros que se necesitan para crear el componente. También crea el
fichero fuente principal (micomponente_dll.cpp) que contiene la implementación de
cada función exportada de la DLL.
El compilador adicionalmente produce un fichero de Lenguaje de Descripción
de Interfaz (IDL) (micomponente_idl.idl), que integra las especificaciones para
biblioteca de tipos del componente, interfaz, y clase, con el GUIDS asociado. (GUID es
un acrónimo de Globally Unique Identifier, un entero de 128-bit que garantiza ser único
siempre.)
Posteriormente se crea la definición de la clase C++ y los ficheros de
implementación (miclase_com.hpp y miclase_com.cpp).
Además de estos ficheros fuente, el compilador genera un fichero DLL de exportaciones
(micomponente.def), un script de recursos (micomponente.rc), y un Fichero de
Tecnología de Componente (micomponente.ctf).

6.2.2 Creación de la definición de interfaces:


El segundo paso del proceso, invoca el IDL del compilador en el fichero IDL
generado en el paso 1 (micomponente_idl.idl), creando el fichero de cabecera de
interfaz (micomponente_idl.h), el fichero de interfaz GUID (micomponente_idl_i.c), y
el fichero de biblioteca de tipos del componente (micomponente_idl.tlb).
El fichero de cabecera de interfaz contiene definiciones de tipo y declaraciones
de función basados en la definición de interfaz en el fichero IDL. El fichero interfaz
GUID contiene las definiciones de las GUIDS de todos interfaces del fichero IDL. El
fichero de biblioteca de tipos del componente contiene una representación binaria de
todos los tipos y objetos expuestos por el mismo.

6.2.3 Compilación C++:


El tercer paso compila todos los ficheros C/C++ fuente generados en los pasos 1
y 2 dentro del código del objeto. Además de un fichero adicional que contiene un
conjunto de plantillas de clases C++ (mclcomclass.h).
Éste fichero contiene la implementación de todas las plantillas necesarias para
las clases base COM, además de la implementación del código de error y código de
registro.

6.2.4 Enlazado y relación de Recursos:


El cuarto paso crea la DLL final del componente. Este paso invoca el Linkador
para los ficheros generados en el paso 3 y las bibliotecas de Matlab necesarias para
producir un componente DLL (micomponente_1_0.dll).
El recurso del compilador es entonces invocado en la DLL, junto con el script de
recursos generado en el paso 1, para enlazar el fichero de biblioteca de tipos generado
en el paso 2, dentro del DLL completado.

6.2.5 Registro del componente:


Los componentes COM creados son self-registering. Un componente self-
registering contiene todo el código necesario para añadir o quitar una descripción
completa de si mismo desde el registro del sistema.
La herramienta mwregsvr, distribuida con el MCR, registra las DLLs self-
registering. Por ejemplo, para el registro de un componente llamado
micomponente_1_0.dll, si se quiere llamar a esta herramienta desde MSDOS se ha de
ejecutar la siguiente línea de comando mwregsvr micomponente_1_0.dll
Cuando mwregsvr completa el proceso de registro, muestra un mensaje
indicando éxito o fracaso. Similarmente, el comando mwregsvr /u
micomponente_1_0.dll desregistra el componente.

S-ar putea să vă placă și