Upload
others
View
12
Download
0
Embed Size (px)
Citation preview
i
Equation Chapter 1 Section 1
Trabajo Fin de Grado
Grado en Ingeniería Aeroespacial
Desarrollo de un código para el procesado de vídeos
en electro-flow-focusing
Autor: José Damián Pérez Ramírez
Tutor: Elena de Castro Hernández
Dep. de Ingeniería Aeroespacial y Mecánica de Fluidos
Escuela Técnica Superior de Ingeniería
Universidad de Sevilla
Sevilla, 2018
iii
Trabajo Fin de Grado
Grado en Ingeniería Aeroespacial
Desarrollo de un código para el procesado de vídeos
en electro-flow-focusing
Autor:
José Damián Pérez Ramírez
Tutor:
Elena de Castro Hernández
Profesor Ayudante Doctor
Dep. de Ingeniería Aeroespacial y Mecánica de Fluidos
Escuela Técnica Superior de Ingeniería
Universidad de Sevilla
Sevilla, 2018
v
Trabajo Fin de Grado: Desarrollo de un código para el procesado de vídeos en electro-flow-focusing
Autor: José Damián Pérez Ramírez
Tutor: Elena de Castro Hernández
El tribunal nombrado para juzgar el trabajo arriba indicado, compuesto por los siguientes miembros:
Presidente:
Vocales:
Secretario:
Acuerdan otorgarle la calificación de:
Sevilla, 2018
El Secretario del Tribunal
ix
Agradecimientos
Principalmente quiero dedicar un especial agradecimiento a mi tutora, Elena de Castro Hernández por haberme dado la oportunidad de realizar este trabajo y por toda la ayuda prestada en la realización del mismo.
En segundo lugar, agradecer también a Fernando Fernández Sánchez por su predisposición en cualquier
momento a prestarme ayuda en fragmentos del código. En último lugar, a mi familia por toda la ayuda y
motivación depositada en mí a lo largo de mi trayectoria académica.
José Damián Pérez Ramírez
Sevilla, 2018
xi
Resumen
El objetivo del presente documento es continuar la línea de investigación del Departamento de Ingeniería
Aeroespacial y Mecánica de Fluidos de la Escuela Superior de Ingeniería de la Universidad de Sevilla
enfocada en el estudio de chorros bajo la acción de un campo eléctrico alterno dentro del marco de la microfluídica. En concreto, se continua la interfaz gráfica de usuario realizada por Fernando Carrión Ronda
como Trabajo Fin de Grado [2], tutelado también por Elena de Castro Hernández, añadiendo a ésta un nuevo
módulo denominado “Profile” que permite la obtención de las coordenadas del chorro. Además, se implementa una nueva interfaz gráfica, “Miplot”, la cual ofrece la posibilidad de representar gráficamente las
coordenadas de los chorros antes obtenidos. Por último, como aplicación práctica a ambas interfaces, se realiza
un estudio sobre varios chorros variando las condiciones de experimentación con las que fueron grabados.
Con todo esto, en el Capítulo 1, se le ofrece al lector una breve introducción a la microfluídica en la que se clasifican los diferentes fenómenos observados así como los métodos de generación de gotas. En el Capítulo
2, se describe el desarrollo de los códigos de ambas interfaces explicando su desarrollo y las variables de
mayor interés. A continuación, en el Capítulo 3, se expone un breve manual de uso del programa para aquel usuario que esté interesado en la utilización de cualquiera de ellos. En cuanto al Capítulo 4, a modo de ejemplo
práctico, se realiza un estudio sobre varios chorros variando una serie de parámetros. En lo que respecta al
Capítulo 5, se detallan una serie de conclusiones. En el Capítulo 6, se adjuntan los fragmentos del código principal que han servido para la realización de ambos programas. Por último, como anexo, se ha creado de
forma equemática un manual de usuario a una sola cara.
xiii
Abstract
The main objective of this document is to continue Aerospace Engineering and Fluid Mechanics
Department, from Escuela Superior de Ingeniería (Universidad de Sevilla), research on jets under the effect of
an electric field as a part of its microfluidic studies. Actually, it can be considered the completion of the Graphical User Interface made by Fernando Carrión Ronda [2], also tutored by Elena de Castro Hernández.
The idea is to add a new part to this GUI called “Profile” which allow to obtain the jet’s coordinates. In
addition, a new Graphical User Interface is implemented which name is “Miplot” and its function is to plot the jet’s coordinates. To sum up, it is offered a practical application for both interfaces which is a study about the
analysis of different jets varying the experimental conditions with which they were recorded.
In Chapter 1, a brief introduction to microfluidic science is made trying to classify the different kinds of phenomenons that are known and the ways of bubbles generation. In Chapter 2, the development of the
program’s code and the interesting variables are described. Then, in Chapter 3, a short user’s guide is offered
for some user who is interesed in to use any of them. In Chapter 4, a study is made on several jets varying
some parameters. Hereunder, in Chapter 5, some conclusions are written. In Chapter 6, the main program’s
codes are attached. Finally, it is made a very brief user’s guide which is included like attached.
xv
Índice
Agradecimientos ix
Resumen xi
Abstract xiii
Índice xv
Índice de Figuras xvii
Notación xxi
1 Introducción 11 1.1 Regímenes observados en microfluídica 12
1.1.1 Dripping (Régimen de goteo) 12 1.1.2 Jetting 12
1.2 Configuraciones para generar microgotas 13 1.2.1 Coflow (Coflujo) 13 1.2.2 Flow focusing 13 1.2.3 T-junction (Unión en T) 14
2. Descripción del código para el procesado de vídeos en electro-flow-focusing 17 2.1 Introducción 17 2.2 Descripción de las variables principales 18 2.3 Preprocessor 19
2.3.1 Select a new file 19 2.3.2 Change rotation angle 19 2.3.3 Select region of interest 19 2.3.4 Change resolution 20 2.3.5 Change framerate 20 2.3.6 Change analysis range 20 2.3.7 Object size 20
2.4 Profile 20 2.4.1 Change bubble range 21 2.4.2 Change time range 25 2.4.3 Save results 25
2.5 Miplot 27 2.5.1 Plot figure 28 2.5.2 Save figure 30 2.5.3 Delete figure 31
3 Breve manual de uso 33 3.1 Analizar2 33
3.1.1 Preprocessor 33 3.1.2 Analysis 37 3.1.3 Profile 37
3.2 Mi plot 43 3.3 Ejemplos 48
4 Estudio 53 4.1 Conductividad fija, frecuencia variable y diferentes instantes de tiempo (caso 1) 53 4.2 Conductividad fija, frecuencia variable y diferentes instantes de tiempo (caso 2) 54 4.3 Frecuencia fija, conductividad variable y diferentes instantes de tiempo 55 4.4 Conclusiones del estudio 61
5 Conclusiones 63
6 Código empleado 65 6.1 Analizar 2 65 6.2 Miplot 82
Referencias 91
A. MANUAL DE USO A UNA CARA 95
xvii
ÍNDICE DE FIGURAS
Figura 1.1 Emulsificador de ultrasonido. Imagen tomada de [1]. 11
Figura 1.2 Imagen mostrando el régimen de dripping en configuración de coflujo. Imagen tomada de [6]. 12
Figura 1.3 Imagen mostrando el régimen de narrowing en configuración de coflujo. Imagen tomada de [1].
13
Figura 1.4 Imagen mostrando el régimen de widening en configuración de coflujo. Imagen tomada de [1].
13
Figura 1.5 Esquema de la configuración de coflujo. Imagen tomada de [1]. 13
Figura 1.6 Esquema de la configuración de flow focusing. Imagen tomada de [7]. 14
Figura 1.7 Secuencia de imágenes que muestran la rotura de la gota mediante Flow-Focusing. Imagen tomada
de [1]. 14
Figura 1.8 Esquema de la configuración de T-junction. Imagen tomada de [7]. 14
Figura 2.1 Diagrama de flujo de información entre las dos interfaces gráficas. 17
Figura 2.2 Menú interactivo de la primera interfaz gráfica de usuario, Analizar2. 21
Figura 2.3 Región de interés del chorro. 22
Figura 2.4 Línea de referencia del chorro. 23
Figura 2.5 Imagen del chorro en binario y habiendo eliminado los elementos que no son de interés. 23
Figura 2.6 Imagen del chorro una vez que se rellena y se ha trazado la frontera. 23
Figura 2.7 Cálculo del diámetro del chorro. Imagen tomada de [2]. 24
Figura 2.8 Ejemplo de archivo de texto de salida del primer tipo. 26
Figura 2.9 Ejemplo de archivo de texto de salida del segundo tipo. 27
Figura 2.10 Menú interactivo de la segunda interfaz gráfica de usuario, Miplot. 28
Figura 2.11 Representación de dos chorros (corto y largo) de la quinta burbuja para cinco instantes obtenida al
ejecutar Plot figure. 29
Figura 2.12 Representación de dos chorros (corto y largo) de la quinta burbuja para cinco instantes obtenida al ejecutar Save figure. 31
Figura 3.1 Ventana de selección de archivo de entrada a la primera GUI. 33
Figura 3.2 Ventana interactiva de la primera GUI. Encuadrado en rojo se aprecia el módulo Preprocessor.
34
Figura 3.3 Ejemplo de fotograma orientado en la posición correcta. 34
Figura 3.4 Ejemplo de fotograma orientado en una posición incorrecta. Imagen tomada de [2]. 35
Figura 3.5 Ejemplo de región de interés. En este caso al no haber interferencias se toma como región la primera burbuja. 35
Figura 3.6 Ejemplo de interferencia y de región de interés que se debería elegir. 36
Figura 3.7 Ejemplo de burbuja detectada correctamente ya que se observa su perímetro en color rojo. 36
Figura 3.8 Ejemplo de interferencia y de la burbuja detectada que se debería elegir. 37
Figura 3.9 Ejemplo de barra de estado analizando los fotogramas. 37
Figura 3.10 Ventana interactiva de la primera GUI. Encuadrado en rojo se aprecia el módulo Profile. 38
Figura 3.11 Ventana para introducir las burbujas a estudiar. 38
Figura 3.12 Ejemplo de región de interés del chorro. 39
Figura 3.13 Ejemplo de línea de referencia del chorro. 39
Figura 3.14 Fotograma mostrado al usuario del instante posterior a la rotura para las burbujas seleccionadas por el usuario. 40
Figura 3.15 Ventana para la selección de la burbuja a estudiar. 40
Figura 3.16 Ventana para la selección del número de instantes de tiempo. 41
Figura 3.17 Ejemplo de archivo de texto que se genera con los parámetros y resultados. 42
Figura 3.18 Ejemplo de archivo de texto que se genera con las coordenadas del chorro. La primera columna
representa las coordenadas abcisas, la segunda las ordenadas superiores y la tercera las ordenadas inferiores.
43
Figura 3.19 Ventana interactiva de la segunda GUI. 44
Figura 3.20 Ventana para la selección del número de burbujas de un mismo vídeo o para la selección del
número de vídeos de una misma burbuja que se quieren representar. 44
Figura 3.21 Ventana para la selección del número de instantes de tiempo que se quieren estudiar. 44
Figura 3.22 Ventana para seleccionar los archivos de texto que se quieren tratar. 45
Figura 3.23 Representación de dos chorros (corto y largo) de la quinta burbuja para cinco instantes obtenida al
ejecutar Plot figure. 46
Figura 3.24 Representación de dos chorros (corto y largo) de la quinta burbuja para cinco instantes obtenida al
ejecutar Save figure. 46
Figura 3.25 Representación de cuatro chorros en las mismas condiciones (frecuencia y voltaje) y para el mismo instante de tiempo para cuatro burbujas distintas. 47
Figura 3.26 Representación de cuatro chorros para los mismos voltaje, instante de tiempo y burbuja para
cuatro valores de la frecuencia diferentes. 47
Figura 3.27 Representación de cuatro burbujas distintas de un mismo chorro corto en el instante de rotura. 48
Figura 3.28 Representación de cuatro burbujas distintas de un mismo chorro largo en el instante de rotura.
48
Figura 3.29 Representación de dos chorros (corto y largo) de una misma burbuja (la quinta) para los mismos
cinco instantes de tiempo . 49
Figura 3.30 Representación de dos chorros (diferente frecuencia y mismo voltaje) de una misma burbuja (la tercera) para los mismos cuatro instantes de tiempo . 50
54
Figura 4.1 Representación de seis chorros diferentes variando la frecuencia, voltaje y conductividad constantes
para cuatro instantes de tiempo diferentes de la tercera burbuja. 54
Figura 4.2 Representación de seis chorros diferentes variando la frecuencia, voltaje y conductividad constantes
para cuatro instantes de tiempo diferentes de la tercera burbuja. 55
Figura 4.3 Representación de dos chorros diferentes manteniendo la frecuencia (50 kHz) y voltaje constantes y variando la conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja. 56
Figura 4.4 Representación de dos chorros diferentes manteniendo la frecuencia (40 kHz) y voltaje constantes
y variando la conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja. 57
Figura 4.5 Representación de dos chorros diferentes manteniendo la frecuencia (30 kHz) y voltaje constantes y variando la conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja. 58
Figura 4.6 Representación de dos chorros diferentes manteniendo la frecuencia (20 kHz) y voltaje constantes
xix
y variando la conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja. 59
Figura 4.7 Representación de dos chorros diferentes manteniendo la frecuencia (10 kHz) y voltaje constantes y variando la conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja. 60
Figura 4.8 Representación de dos chorros diferentes manteniendo la frecuencia (5 kHz) y voltaje constantes y
variando la conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja. 61
11
1 INTRODUCCIÓN
l presente documento está enmarcado dentro de una rama de la Mecánica de Fluidos denominada
Microfluídica. Como su nombre indica, trata el estudio de fluidos en dimensiones muy pequeñas, lo que
garantiza además, que el número de Reynolds sea muy bajo.
Como ya se sabe, los líquidos son de gran importancia tanto para la ciencia, la industria y, hasta en nuestra vida cotidiana. Tanto es así, que el estudio que se hace sobre ellos es enorme y, en parte, dicho estudio
contempla también las gotas y burbujas. Aunque a priori parezca que no, se encuentran en muchas facetas de
nuestro día a día como es el caso de la lluvia o, sin ir más lejos, en nuestra propia cocina al hervir agua.
Además, en el mundo industrial y en el profesional, la presencia de burbujas es muy importante, tal es el
caso de los meteorólogos al estudiar la formación de lluvia; de los ingenieros químicos al utilizar gotas en la
destilación o la absorción o; de los ingenieros mecánicos al estudiar las burbujas en procesos como la combustión o la evaporación [1]. En otras ramas de la ciencia como son la medicina o la farmacéutica también
son de gran utilidad, por ejemplo, para el suministro de fármacos vía pulmonar o para la producción del
fármaco, respectivamente [5].
Por todo lo dicho hasta ahora, es claro que el estudio de generación de burbujas es algo bastante importante. Existen diferentes procesos para su generación, todos artificialmente por supuesto, y que se
pueden clasificar en dos tipos: los que se producen mediante generación masiva y los que se producen por una
generación controlada.
Los mezcladores, agitadores y emulsificadores de ultrasonido son ejemplos de casos producidos por una
generación masiva; estos casos son simples, fiables y de bajo coste. Sin embargo, tienen como desventaja que
proporcionan una generación de gotas de tamaño muy disperso y, además, presentan un control bastante pobre
del diámetro [6]. La figura 1.1. representa un ejemplo de ellos.
Figura 1.1 Emulsificador de ultrasonido. Imagen tomada de [1].
E
Hay una fuerza motriz más poderosa que el vapor, la
electricidad y la energía atómica: la voluntad.
- Albert Einstein -
Introducción
12
Por otro lado, se encuentran aquellas burbujas que se generan bajo condiciones más controladas y son, de
hecho, las que originan los vídeos a estudiar en este documento. Se trata de gotas micrométricas
monodispersas y que han sido originadas por un procedimiento en el que se asegura el control en la corriente y en la mezcla del fluido principal con otros componentes [2]. Más adelante se explican tres de estas técnicas
que permiten la generación de burbujas a escala micrométrica, éstas son: Coflow, Flow-Focusing y T-
Junction.
Sin embargo, antes es conveniente mencionar los diferentes tipos de regímenes en los que operan estos dispositivos para, posteriormente, explicar cómo intervienen en los mismos. De forma general, existen dos
tipos observados en función de las condiciones de operación, estos son: dripping y jetting.
1.1 Regímenes observados en microfluídica
1.1.1 Dripping (Régimen de goteo)
En este primer caso, al proporcionar un caudal bajo se produce un goteo periódico justamente en la punta del tubo de inyección [1]. Como resultado, las gotas que se obtienen son muy uniformes pero, por el contrario,
la frecuencia de producción es muy baja. Además, presenta como inconveniente que el tamaño de la gota
formada está restringido por el tamaño del tubo que la genera ya que es del orden del tamaño del mismo con lo
que dicho tubo presenta facilidad para obstruirse. En la siguiente figura se muestra un ejemplo de este régimen.
Figura 1.2 Imagen mostrando el régimen de dripping en configuración de coflujo. Imagen tomada de [6].
1.1.2 Jetting
En el lado opuesto al dripping se encuentra el régimen de jetting que se forma para caudales mayores que
el anterior. Este caso se caracteriza por la formación de grandes chorros (denominado fase dispersa; por contra, el fluido exterior recibe la denominación de fase continua) en los que la gota se forma en el final del mismo.
Gracias a esto, se pueden generar gotas del tamaño del chorro y que pueden ser mucho menores que el tubo
del que se producen. Hay que tener en cuenta que esto solamente se consigue bajo la acción de un campo de
fuerza, ya sea eléctrico o hidrodinámico.
Además, en función de la geometría del chorro que se ve afectado por los esfuerzos viscosos del flujo
exterior y del interior así como de las fuerzas de confinamiento (debidas a la tensión superficial) existe, a su
vez, una subdivisión de este régimen. Si se observa que el chorro se estrecha de forma progresiva se denomina Narrowing (estrechamieno) y, si se aprecia que se ensancha progresivamente Widening (ensanchamiento) [6].
En el primer caso, el chorro es formado cuando los esfuerzos viscosos que se ejercen en la superficie del
mismo por el flujo exterior prevalecen sobre las de confinamiento y, de forma general, la velocidad del flujo exterior es mayor que la del interior. En el Widening ocurre lo contrario y son ahora los esfuerzos viscosos
ejercidos por el flujo interior los que superan a dichas fuerzas de confinamiento además de que, por regla
general, la velocidad del flujo interior es mayor que la del exterior. En las siguientes dos figuras se adjunta un
ejemplo de ambos casos:
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing
13
Figura 1.3 Imagen mostrando el régimen de narrowing en configuración de coflujo. Imagen tomada de [1].
Figura 1.4 Imagen mostrando el régimen de widening en configuración de coflujo. Imagen tomada de [1].
Como se ha mencionado anteriormente, para generar el régimen de Jetting es necesario actuar bajo la acción de un campo de fuerza, dicho campo se consigue con las configuraciones anteriormente mencionadas y
que se explican a continuación.
1.2 Configuraciones para generar microgotas
1.2.1 Coflow (Coflujo)
Esta primera configuración se caracteriza por el flujo coaxial de dos fluidos no miscibles que darán diferentes tipos de regímenes en función de la relación existente entre las fuerzas de viscosidad, tensión
superficial e inercia [1]. En la Figura 1.5 se puede observar un esquema de este procedimiento.
Dependiendo de los parámetros seleccionados, se obtendrán para este método los diferentes regímenes
comentandos anteriormente (widening y narrowing). Este último es de gran interés ya que se podrán crear
burbujas pequeñas con elementos generadores no necesariamente demasiado pequeños.
Figura 1.5 Esquema de la configuración de coflujo. Imagen tomada de [1].
1.2.2 Flow focusing
Este segundo caso se caracteriza por cómo el fluido exterior enfoca al interior haciéndolo pasar por un
pequeño orificio localizado en frente del canal de inyección. En consecuencia, el fluido interior bloquea este
orificio lo que origina un aumento de la presión aguas arriba y es entonces este aumento de la presión el que termina provocando la generación de la burbuja. Al pasar el fluido por el orificio origina un chorro que puede
ser mucho más pequeño que el propio tubo de inyección. Un esquema de este método y un ejemplo de cómo
se forman las gotas se puede apreciar en la figuras 1.6 y 1.7, respectivamente.
14 Introducción
De nuevo, al igual que en la anterior configuración, se pueden obtener los dos tipos de regímenes vistos
anteriormente, el de dripping y el de jetting. Como matiz, decir que en el de dripping la generación de las gotas
ocurre cerca del orificio mientras que en el de jetting ocurre a una distancia mínima de tres diámetros de
orificio [4].
Figura 1.6 Esquema de la configuración de flow focusing. Imagen tomada de [7].
Figura 1.7 Secuencia de imágenes que muestran la rotura de la gota mediante Flow-Focusing. Imagen tomada de [1].
1.2.3 T-junction (Unión en T)
En esta última configuración el nombre lo dice todo y es que, por un canal circula la fase continua y es
entonces intersectado por otro en el que circula la fase dispersa. En la unión de ambos canales se genera una interfase de ambos fluidos y, posteriormente, debidos a los esfuerzos cortantes de la fase continua y el
gradiente de presiones, la fase dispersa se elonga en el canal hasta que se produce la rotura y se forma la gota.
Es importante decir que, el tamaño de la gota depende del cociente de caudales, las dimensiones de los
canales y del cociente de las viscosidades de ambos líquidos [7].
De nuevo, un ejemplo de este tipo se representa en la siguiente figura.
Figura 1.8 Esquema de la configuración de T-junction. Imagen tomada de [7].
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing
15
Llegados a este punto, ya se sabe de forma superficial que existen varios métodos para la generación de
burbujas y además, que se pueden formar bajo diferentes regímenes. Todo esto se observó mediante la
experimentación y, el estudio que se hizo posteriormente, guardando dicha información en imágenes y vídeos;
con lo que resultó bastante interesante estudiar estos archivos en busca de información adicional. Este fue el caso que trató Fernando Carrión Ronda en su Trabajo Fin de Grado en el que estudió diferentes parámetros
como la distribución de tamaños de las burbujas o la longitud y el diámetro del chorro. Gracias a su estudio
que sirvió de base para la realización de este documento se pretende ahora extraer algo más de información de dichos vídeos como puede ser una representación gráfica de cada una de las burbujas o del chorro que le
interese al usuario.
Con todo esto, en este trabajo, en primer lugar se explica la realización de los programas detallando la información que ofrecen y el camino seguido para obtenerla, Capítulo 2. En el Capítulo 3 se expone un breve
manual de uso para aquel usuario que esté interesado en utilizar los programas. Posteriormente, en el Capítulo
4 se realiza una aplicación práctica de los mismos por medio de un estudio variando algunos parámetros de
interés. En el Capítulo 5 se ofrecen una serie de conclusiones obtenidas acerca de las interfaces gráficas.
Finalmente, en el Capítulo 6, se adjunta el código en Matlab para cada uno de los programas.
17
2. DESCRIPCIÓN DEL CÓDIGO PARA EL
PROCESADO DE VÍDEOS EN ELECTRO-FLOW-FOCUSING
2.1 Introducción
En los siguientes epígrafes del presente trabajo se van a proceder a explicar las diferentes partes que conforman el código, objeto principal de este documento. Dicho código ha sido implementado en una interfaz
gráfica de usuario (GUI) mediante el programa informático Matlab, lo que permite en la mayor medida
facilitar al usuario en el manejo del programa y la obtención satisfactoria de los resultados deseados. Su objetivo es el procesado de vídeos de experimentos de microfluídica analizando chorros y burbujas en
conductos.
El alcance de este trabajo, como se verá más adelante, comprende entre otras cosas, la implementación de dos de estas interfaces gráficas comentadas anteriormente. La primera de ellas, es una continuación de la que
realizó Fernando Carrión Ronda en [2] a la que se le ha añadido un nuevo bloque denominado Profile el cual
se explicará en el subapartado 2.4. La segunda, es una GUI nueva denominada Miplot y es más sencilla que la
anterior pero no por ello menos útil ya que permite al usuario (como su nombre indica) la representación de los
resultados obtenidos en la primera (en el bloque Profile) y, que se explicará en detalle en el subapartado 2.5.
Un breve esquema de cómo fluye la información entre las dos interfaces puede ser el siguiente:
Figura 2.1 Diagrama de flujo de información entre las dos interfaces gráficas.
En él, se observa cómo para ejecutar el bloque Profile es necesario proporcionarle vídeos (o imágenes).
Éstos pueden venir dados en los siguientes formatos:
1. Vídeos en formato .avi.
2. Vídeos en formato .tif comprimidos o descomprimidos.
3. Imágenes en formato .tif.
Una vez que el bloque Profile trata alguno de estos formatos, devuelve unos archivos en formato .txt,
éstos son de dos tipos:
1. Archivo .txt con los parámetros seleccionados por el usuario y los resultados obtenidos.
2. Tantos archivos .txt como el usuario desee con las coordenadas abcisas y ordenadas del chorro bajo
estudio.
Los segundos son requeridos por la segunda interfaz gráfica Miplot para generar unas gráficas
superpuestas de los chorros que le interesen al usuario. Estas gráficas se almacenan en formato .fig para que el
usuario las pueda modificar posteriormente.
Por último, se procede a comentar lo que se va a tratar en las siguientes subsecciones. En la subsección
2.2 se describen las principales variables que han servido para almacenar la información más relevante. En la
2.3 se comenta de forma breve el funcionamiento del módulo Preprocessor. En la siguiente, subsección 2.4, se
explica detalladamente cómo funciona el bloque Profile de la primera GUI. Finalmente, la última de ellas, la
Miplot Profile Vídeos Archivos .txt Archivos .fig
18 Descripción del código para el procesado de vídeos en electro-flow-focusing
subsección 2.5 trata la segunda GUI (Miplot) de igual forma que se hace en el
subapartado anterior, es decir, explicando con detalle tanto archivos de entrada y salida como el
funcionamiento que lleva intrínseco.
2.2 Descripción de las variables principales
Como se ha dicho anteriormente, se procede, en el presente apartado a comentar las variables que
permiten almacenar la información más importante a lo largo del código. Puesto que dicho código, en parte, es
una continuación del realizado en [2] es necesario utilizar algunas de las variables que en él se definen. Una
vez dicho esto, éstas son:
1. Param: Estructura en la que se guardan datos importantes para un tratamiento posterior de los mismos.
Esta compuesta, a su vez, de las siguientes variables:
Resolution: Resolución en m por píxel.
Framerate: Fotogramas por segundo de grabación del vídeo.
Rotate: Rotación (ángulo) necesaria para colocar los fotogramas en la posición necesaria para
realizar el análisis de manera correcta.
Object_area: Primera aproximación del área de la burbuja.
Frnum: Vector con los números de los fotogramas que serán analizados.
Roi: Vector con los cuatro vértices que definen la región de interés.
Bbnum: Vector que contiene los números de las burbujas generadas en el vídeo y, tras su
correspondiente tratamiento, las elegidas por el usuario.
Inc_bb: Incremento con el que decide el usuario estudiar las burbujas.
Object_diam: Primera aproximación del diámetro de la burbuja. Calculada a partir de
object_area.
Bbnum2: Vector que contiene los números de las burbujas generadas en el vídeo y, tras su
correspondiente tratamiento, las elegidas por el usuario.
Selected_bubble: Burbuja seleccionada por el usuario.
2. Results: Estructura en la que se almacenan los resultados obtenidos en los bloques anteriores al Profile y, que se usa en éste para usar cierta información. Se compone, a su vez, de las siguientes variables
para cada fotograma analizado:
TotalNrBubbles: Total de burbujas capturadas hasta el fotograma correspondiente incluyendo
todos los anteriores analizados.
3. Results_profile: Estructura en la que se almacenan los resultados obtenidos en el bloque Profile y, que
se usará, posteriormente, en la segunda interfaz gráfica. Contiene la siguiente información:
Diam: Vector que contiene los valores mínimos de los diámetros del chorro en el momento
de la rotura de las burbujas seleccionadas por el usuario.
X: Matriz de celdas que contiene las coordenadas de abcisas del chorro en el momento de la
rotura, con tantas filas como burbujas seleccione el usuario.
Y_top: Matriz de celdas que contiene las coordenadas de ordenadas superior del chorro en el
momento de la rotura con tantas filas como burbujas seleccione el usuario.
Y_bot: Matriz de celdas que contiene las coordenadas de ordenadas inferior del chorro en el
momento de la rotura con tantas filas como burbujas seleccione el usuario.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 19
X2: Matriz de celdas que contiene las coordenadas de abcisas del chorro elegido por el
usuario en los instantes de tiempo seleccionados por éste con tantas filas como instantes haya.
Y_top2: Matriz de celdas que contiene las coordenadas de ordenadas superior del chorro elegido por el usuario en los instantes de tiempo seleccionados por éste con tantas filas como
instantes haya.
Y_bot2: Matriz de celdas que contiene las coordenadas de ordenadas inferior del chorro
elegido por el usuario en los instantes de tiempo seleccionados por éste con tantas filas como
instantes haya.
4. Sdir, filename: Cadena de caracteres en la que se almacena la dirección de la carpeta en la que se
encuentra el vídeo y nombre, respectivamente.
5. Format_index: Variable en la que se almacena un número entre uno y cuatro dependiendo del tipo de
archivo que se pretende analizar.
2.3 Preprocessor
No es objeto de este trabajo la implementación de este módulo, pero debido a que el usuario lo utilizará posteriormente, se considera explicarlo, aunque de forma breve. No obstante, si se quiere profundizar en el
contenido se pueden encontrar los detalles del mismo en el apartado 3.3 de [2].
A modo de introducción, en este apartado se realizan una serie de operaciones con el objetivo de
contextualizar el análisis a realizar, paso necesario para su posterior análisis.
2.3.1 Select a new file
Automáticamente al ejecutar el programa, antes de que aparezca el menú se ejecuta esta acción. Al tomar
el archivo de entrada deseado por el usuario el programa es capaz de retener cierta información del vídeo que
será de interés en apartados posteriores, ésta se almacena en las siguientes variables:
Sdir: Dirección del archivo que se pretende analizar.
Filename: Nombre del archivo que se pretende analizar.
Format_index: Número que identifica el tipo del formato del archivo a analizar. Es de gran interés para otros módulos en los que se debe seleccionar un fotograma ya que en función del
formato se lee de una manera diferente. Los valores que se le atribuyen son:
Formato: .avi, entonces format_index vale uno.
Formato: .tif comprimido, entonces format_index vale dos.
Formato: .tif descomprimido, entonces format_index vale tres.
Formato: imagen .tif, entonces format_index vale cuatro.
2.3.2 Change rotation angle
Para que el programa realice un correcto tratamiento de los archivos es necesario que las burbujas se
desplacen de izquierda a derecha, es por esto por lo que en algunas ocasiones es necesario girar el archivo
puesto que este podría no venir dado en la posición correcta.
El ángulo a girar se mide en grados y en el sentido convencional de giros y momentos. Además este valor
se almacena en la variable param.rotationangle y, en los siguientes módulos que se trabaje sobre la imagen,
ésta ya aparecerá girada.
2.3.3 Select region of interest
En este apartado se pretende seleccionar una región más pequeña para realizar el estudio, para lo que
concierne en este trabajo sirve para contabilizar las burbujas que se forman en el vídeo. Los puntos que definen
20 Descripción del código para el procesado de vídeos en electro-flow-focusing
esta región se almacenan en la variable param.roi.
Para definirla, como se verá en el apartado “Breve manual de uso”, el usuario debe seleccionar los dos
puntos correspondientes a los dos vértices opuestos del rectángulo que la define.
2.3.4 Change resolution
Si se quiere cambiar la resolución del vídeo que viene por defecto se debe ejecutar este submódulo. Esta
información se almacena en la variable param.resolution para un tratamiento posterior en otros submódulos.
2.3.5 Change framerate
Por otro lado, si el usuario desea modificar los fotogramas por segundo (fps) del vídeo puede usar este
apartado. Para guardar la información se utiliza la variable param.framerate.
2.3.6 Change analysis range
En este apartado, con el objetivo de reducir el tiempo de análisis, el usuario puede elegir los fotogramas
que le interesen analizar, desde el primero hasta el último además de poder elegir el incremento deseado. La
variable utilizada para almacenar estos fotogramas es param.frnum.
2.3.7 Object size
Para terminar el primer módulo del programa es necesario que se reconozca una burbuja con el objetivo
de reducir el rango de búsqueda. Lo que se hace al encontrar la gota es tomar su área, valor de gran
importancia para apartados poteriores.
La manera de reconocerla es idéntica a la de la región de interés pero lo que debe estar en el interior del rectángulo ahora es la gota. Para detectar la burbuja en esta región y almacenar su área se utiliza la función
get_objects que devuelve entre cierta información, el área de la burbuja que se almacena en la variable
param.object_area. Si el lector está interesado en aprender más sobre esta función se recomienda leer el
apartado 3.3.5 de [2].
2.4 Profile
Este subapartado hace referencia al último bloque añadido a la primera interfaz gráfica. Se denomina
Profile y tiene como objetivo obtener las coordenadas del contorno del chorro de las diferentes burbujas a gusto del usuario, es decir, según las burbujas que éste elija además de los instantes de tiempo. En la siguiente
imagen se muestra el menú interactivo con los diferentes bloques de los que se compone, incluido el Profile:
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 21
Figura 2.2 Menú interactivo de la primera interfaz gráfica de usuario, Analizar2.
Como se observa, está formado, a su vez, por tres subbloques:
1. Change bubble range.
2. Change time range.
3. Save results.
Es importante decir, que para ejecutar este bloque es necesario ejecutar los dos anteriores (Preprocessor
y Analysis).
2.4.1 Change bubble range
En este subbloque se pretenden obtener las coordenadas del contorno del chorro justamente en el
momento de la rotura. Además, al hacerlo de manera interactiva se le permite al usuario que elija las burbujas
que más le interesen.
Puesto que el usuario no sabe cuántas burbujas se generan en el vídeo, previamente a la operación de
elección, se le proporcionan por pantalla.
En lo que respecta a dicha operación de elección, es conveniente explicarla para no dejar lugar a dudas.
Es necesario introducir tres datos:
1. First bubble: Primera burbuja a interés del usuario.
2. Last bubble: Última burbuja a interés del usuario.
3. Increment: Incremento deseado por el usuario.
Hay que dejar claro que la forma de elegir las burbujas se hace igual a como se definen los elementos en
un vector en Matlab, es decir, para respetar el incremento, la última gota elegida (en 2) podría o no podría
(dependiendo de dicho incremento) formar parte del estudio.
Para solventar cualquier duda si aún la hubiera se plantean los dos siguientes ejemplos, ambos para el
mismo vídeo con lo que el número de burbujas que se generan es el mismo: 14; y, además se eligen la primera
y la última burbujas iguales para notar la diferencia:
22 Descripción del código para el procesado de vídeos en electro-flow-focusing
Ejemplo 1
1. First bubble: 5
2. Last bubble: 10
3. Increment: 1
Burbujas a representar: 5, 6, 7, 8, 9, 10.
Ejemplo 2
1. First bubble: 5
2. Last bubble: 10
3. Increment: 2
Burbujas a representar: 5, 7, 9.
Donde se aprecia que en el segundo ejemplo la última gota elegida no formaría parte del estudio.
Posteriormente, el programa le pide al usuario que elija la región de interés del chorro que desea estudiar,
para seleccionarla se deben elegir los dos vértices opuestos de un rectángulo; en concreto, el superior izquierdo y el inferior derecho. Es conveniente tomar una gota en dicha región ya que el chorro crece en los siguientes
fotogramas y se podría salir y, además, esto no conllevaría ningún problema adicional. Como requisito a tener
en cuenta para seleccionar dicha región se deberá tomar de tal forma que no contenga a las líneas que
delimitan el conducto ya que podría llevar a errores en la ejecución del programa. Dicha región se almacena en
el código en la variable roi_jet.
En la siguiente figura se representa un ejemplo de región de interés del chorro:
Figura 2.3 Región de interés del chorro.
Acto seguido, el programa pide que se defina la línea de referencia a partir de la cual se comenzará a
medir la longitud del chorro. Para seleccionarla, se debe hacer de igual forma a como se hizo para la región de interés, es decir, pinchando en la imagen y seleccionando, pero ahora con la peculiaridad de que es una línea y
no un rectángulo con lo que solamente harán falta dos puntos: el superior y el inferior; en este mismo orden.
Esta línea siempre será vertical con lo que una vez definido el primer punto (el superior), el segundo (el
inferior) estará en el mismo punto de abcisa que el primero. Como principal requisito para definir dicha línea siempre deberá estar contenida en la región de interés del chorro. Dicha línea se almacena en el código en las
variables x_ref e y_ref.
En la siguiente figura se representa un ejemplo de línea de referencia del chorro definida en el lugar
apropiado para medir la longitud de éste:
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 23
Figura 2.4 Línea de referencia del chorro.
Una vez que se han definido tanto la región de interés del chorro como la línea de referencia del mismo,
el programa analiza para cada fotograma del vídeo el contorno de éste obteniendo sus coordenadas (tanto abcisas como ordenadas). Para ello se siguen los siguientes pasos que se explicarán sin entrar en mayor detalle,
si se quiere profundizar en el contenido véase el apartado 3.5.4. de [2]:
1. Tratamiento de la imagen: El tratamiento que se le realiza a la imagen es quedarse con la región de
interés seleccionada, pasar a binario (blanco y negro), eliminar pequeños elementos y rellenar los
huecos de blanco.
2. Trazado del contorno del chorro: Esto se realiza mediante la función bwtraceboundary de Matlab.
En las siguientes figuras se puede apreciar lo comentado anteriormente.
Figura 2.5 Imagen del chorro en binario y habiendo eliminado los elementos que no son de interés.
Figura 2.6 Imagen del chorro una vez que se rellena y se ha trazado la frontera.
3. Longitud del chorro: Se calcula como la diferencia entre la coordenada abcisa máxima de la frontera
del chorro y la coordenada abcisa de la línea de referencia. Este valor es de bastante utilidad puesto
que se utiliza como se verá más adelante como parte del criterio de rotura con lo que se almacena en
la variabe jet_length.
4. Diámetro del chorro: Se calcula recorriendo desde la línea de referencia hasta el final del chorro y
encontrando los píxeles más altos (almacenados en la variable y_top) y los más bajos (almacenados
en la variable y_bot). La diferencia de estas dos variables proporciona el valor del diámetro del chorro que se almacena en la variable diam, esto se puede entender más fácilmente observando la figura 2.7.
Todos estos valores serán de utilidad, tanto las ordenadas (para obtener la representación de la
frontera) como el valor del diámetro (para el criterio de rotura).
24 Descripción del código para el procesado de vídeos en electro-flow-focusing
Figura 2.7 Cálculo del diámetro del chorro. Imagen tomada de [2].
Con lo que en resumen, se obtienen dos variables de mucho interés:
1. Diam: Vector que almacena en cada una de sus componentes la distancia en píxeles entre los puntos
superior e inferior del contorno del chorro para cada fotograma.
2. Jet_length: Vector que almacena en cada una de sus componentes la longitud del chorro para todos los
frames.
El siguiente paso es el más importante de todos y puede ser el que más tiempo ha llevado a la elaboración
del código y no es otro que establecer el criterio de rotura, puesto que en este subbloque, como se comentó
anteriormente, lo que se pretende obtener son las coordenadas cartesianas del contorno del chorro justamente
en el momento de la rotura.
En un primer momento, se optó por crear una variable (vector) que almacenara para cada fotograma el
valor mínimo de los diámetros de ese fotograma, es decir, el valor mínimo del vector diam sería almacenado
en una nueva variable denominada min_diam. Resulta lógico pensar que en el primer fotograma que esta variable se hiciera cero ya habría roto el chorro y se habría formado la burbuja con lo que el programa
guardaba las variables de interés del fotograma justamente anterior. La condición básicamente consistió en
imponer que el valor de min_diam fuera cero en el actual fotograma y, además mayor que cero en el anterior. Sin embargo, a pesar de que funcionaba correctamente para vídeos de chorro corto, para los de chorro largo
debido a la propia longitud del mismo para algunas roturas el valor del diámetro mínimo cuando rompía no era
nulo.
En un estudio posterior, se decide introducir una variable (vector) adicional y es la anteriormente
mencionada jet_length. De forma general, en esta variable se irán almacenando valores cada vez mayores
mientras el chorro vaya creciendo y, justamente cuando rompa, su valor disminuirá drásticamente, es entonces
cuando el programa guarda las variables de interés del fotograma justamente anterior.
Finalmente, para hacer el código más robusto se impone una tercera condición mediante la variable
frames_rotura la cual permite descartar errores introducidos por las dos anteriores. En esta última se
almacenan los fotogramas en los que se produce la rotura y se compara con el fotograma que verifica las dos anteriores; si la diferencia es mayor que el número total de frames dividido entre las burbujas generadas se
almacena y, sino, se descarta.
Por último, para los fotogramas que cumplen todas estas condiciones (lógicamente son los mismos que burbujas se generan) se almacenan los variables de interés: diámetro (por tener cierta información) y
coordenadas cartesianas (tanto abcisas como ordenadas superior e inferior) para las burbujas elegidas por el
usuario.
Mientras todo esto ocurre de forma interna en el programa, se le representa al usuario por pantalla los
instantes justamente posteriores a la rotura de las gotas consideradas por éste.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 25
2.4.2 Change time range
Si se pretende, por el contrario, obtener representaciones de diferentes instantes de tiempo (ya sean o no
los del instante de rotura) de una misma burbuja habría que ejecutar este apartado.
De igual manera que en el apartado anterior, lo primero que se le muestra al usuario tras ejecutarlo es el número total de burbujas que han sido capturadas y, posteriormente, que introduzca cuál de ellas pretende
estudiar, la cual se almacena en la variable param.selected_bubble.
Acto seguido, se deben definir tanto la región de interés del chorro como la línea de referencia del
mismo. Así como la manera en la que el programa lo ejecuta y el usuario la define es idéntica a la del
subapartado anterior.
Lo siguiente que se hace es un barrido de todos los fotogramas del vídeo imponiendo las condiciones de
rotura anteriormente explicadas y atribuyendo a cada burbuja los frames en los que todavía son parte de un chorro. Esto se consigue almacenando estos fotogramas en una matriz de celdas denominada frames con tantas
filas como gotas se formen y de una única columna. De este modo, cuando el usuario defina los instantes de
tiempo que desea representar será más fácil encontrarlos, además, se muestran por pantalla. De igual modo que en el subapartado anterior, mientras todo esto se ejecuta internamente en el programa, al usuario se le muestra
por pantalla la representación en binario de la evolución del chorro dentro de la región de interés.
A continuación, el usuario introducirá los instantes de tiempo en los que quiera obtener la
representación del contorno del chorro. Puesto que el objetivo final que se persigue es comparar diferentes chorros (o burbujas) en el mismo instante de tiempo y, como cada vídeo presenta una frecuencia de generación
de burbujas diferente, resulta interesante definir una variable adimensional de tiempo que permita relacionar
instantes similares entre vídeos diferentes; esta es tau y cuyos valores se encuentran entre 0 (instante inicial) y
1 (instante final).
Los instantes de tiempo seleccionados por el usuario se identifican con los fotogramas mediante la
variable frames2 y, ahora se hace de nuevo un barrido pero solamente de los fotogramas almacenados en esta
última variable. Este segundo barrido se hace igual que el primero (seleccionando la región de interés del chorro, la línea de referencia, etc.), en lo único que difiere es que para estos fotogramas se guarda la
información del contorno del chorro en las variables x3, y_top3 e y_bot3.
2.4.3 Save results
Como último subpartado de la primera interfaz gráfica, se propone uno tal que le permite al usuario salvar los parámetros y resultados obtenidos en los subapartados anteriores en archivos de texto. Para realizar
esto, se emplean las funciones fopen, fprintf y fclose de Matlab.
Como se dijo en la introducción, se obtienen dos tipos de archivos de texto:
1. Archivo .txt con los parámetros seleccionados por el usuario y los resultados obtenidos.
Este primer archivo recoge información tanto del bloque Preprocessor como del Profile. En el
caso de este último, la información que aparezca depende de si se ejecuta un subbloque u otro.
El nombre del archivo de texto con el que se guarda es el nombre del vídeo analizado seguido de
la siguiente cadena de caracteres: ‘Profile.txt’.
En la siguiente figura se representa un ejemplo de este archivo de salida en el que se han ejecutado
los dos subbloques del Profile:
26 Descripción del código para el procesado de vídeos en electro-flow-focusing
Figura 2.8 Ejemplo de archivo de texto de salida del primer tipo.
2. Tantos archivos .txt como el usuario desee con las coordenadas abcisas y ordenadas del chorro
bajo estudio.
Si se ejecuta Change bubble range se obtendrán tantos archivos .txt como burbujas se hayan seleccionado con las coordenadas del contorno en el momento de la rotura. El nombre con el que
se salva es el nombre del vídeo estudiado seguido del número de la burbuja en cuestión y, se opta
por elegir el valor ‘2’ para el instante de tiempo ya que al ser inadmisible (tau varía entre 0 y 1),
permite diferenciar a los archivos generados en este subbloque de los del siguiente.
Por otro lado, si se ejecuta Change time range se guardarán tantos archivos de texto como
instantes de tiempo el usuario haya elegido de la burbuja también escogida por él. En este caso, el
nombre del archivo es el del vídeo seguido del número de la burbuja y del instante de tiempo.
La siguiente figura representa un caso como este último donde la primera columna representa las
coordenadas abcisas, la segunda las ordenadas superiores y la tercera las ordenadas inferiores:
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 27
Figura 2.9 Ejemplo de archivo de texto de salida del segundo tipo.
Ambos archivos de texto son guardados automáticamente tanto en la carpeta que se encuentra el vídeo como en la que está el programa. La idea de esto es tener los archivos de salida junto con su correspondiente
vídeo en la misma carpeta (se verá en el siguiente apartado que la gráfica de salida también se guarda igual)
siendo necesario así mismo para la segunda interfaz que los documentos de texto se encuentren también en la
carpeta del programa.
2.5 Miplot
Este subapartado hace referencia a la segunda interfaz gráfica. Se denomina Miplot y cuyo objetivo es
analizar los archivos de texto del segundo tipo obtenidos anteriormente. En la siguiente figura se muestra el menú interactivo con los diferentes bloques de los que se compone y con el espacio reservado para la
representación:
28 Descripción del código para el procesado de vídeos en electro-flow-focusing
Figura 2.10 Menú interactivo de la segunda interfaz gráfica de usuario, Miplot.
Se observa que está formado, a su vez, por tres subbloques:
1. Plot figure.
2. Save figure.
3. Delete figure.
En los siguientes subapartados se proceden a explicar cada uno de ellos de manera más detallada.
2.5.1 Plot figure
Este primer subbloque de la segunda interfaz gráfica permite al usuario representar el chorro o chorros que éste desee. Básicamente, lo que hace es leer los archivos de texto (introducidos por el usuario), almacenar
su información y mostrarla por pantalla por medio de una representación.
Es conveniente hacer aquí una clara diferenciación de los dos tipos de representaciones que se pueden
hacer con independencia del instante de tiempo:
1. Burbujas diferentes dentro de un mismo vídeo.
2. Misma burbuja en vídeos diferentes.
Puesto que se da libertad al usuario para elegir el número de burbujas a representar de un vídeo (ó el número de vídeos de una misma burbuja), así como el número de instantes de tiempo es necesario definir dos
variables que recojan esta información. Éstas son: N1 y N2.
N1: Variable que hace referencia al número de burbujas que se quieren representar dentro de un mismo
vídeo o bien, al número de vídeos de una misma burbuja.
N2: Variable que hace referencia al número de instantes de tiempo que se quieren considerar.
Estos valores permiten definir la representación, la cual se realiza con la función subplot de Matlab y, además, en el caso de que solo se quiera hacer un plot de un solo chorro se puede diferenciar fácilmente al ser
ambos idénticamente la unidad (una burbuja o un vídeo y un instante de tiempo). Por último, también sirven
para mostrar un mensaje por pantalla al usuario en caso de que el número de archivos de texto introducidos por
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 29
éste no sea el correcto.
Quizás una de las mayores complicaciones de este subbloque fue la implementación de la leyenda ya
que, como es lógico, depende del nombre de los archivos de texto en cuestión y en estos, a su vez, puede variar: el nombre del vídeo, el número de la burbuja y el instante de tiempo con lo que para hacerlo robusto lo
que se plantea es para cada una de estas tres variables recorrer la matriz de celdas en la que se almacena el
nombre de los vídeos y comprobar si cambian estas variables (nombre del vídeo, número de la burbuja e
instante de tiempo). En caso de que cambie se actualiza una nueva variable (vector) que para cada caso es: index_name, index_bubble e index_tau y, por tanto si, por ejemplo, es el instante de tiempo el que cambia en
cada vídeo la variable correspondiente al tiempo será:
index_tau=[1 2 3 4 5 6… n], siendo n el número de archivos de texto seleccionados.
Si por el contrario el instante de tiempo no cambia este vector es idénticamente el de la unidad:
index_tau=[1 1 1 1 1 1… 1]
De igual forma ocurre con los otros dos índices (el de la burbuja y el del nombre).
Posteriormente, se crea en una matriz de celdas la leyenda en función de estas variables anteriores para
más tarde representarla junto a las gráficas de forma que siempre se identifique cada chorro con el mismo
color.
Un error que aparecía en varias representaciones era la existencia de “picos” hacia arriba en el chorro,
para eliminarlo se opta por atribuirle a puntos mayores al 50% de la media el propio valor de la media.
Además, para que cada representación sea acorde con sus ejes (que no quede sobredimensionado para
chorros cortos) se propone definir los ejes como sigue:
Eje de abcisas: Un 10% mayor de la longitud del chorro más largo.
Eje de ordenadas: El doble del espesor del chorro más ancho en la zona más gruesa (suele ser al final,
donde se forma la burbuja).
Por último, se representa en la siguiente figura a modo de ejemplo de este módulo un caso en el que se ha
comparado un chorro corto y uno largo para la misma burbuja (la quinta) y para los mismos cinco instantes de
tiempo:
Figura 2.11 Representación de dos chorros (corto y largo) de la quinta burbuja para cinco instantes obtenida al ejecutar Plot figure.
30 Descripción del código para el procesado de vídeos en electro-flow-focusing
2.5.2 Save figure
En el caso de que la representación del apartado anterior sea la que se esperaba se procede a ser guardada
ejecutando este subbloque. Además, salva dicha representación en un archivo .fig con el objetivo de que si el
usuario posteriormente quiere trabajar con él pueda hacerlo.
Puesto que la representación tiene como fin comparar varios tipos de chorro, el nombre que se le atribuye
al archivo de salida (.fig) es básicamente el nombre que se utiliza para los archivos de texto con sus
correspondientes variables (frecuencia, voltaje, burbuja e instante de tiempo) pero, para aquellas variables que
sean diferentes entre los vídeos se sobrescriben con el carácter ‘X’. Para aclarar esta idea se exponen dos
ejemplos:
Ejemplo 1: Mismo vídeo e instante de tiempo y 4 burbujas diferentes
1. f50v1000.avib02tau0.40.txt
2. f50v1000.avib04tau0.40.txt
3. f50v1000.avib06tau0.40.txt
4. f50v1000.avib08tau0.40.txt
Nombre del archivo: f50v1000.avib0Xtau0.40.fig
Ejemplo 2: Misma burbuja e instante de tiempo y 4 condiciones experimentales diferentes
1. f20v1000.avib03tau0.50.txt
2. f30v1000.avib03tau0.50.txt
3. f40v1000.avib03tau0.50.txt
4. f50v1000.avib03tau0.50.txt
Nombre del archivo: fX0v1000.avib03tau0.50.fig
El archivo de salida (.fig) se almacena tanto en la carpeta donde se encuentra el vídeo (como se dijo
anteriormente para tenerlo todo en la misma carpeta) como en la que está el programa.
Se adjunta a continuación un ejemplo de este tipo de archivo, nótese que es la misma representación que
en el caso anterior pero ya guardada como .fig.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 31
Figura 2.12 Representación de dos chorros (corto y largo) de la quinta burbuja para cinco instantes obtenida al ejecutar Save figure.
2.5.3 Delete figure
Si por el contrario, la representación obtenida por pantalla no es la adecuada o simplemente se quiere
limpiar el espacio de la interfaz reservado para los plots hay que ejecutar este subbloque. Lo que hace en resumidas cuentas no es otra cosa que borrar la(s) gráfica(s) que haya para dar paso a otra(s) que se quiera(n)
representar posteriormente.
33
3 BREVE MANUAL DE USO
En el presente capítulo se exponen los pasos que el usuario debe seguir para poder utilizar ambos
programas. El orden en el que se va a explicar es el orden correcto y el que el usuario debe seguir para realizar
con éxito el procesado de vídeos de microfluídica y la posterior representación de los casos de mayor interés.
3.1 Analizar2
En primer lugar, para poder obtener las representaciones es necesario calcular el perfil de los chorros y
esto se consigue con esta primera interfaz gráfica. Ésta contiene más bloques para el tratamiento de vídeos en microfluídica de los que se van a explicar en este capítulo, para aprender a usarlos veáse el Capítulo 4 de [2].
Para ejecutarla se puede escribir ‘analizar2’ en el Command Window de Matlab o bien pinchar en el botón
‘Run’ del Editor.
3.1.1 Preprocessor
Lo primero que el programa pide es el vídeo que debe ser analizado, para ello se muestra por pantalla una
ventana similar a la de la Figura 3.1. En ella, se puede seleccionar en la esquina inferior derecha el formato del
archivo (.avi, .tif comprimido, .tif descomprimido o imagen .tif). Una vez que se selecciona el formato
deseado, solamente aparecen en la carpeta los archivos de ese formato en concreto.
Figura 3.1 Ventana de selección de archivo de entrada a la primera GUI.
34 Breve manual de uso
Posteriormente, se selecciona el archivo que se quiere procesar y se abre la ventana de la interfaz gráfica.
La figura 3.2 muestra el menú interactivo tal y como debería aparecer en el que se aprecian los diferentes módulos y el primer fotograma del archivo de entrada. En las siguientes líneas se explica para cada uno de los
subbloques del Preprocessor en qué casos y cómo se deben utilizar.
Figura 3.2 Ventana interactiva de la primera GUI. Encuadrado en rojo se aprecia el módulo Preprocessor.
1. Change video/image: Si se quiere cambiar el archivo a analizar, ya sea en caso de fallo o para realizar
un nuevo estudio sin cerrar el programa, se debe ejecutar este subbloque. Para el segundo caso es necesario pulsar previamente el botón “Clear Data” para evitar que se confundan datos y resultados
entre análisis de vídeos diferentes. La manera de introducir el nuevo archivo (vídeo o imagen) es
idéntica a la explicada anteriormente.
2. Change rotation angle: Si el usuario considera que el vídeo se encuentra girado puede colocarlo horizontal con esta opción teniendo en cuenta que el programa analiza los vídeos con las gotas
circulando de izquierda a derecha. Para girarlo, se debe introducir el valor numérico (en grados)
teniendo en cuenta que se ha utilizado el criterio convencional de signos para giros y momentos (positivo para un giro contrario a las agujas del reloj y negativo para uno en el sentido de las agujas
del reloj). En las siguientes dos figuras aparecen dos casos: el primero (Figura 3.3) para un fotograma
colocado en la posición correcta y el segundo (Figura 3.4) para un fotograma en vertical y que es
necesario girarlo 90.
Figura 3.3 Ejemplo de fotograma orientado en la posición correcta.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 35
Figura 3.4 Ejemplo de fotograma orientado en una posición incorrecta. Imagen tomada de [2].
3. Select region of interest: Se procede a definir la región mediante la cual el programa va a calcular
cuántas gotas se forman en el vídeo, para ello, hay que seleccionar dos puntos que son los dos vértices
opuestos del rectángulo que define dicha región sin importar el orden en que se den. Es necesario tomar una región suficiente que abarque a la primera burbuja formada, de forma idéntica a como
aparece en la Figura 3.5. El programa “contará” cuántas gotas pasan por esta región y, posteriormente,
restará una (la ya formada que queda atrapada en dicha región).
Figura 3.5 Ejemplo de región de interés. En este caso al no haber interferencias se toma como región la primera burbuja.
Se debe dejar claro al usuario que si en el primer fotograma del vídeo a tratar aparecen interferencias (pequeñísimas gotitas, manchas o una continuación muy pequeña del chorro) entre el chorro y la primera gota,
se recomienda tomar como región de interés la correspondiente a la segunda burbuja teniendo en cuenta el
usuario que el programa habrá contabilizado una gota más. Esto se debe realizar debido a un problema que
surge en el paso 7 como se verá más adelante. En la siguiente figura se representa un ejemplo de interferencia
y cuál sería la región de interés que se debe seleccionar.
36 Breve manual de uso
Figura 3.6 Ejemplo de interferencia y de región de interés que se debería elegir.
4. Change resolution: Seleccionando esta opción se puede cambiar la resolución del vídeo en 𝜇𝑚/𝑝𝑖𝑥𝑒𝑙. Este dato es bastante importante si el usuario decide ejecutar el bloque Postprocessor ya que los
resultados se calculan en píxeles y, posteriormente, se transforman en m mediante este valor.
5. Change framerate: Seleccionando esta opción se puede cambiar la velocidad de adquisición del vídeo
en fps.
6. Change analysis range: Esta opción le permite al usuario analizar sólo aquellos fotogramas que a él le interesen reduciendo de este modo, el tiempo de análisis. Al ejecutarlo, aparece una ventana en la que
se deben introducir el primer fotograma a estudiar, el último y el incremento. Hay que tener especial
precaución con el caso del incremento ya que si entre dos fotogramas que se analizan una burbuja
viaja una distancia igual o superior a la que separa dos burbujas el análisis no sería correcto.
7. Object size: Al ejecutar este paso se debe seleccionar una burbuja para capturar su tamaño (área) y
tenerlo de referencia. Para seleccionar una gota con éxito se debe realizar el mismo proceso que para la región de interés con la peculariedad de que ahora no aparecen las líneas discontinuas rojas; no
obstante, para que el usuario se asegure de que el programa ha detectado la burbuja, su contorno se
tiñe de rojo como el caso que aparece en la Figura 3.7. Si no se detecta, no se muestra nada y se toma
el área que hay por defecto, es muy importante que se detecte correctamente la burbuja para evitar
errores.
Figura 3.7 Ejemplo de burbuja detectada correctamente ya que se observa su perímetro en color rojo.
Si se da el caso comentado en el paso 3 habría que elegir la segunda gota ya que debido a las
interferencias el programa no es capaz de detectar la primera. En este caso, habría que definir de nuevo la región de interés ya que al no detectar la burbuja, al contabilizarlas se obtendría un número muy bajo de
burbujas generadas. No obstante, esto se comprueba al ejecutar los pasos 15 y 16 puesto que lo primero que se
muestra por pantalla es el número total de burbujas encontradas; si este valor es muy pequeño se debe
seleccionar la segunda burbuja como región de interés.
En la siguiente figura se adjunta un ejemplo de interferencia en la que se muestra la segunda burbuja
detectada ya que la primera no ha podido ser encontrada por el programa.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 37
Figura 3.8 Ejemplo de interferencia y de la burbuja detectada que se debería elegir.
3.1.2 Analysis
8. Analyze frames: Llegado a este punto ya se han realizado los correspondientes pasos del módulo
Preprocessor previos al análisis del vídeo. En este caso, el programa recorre cada fotograma del vídeo obteniendo información de interés para después utilizarla en el resto de módulos. Cuando el usuario
ejecute este paso aparecerá en pantalla una barra de estado como la de la Figura 3.9 que muestra el
progreso del análisis (en tanto por ciento) además de el número de fotogramas sobre el total que han
sido analizados. Finalmente, al terminar esta acción, la barra de estado desaparece y ya se está en
disposición de ejecutar el último módulo, Profile.
Figura 3.9 Ejemplo de barra de estado analizando los fotogramas.
3.1.3 Profile
Posteriormente, para obtener los archivos de texto que contienen las coordenadas del contorno se debe ejecutar este bloque, recuadrado en rojo en la Figura 3.10. Según le interese al usuario obtener un tipo de
representación u otra debe ejecutar un submódulo u otro siendo ambos independientes con lo que se puede
ejecutar uno sin necesidad de otro.
38 Breve manual de uso
Figura 3.10 Ventana interactiva de la primera GUI. Encuadrado en rojo se aprecia el módulo Profile.
15. Change bubble range: En el caso de que el usuario esté interesado en obtener la representación del
contorno del chorro en el momento de la rotura debe ejecutar este submódulo.
Al ejecutarlo, en el cuadro de diálogo aparecerá el número total de burbujas encontradas e instantáneamente se abrirá una ventana similar a la de la Figura 3.11 en la que el usuario debe introducir la
primera burbuja a estudiar, la última y el incremento entre burbujas.
Figura 3.11 Ventana para introducir las burbujas a estudiar.
Como ya se vió anteriormente (pero se repite en este punto debido a su importancia) puede ser que
debido al incremento la última burbuja no entre a formar parte del estudio con lo que hay que tener cuidado a
la hora de seleccionar dicho incremento o la última gota. Para despejar cualquier tipo de duda se adjuntan los
mismos ejemplos que en el apartado 2.4.1:
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 39
Ejemplo 1
4. First bubble: 5
5. Last bubble: 10
6. Increment: 1
Burbujas a representar: 5, 6, 7, 8, 9, 10.
Ejemplo 2
4. First bubble: 5
5. Last bubble: 10
6. Increment: 2
Burbujas a representar: 5, 7, 9.
Posteriormente, se debe introducir la región de interés del chorro. La forma de seleccionarla es idéntica a
la de la burbuja y es recomendable tomar la primera burbuja ya formada con el fin de que el chorro esté en
todos los fotogramas ya que puede crecer y salirse de la región de interés. Un ejemplo de región de interés del
chorro se muestra en la Figura 3.12:
Figura 3.12 Ejemplo de región de interés del chorro.
El siguiente paso es seleccionar la línea de referencia del chorro a partir de la cual se empieza a medir la
longitud del mismo. Para ello, el usuario debe indicar dos puntos, el superior y el inferior (no importa si el
punto inferior no se encuentra en la vertical del superior ya que el programa lo hace automáticamente). Un
ejemplo de línea de referencia del chorro se adjunta en la Figura 3.13:
Figura 3.13 Ejemplo de línea de referencia del chorro.
Automáticamente después, se abre una ventana de progreso idéntica a la del punto 8 y, además se
muestran los instantes justamente posteriores a la rotura del chorro para las burbujas seleccionadas tal cuales
como el programa los trata y representado uno de ellos en la siguiente figura:
40 Breve manual de uso
Figura 3.14 Fotograma mostrado al usuario del instante posterior a la rotura para las burbujas seleccionadas por el usuario.
Una vez que el programa termina de analizar todos los fotogramas las ventanas se cierran y el usuario
debe decidir si quiere estudiar para el mismo vídeo diferentes instantes de tiempo (punto 16) o, finalizar
guardando los archivos de texto con las coordenadas del contorno del chorro para las gotas seleccionadas en el
momento de la rotura (punto 17).
16. Change time range: En el caso de que el usuario esté interesado en obtener la representación del contorno
del chorro para una burbuja en concreto y en diferentes instantes de tiempo debe ejecutar este submódulo.
De nuevo, al ejecutarlo, se muestra en el cuadro de diálogo el número total de burbujas encontradas en
el vídeo y, automáticamente se abre una ventana similar a la de la Figura 3.15 en la que el usuario debe
introducir la burbuja que desea estudiar.
Figura 3.15 Ventana para la selección de la burbuja a estudiar.
Una vez que se ha introducido la burbuja que se desea estudiar, el siguiente paso es seleccionar la región de interés del chorro y, posteriormente, la línea de referencia. La forma de hacerlo es exactamente igual que la
explicada en el punto anterior. De nuevo, se abre una ventana de progreso y se muestra por pantalla para todos
los frames la evolución del chorro puesto que se recorren todos los fotogramas para identificar en cuáles de
ellos se encuentra la gota elegida.
Acto seguido, aparece en el cuadro de diálogo los frames en los que la gota elegida forma parte del
chorro y, además, una ventana como la de la Figura 3.16 en la que el usuario debe introducir los instantes de tiempo en los que quiere estudiar la evolución del chorro en cuestión. Posteriormente, se muestra en el cuadro
de diálogo los instantes que van a ser almacenados. Para aclarar alguna duda se presenta el siguiente ejemplo:
Ejemplo
Número de instantes de tiempo: 5.
Instantes a representar: 0, 0.25, 0.5, 0.75, 1.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 41
Figura 3.16 Ventana para la selección del número de instantes de tiempo.
Lo siguiente que hace el programa es para estos instantes almacenar la información relevante, es decir, las coordenadas del contorno. Además, la forma de operar es exactamente la misma: región de interés del
chorro y línea de referencia del mismo. Esto hace que el programa sea muy fácil de utilizar.
Finalmente, se representan por pantalla los instantes de tiempo justamente después a los seleccionados de
la burbuja en cuestión y este submódulo finaliza.
17. Save results: Cuando el usuario ha ejecutado uno o los dos bloques anteriores debe guardar esa
información para realizar un tratamiento posterior. Al ejecutar este punto no aparece nada por pantalla, sino que se guarda automáticamente tanto en la carpeta en la que se encuentra el vídeo como en la que está el
programa una serie de archivos de texto con los siguientes nombres y contenidos:
‘FilenameProfile.txt’: Archivo que se guarda independientemente de cuál de los dos submódulos
anteriores se ejecute y que contiene tanto parámetros que se seleccionan en el Preprocessor y en el
Profile como resultados de éste último. En la Figura 3.17 se muestra un ejemplo de este caso.
‘Filenamebbubblenumbertaumomenttime.txt’: Archivo que contiene por columnas las coordenadas
abcisa, ordenada superior y ordenada inferior del contorno del chorro. La única diferencia entre los dos submódulos es el número que acompaña a “tau”, en caso de haber ejecutado el paso 15 éste sería
2 (por no saber a priori que instante en concreto es y para poder diferenciar los archivos .txt del caso
de la rotura y de los instantes generales); y, en caso de haber ejecutado el 16 éste sería el del instante en cuestión. Un ejemplo de este tipo de archivo se adjunta en la Figura 3.18 donde se observa que para
valores crecientes de la coordenada abcisa (primera columna) las ordenadas se mantienen constantes
(segunda y tercera columnas), esto es debido a que se trata del comienzo de un chorro largo.
42 Breve manual de uso
Figura 3.17 Ejemplo de archivo de texto que se genera con los parámetros y resultados.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 43
Figura 3.18 Ejemplo de archivo de texto que se genera con las coordenadas del chorro. La primera columna representa las
coordenadas abcisas, la segunda las ordenadas superiores y la tercera las ordenadas inferiores.
3.2 Mi plot
Una vez que el usuario ya dispone de los archivos de texto ya está en condiciones de usar la segunda
interfaz gráfica. Al igual que en la anterior los archivos de entrada eran los vídeos o imágenes, ahora en éste
son los archivos .txt. Para ejecutarla, se puede escribir ‘miplot’ en el Command Window de Matlab o bien
pinchar en el botón ‘Run’ del Editor. Tras hacer esto, se abre la ventana de la interfaz gráfica (similar a la de la
Figura 3.19) en la cual hay tres bloques que se explican a continuación:
44 Breve manual de uso
Figura 3.19 Ventana interactiva de la segunda GUI.
1. Plot figure: Como su nombre indica, si se quiere representar algún chorro este es el apartado que se
debe ejecutar.
En primer lugar, se abre una ventana idéntica a la de la Figura 3.20 en la que el usuario debe introducir
o bien, el número de archivos de texto correspondientes a diferentes burbujas que se desean estudiar de un mismo vídeo o el número de archivos de texto correspondientes a diferentes vídeos y a una misma
burbuja.
Figura 3.20 Ventana para la selección del número de burbujas de un mismo vídeo o para la selección del número de vídeos de una
misma burbuja que se quieren representar.
Acto seguido, se abre otra ventana similar a la de la Figura 3.21 en la que se debe introducir el número
de instantes de tiempo que se quieren estudiar.
Figura 3.21 Ventana para la selección del número de instantes de tiempo que se quieren estudiar.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 45
Posteriormente, se abre una ventana para seleccionar los archivos de texto igual a la de la Figura 3.22
en la que el usuario debe seleccionar los archivos .txt que está interesado en representar. Para
seleccionarlos, debe hacerlo de una sola vez con lo que se recomienda usar la tecla “ctrl” y clicar sobre cada uno de los archivos. En el caso de que no coincida el número dado en las dos primeras ventanas con
el número de archivos de texto seleccionados aparece un mensaje de error en el cuadro de diálogo. Es
importante que los archivos de texto se encuentren en la carpeta del programa para no inducir a errores, es
por esto por lo que se guardaron en la carpeta del vídeo (para tenerlos de una forma ordenada) y en la del
programa (para evitar este error).
Figura 3.22 Ventana para seleccionar los archivos de texto que se quieren tratar.
Por último, en el caso de que no se produzca este error, aparece en el espacio reservado para la representación tantos plots como instantes de tiempo diferentes se quieran representar y en ellos,
superpuestas, tantas gráficas como vídeos o burbujas diferentes se hayan considerado. En la Figura 3.23 se
adjunta el caso que ya se vió anteriormente:
46 Breve manual de uso
Figura 3.23 Representación de dos chorros (corto y largo) de la quinta burbuja para cinco instantes obtenida al ejecutar Plot figure.
2. Save figure: En el caso de que la anterior representación sea la correcta y definitiva, el usuario puede
almacenarla para además de preservarla, poder trabajar con ella (por eso se opta por dotarla de un
formato .fig). Un ejemplo de este tipo de archivo se adjunta en la Figura 3.24:
Figura 3.24 Representación de dos chorros (corto y largo) de la quinta burbuja para cinco instantes obtenida al ejecutar Save figure.
La figura se guarda tanto en la carpeta del vídeo (si el archivo de texto se toma de esta carpeta) como
en la que se encuentra el programa (se tome el archivo de texto de una carpeta u otra) y su nombre es la misma
cadena de caracteres de los archivos de texto con la peculiaridad de que las variables (frecuencia, voltaje,
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 47
burbuja o instante de tiempo) que sean diferentes se le atribuye el carácter ‘X’. Para aclarar esta idea se
exponen unos ejemplos similares a los del subapartado 2.5.2:
Ejemplo 1: Mismo vídeo e instante de tiempo y 4 burbujas diferentes
1. f50v1000.avib02tau0.40.txt
2. f50v1000.avib11tau0.40.txt
3. f50v1000.avib17tau0.40.txt
4. f50v1000.avib20tau0.40.txt
Nombre del archivo: f50v1000.avibXXtau0.40.fig
En la siguiente figura se representan estos cuatro casos:
Figura 3.25 Representación de cuatro chorros en las mismas condiciones (frecuencia y voltaje) y para el mismo instante de tiempo
para cuatro burbujas distintas.
Ejemplo 2: Misma burbuja e instante de tiempo y 4 condiciones experimentales diferentes
1. f20v1000.avib03tau0.50.txt
2. f30v1000.avib03tau0.50.txt
3. f40v1000.avib03tau0.50.txt
4. f50v1000.avib03tau0.50.txt
Nombre del archivo: fX0v1000.avib03tau0.50.fig
En la siguiente figura se representan estos cuatro casos:
Figura 3.26 Representación de cuatro chorros para los mismos voltaje, instante de tiempo y burbuja para cuatro valores de la
frecuencia diferentes.
Por último, si a la hora de elegir los archivos de texto éstos se han tomado de la propia carpeta del programa, aparece en el Command Window de Matlab un mensaje de error que se debe ignorar ya que viene a
decir que ha sido imposible copiar la representación (ya guardada en la carpeta del programa) en la misma
carpeta.
48 Breve manual de uso
3. Delete figure: En el caso de que la representación no sea la esperada o se haya producido algún error a la
hora de seleccionar los archivos de texto se puede eliminar lo que hay en el espacio reservado para los plots
ejecutando este módulo. Posteriormente, se puede volver a graficar usando el módulo 1.
3.3 Ejemplos
En este último subapartado del capítulo se incluyen una serie de gráficas a modo de ejemplo con una
breve explicación de cada una de ellas:
Ejemplo 1: Comparación de cuatro burbujas diferentes de un mismo chorro corto en los
instantes de rotura.
Figura 3.27 Representación de cuatro burbujas distintas de un mismo chorro corto en el instante de rotura.
Al ser un estudio de cuatro casos bajo las mismas condiciones experimentales, para las cuatro burbujas,
el chorro es prácticamente igual en el momento de la rotura para todas ellas.
Ejemplo 2: Comparación de cuatro burbujas diferentes de un mismo chorro largo en los
instantes de rotura.
Figura 3.28 Representación de cuatro burbujas distintas de un mismo chorro largo en el instante de rotura.
De igual forma que en el ejemplo anterior, al ser el estudio bajo iguales condiciones experimentales
(frecuencia y voltaje) los cuatro chorros son similares en el instante de la rotura.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 49
Ejemplo 3: Comparación de dos chorros (corto y largo) de una misma burbuja para los mismos
cinco instantes de tiempo.
Figura 3.29 Representación de dos chorros (corto y largo) de una misma burbuja (la quinta) para los mismos cinco instantes de
tiempo .
En este tercer caso se opta por comparar un chorro corto y uno largo (ejemplo ya visto a lo largo del
documento). Se aprecia notablemente cómo cambios de la frecuencia y del voltaje cambian notablemente la
longitud del chorro, este hecho se verá con más detalle en el siguiente capítulo.
50 Breve manual de uso
Ejemplo 4: Comparación de dos chorros (para dos valores de la frecuencia y para el mismo
voltaje) de una misma burbuja para los mismos cuatro instantes de tiempo.
Figura 3.30 Representación de dos chorros (diferente frecuencia y mismo voltaje) de una misma burbuja (la tercera) para
los mismos cuatro instantes de tiempo .
Puesto que comparar chorros tan diferentes como el caso anterior parece no ser tan interesante (por ser tan
diferentes), se opta en este caso mantener una de las variables constante (voltaje) y variar la otra (frecuencia).
Es este caso el que se tratará con más detalle en el siguiente capítulo.
Se aprecia en la anterior representación, de forma general, que al aumentar la frecuencia la longitud del
chorro disminuye.
53
4 ESTUDIO
Como aplicación práctica al código explicado en el presente documento se realiza un estudio real en el
que se propone tomar diferentes vídeos, es decir, distintos chorros sometidos a diferentes condiciones experimentales (frecuencia y voltaje) y, para una misma burbuja, estudiar su variación para los mismos
instantes de tiempo.
Los vídeos seleccionados han sido grabados con unos caudales de la fase continua (Qi) y de la fase
dispersa (Qo) de:
𝑄𝑖 = 50𝜇𝑙
ℎ; 𝑄𝑜 = 400
𝜇𝑙
ℎ
Además, se estudia para dos conductividades diferentes, éstas son:
𝑘 = 0.3𝑚𝑆
𝑚, 3
𝑚𝑆
𝑚
Por último, se fija una de las condiciones experimentales (voltaje) y se hace variar la otra (frecuencia):
𝑉 = 1000 𝑉; 𝑓 = 5 𝑘𝐻𝑧, 10 𝑘𝐻𝑧, 20 𝑘𝐻𝑧, 30 𝑘𝐻𝑧, 40 𝑘𝐻𝑧, 50 𝑘𝐻𝑧
El proceso a seguir para obtener las representaciones finales es exactamente el mismo que el explicado en
el apartado anterior:
1. Se ejecuta el módulo Preprocessor de la primera GUI.
2. Posteriormente, se ejecuta el módulo Profile de la primera GUI, en este caso el submódulo “Change
time range” y se selecciona una burbuja cualquiera (en este caso la tercera) y cinco instantes de
tiempo.
Los dos primeros pasos se realizan para todos los vídeos, es decir, doce veces.
3. Finalmente, se representan las gráficas mediante el módulo “Plot figure” de la segunda GUI. Para ello,
se eligen los seis vídeos diferentes (tantos como valores de la frecuencia distintos hay) para cuatro de
los instantes de tiempo elegidos anteriormente (se descarta el inicial).
Esta acción se hace duplicada para cada conjunto de vídeos con la misma conductividad.
En los siguientes apartados se muestran las representaciones obtenidas y un breve comentario sobre los
resultados observados.
4.1 Conductividad fija, frecuencia variable y diferentes instantes de tiempo (caso 1)
En primer lugar, se representan los chorros de una misma burbuja (la tercera) para el valor más pequeño
de la conductividad, manteniendo el voltaje constante y variando la frecuencia como se comentó
anteriormente. Además, se realiza para cuatro instantes de tiempo diferentes. En resumen:
𝑘 = 0.3𝑚𝑆
𝑚
𝑉 = 1000 𝑉; 𝑓 = 5 𝑘𝐻𝑧, 10 𝑘𝐻𝑧, 20 𝑘𝐻𝑧, 30 𝑘𝐻𝑧, 40 𝑘𝐻𝑧, 50 𝑘𝐻𝑧
Burbuja: Tercera
𝜏 = 0.25, 0.5, 0.75, 1
54 Estudio
Figura 4.1 Representación de seis chorros diferentes variando la frecuencia, voltaje y conductividad constantes para cuatro instantes
de tiempo diferentes de la tercera burbuja.
De forma general, se observa (salvo algunos errores) que los chorros para cada instante de tiempo son
bastante similares y, además que el tipo de chorro es de longitud media; esto como se verá más adelante está
muy influenciado por uno de los parámetros, la conductividad. Otro comportamiento observado es el hecho de
que al aumentar la frecuencia, la longitud del chorro disminuye.
4.2 Conductividad fija, frecuencia variable y diferentes instantes de tiempo (caso 2)
En segundo lugar, se realiza un estudio similar al anterior: mismos voltaje, variación de frecuencia,
burbuja y mismos instantes de tiempo. Sin embargo, se modifica el valor de la conductividad obteniéndose
chorros cualitativamente diferentes. Las variables pasan a ser ahora:
𝑘 = 3𝑚𝑆
𝑚
𝑉 = 1000 𝑉; 𝑓 = 5 𝑘𝐻𝑧, 10 𝑘𝐻𝑧, 20 𝑘𝐻𝑧, 30 𝑘𝐻𝑧, 40 𝑘𝐻𝑧, 50 𝑘𝐻𝑧
Burbuja: Tercera
𝜏 = 0.25, 0.5, 0.75, 1
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 55
Figura 4.2 Representación de seis chorros diferentes variando la frecuencia, voltaje y conductividad constantes para cuatro instantes
de tiempo diferentes de la tercera burbuja.
De nuevo, se observa que de forma general, cualitativamente, los chorros coinciden para cada instante de
tiempo. Además, el tipo de chorro es, en este caso, largo (debido al incremento en la conductividad, no
obstante, esto se aprecia mejor en el siguiente apartado). También, se aprecia, al igual que en el apartado
anterior que la longitud del chorro disminuye con el aumento de la frecuencia.
4.3 Frecuencia fija, conductividad variable y diferentes instantes de tiempo
En este tercer caso se opta por comparar chorros con mismos voltaje, frecuencia, burbuja e instante de
tiempo entre los que se hace variar los valores de la conductividad vistos antes para apreciar de una mejor forma cómo varían con este parámetro. Cabe decir que el chorro de mayor conductividad es el representado en
la leyenda en la parte inferior. Dicho esto, se presentan los siguientes seis casos:
56 Estudio
Caso 1:
𝑘 = 0.3𝑚𝑆
𝑚, 3
𝑚𝑆
𝑚
𝑉 = 1000 𝑉; 𝑓 = 50 𝑘𝐻𝑧
Burbuja: Tercera
𝜏 = 0.25, 0.5, 0.75, 1
Figura 4.3 Representación de dos chorros diferentes manteniendo la frecuencia (50 kHz) y voltaje constantes y variando la
conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja.
Se aprecia fundamentalmente que la longitud del chorro para el caso de mayor conductividad es superior
que la del caso de menor conductividad.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 57
Caso 2:
𝑘 = 0.3𝑚𝑆
𝑚, 3
𝑚𝑆
𝑚
𝑉 = 1000 𝑉; 𝑓 = 40 𝑘𝐻𝑧
Burbuja: Tercera
𝜏 = 0.25, 0.5, 0.75, 1
Figura 4.4 Representación de dos chorros diferentes manteniendo la frecuencia (40 kHz) y voltaje constantes y variando la
conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja.
De nuevo, se observa que la longitud del chorro es superior para el caso de mayor conductividad.
Además, como se dijo en los apartados anteriores, la longitud del chorro aumenta con la disminución de la
frecuencia; dicho efecto también se aprecia si se comparan estas gráficas con las anteriores (estos fenómenos
se observan para el resto de casos con lo que no se volverán a comentar).
58 Estudio
Caso 3:
𝑘 = 0.3𝑚𝑆
𝑚, 3
𝑚𝑆
𝑚
𝑉 = 1000 𝑉; 𝑓 = 30 𝑘𝐻𝑧
Burbuja: Tercera
𝜏 = 0.25, 0.5, 0.75, 1
Figura 4.5 Representación de dos chorros diferentes manteniendo la frecuencia (30 kHz) y voltaje constantes y variando la
conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 59
Caso 4:
𝑘 = 0.3𝑚𝑆
𝑚, 3
𝑚𝑆
𝑚
𝑉 = 1000 𝑉; 𝑓 = 20 𝑘𝐻𝑧
Burbuja: Tercera
𝜏 = 0.25, 0.5, 0.75, 1
Figura 4.6 Representación de dos chorros diferentes manteniendo la frecuencia (20 kHz) y voltaje constantes y variando la
conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja.
60 Estudio
Caso 5:
𝑘 = 0.3𝑚𝑆
𝑚, 3
𝑚𝑆
𝑚
𝑉 = 1000 𝑉; 𝑓 = 10 𝑘𝐻𝑧
Burbuja: Tercera
𝜏 = 0.25, 0.5, 0.75, 1
Figura 4.7 Representación de dos chorros diferentes manteniendo la frecuencia (10 kHz) y voltaje constantes y variando la
conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja.
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 61
Caso 6:
𝑘 = 0.3𝑚𝑆
𝑚, 3
𝑚𝑆
𝑚
𝑉 = 1000 𝑉; 𝑓 = 5 𝑘𝐻𝑧
Burbuja: Tercera
𝜏 = 0.25, 0.5, 0.75, 1
Figura 4.8 Representación de dos chorros diferentes manteniendo la frecuencia (5 kHz) y voltaje constantes y variando la
conductividad para cuatro instantes de tiempo diferentes de la tercera burbuja.
Para este último, se aprecia de manera bastante clara lo comentado anteriormente referente a la influencia de la conductividad en la longitud del chorro. Además, se aprecia de forma general que el momento de rotura
se produce antes para los chorros con la conductividad mayor.
4.4 Conclusiones del estudio
De los resultados del estudio se pueden realizar unas conclusiones basadas en la observación de las
representaciones:
1. La longitud del chorro es inversamente proporcional a la frecuencia.
2. La longitud del chorro es directamente proporcional a la conductividad.
3. El instante de rotura se produce antes para conductividades mayores.
63
5 CONCLUSIONES
Como conclusión al trabajo realizado en la programación de un código para el procesado de vídeos
generados en microfluídica, cabe destacar que mediante las dos interfaces gráficas es posible obtener a partir de un vídeo o imagen una representación gráfica de cualquier chorro (correspondiente a una burbuja) en
cualquier instante de su formación. Esto le ofrece al usuario la gran libertad de comparar diferentes chorros, ya
sea entre diferentes vídeos o en el mismo vídeo.
Además, debido a la forma de la realización del código en diferentes bloques y al ser muchas de las
variables de carácter global, el programa puede ser fácilmente continuado introduciendo nuevos módulos.
65
6 CÓDIGO EMPLEADO
En este último capítulo del documento se adjunta el código empleado para cada una de las dos interfaces.
6.1 Analizar 2
%PROFILE % --- Executes on button press in BubbleRange15. function BubbleRange15_Callback(hObject, eventdata, handles)
global sdir files param background results results_profile info mov
format_index filename jet bubb
texto1=strcat(' -> Number bubbles captured:
',num2str(results(end).totalNrBubbles-1));
set(handles.text1,'String',texto1); set(handles.text2,'String',' '); set(handles.text3,'String',' '); set(handles.text4,'String',' ');
param.bbnum=1:results(end).totalNrBubbles-1; % total bubbles to be
analyzed
if length(param.bbnum)>=2 param.inc_bb=param.bbnum(2)-param.bbnum(1); else param.inc_bb=1; end
answer=inputdlg({'First bubble [#]','Last bubble [#]','Increment [#]'},...
'',1,{num2str(param.bbnum(1)),num2str(param.bbnum(end)),num2str(param.inc_bb)
});
param.bbnum(1)=str2num(answer{1}); param.bbnum(end)=str2num(answer{2}); param.inc_bb=str2num(answer{3}); bubb=param.bbnum(1):param.inc_bb:param.bbnum(end);
axes(handles.axes2); im=imread('LogoEtsi.png'); imshow(im);
if format_index==1 %.avi image=read(mov,1); end
if format_index==2 %.tif compressed image=imread(strcat(sdir,filename),1); end
66 Código empleado
if format_index==3 %.tif descompressed image=imread(strcat(sdir,files(1).name)); end
if format_index==4 %.tif image image=imread(strcat(sdir,filename)); end
%Jet ROI
image=imrotate(image,param.rotate,'bilinear','crop');
roi_jet=round([1 size(image,2) 1 size(image,1)]); axes(handles.axes1); imshow(image) hold on, plot([roi_jet(1), roi_jet(2),... roi_jet(2),roi_jet(1),... roi_jet(1)],[roi_jet(3),... roi_jet(3),roi_jet(4),... roi_jet(4), roi_jet(3)], 'r--'), hold off
texto1=' -> Take the region of interest of the jet you want to study ';
set(handles.text1,'String',texto1); set(handles.text2,'String',' '); set(handles.text3,'String',' '); set(handles.text4,'String',' ');
button=questdlg('Jet region of interest ok?','','Yes','No','Yes'); while ~strcmp(button,'Yes') [x y]=ginput(2); % get two
coordinates for the roi x=sort(x); y=sort(y); if x(1)<1, x(1)=1; end % validate the
coordinates if x(2)>size(image,2), x(2)=size(image,2); end if y(1)<1, y(1)=1; end if y(2)>size(image,1), y(2)=size(image,1); end
roi_jet=int16([x(1) x(2) y(1) y(2)]); % update the
roi
imshow(image) hold on, plot([roi_jet(1), roi_jet(2),... roi_jet(2),roi_jet(1),... roi_jet(1)],[roi_jet(3),... roi_jet(3),roi_jet(4),... roi_jet(4), roi_jet(3)], 'r--'), hold off
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 67
button=questdlg('Jet region of interest ok?','','Yes','No','Yes'); end dial=' -> Jet region of interest is set'; set(handles.text1,'String',dial); set(handles.text2,'String',' '); set(handles.text3,'String',' '); set(handles.text4,'String',' ');
jet(1).roi=roi_jet;
%Reference line
button='';
button=questdlg('Select reference line','','Ok','Ok'); button='No';
while ~strcmp(button,'Yes') imshow(image) [x_ref y_ref]=ginput(2); x_ref=[x_ref(1) x_ref(1)]; hold on plot(x_ref,y_ref,'r'),hold off button=questdlg('Correct reference line?','','Yes','No','Yes'); end
dial=' -> Jet reference line is set'; set(handles.text1,'String',dial); set(handles.text2,'String',' '); set(handles.text3,'String',' '); set(handles.text4,'String',' ');
x_refroi=[x_ref(1)-min([roi_jet(1) roi_jet(2)]), x_ref(1)-min([roi_jet(1)
roi_jet(2)])];%Reference line in the roi coordinates system
%Start analazing
voortgang=waitbar(0,cat(2,'0%
[0/',int2str(length(param.frnum)),']'),'NumberTitle','off','Name','Analyzing
frames...');
ii=2; k=0; kk=2; espaciado=floor(param.frnum(end)/(results(end).totalNrBubbles-1))-10;
for z=1:length(param.frnum)
framenum=param.frnum(z);
%-- Read image if format_index==1 %.avi image=read(mov,framenum); end
if format_index==2 %.tif compressed image=imread(strcat(sdir,filename),framenum); end
68 Código empleado
if format_index==3 %.tif descompressed image=imread(strcat(sdir,files(framenum).name)); end
if format_index==4 %.tif image image=imread(strcat(sdir,filename)); end
image=imrotate(image,param.rotate,'bilinear','crop'); a_size=size(image);
if length(a_size)>2 image=rgb2gray(image); end
%Process image image=image(roi_jet(3):roi_jet(4),roi_jet(1):roi_jet(2)); a_size=size(image); image=~im2bw(image,graythresh(image)); image=bwareaopen(image,10); image(:,1)=1;%Fill with 1s the left border image=imfill(image,'holes');%Fill the jet with 1s
%Calculate jet boundary B=bwtraceboundary(image,[double(a_size(1)-1)
double(1)],'E',8,800,'clockwise'); jet(z).boundary=B;
%Calculate jet length jet_length(z)=max(B(:,2));
%Calculate jet diameter a=1;
for i=x_refroi(1):jet_length(z)-1 %Look for top limits from reference
line to the end of the jet y_top(i) = max(find(image(:,i)));%Top jet limit y_bot(i) = min(find(image(:,i)));%Bottom jet limit diam(a) = y_top(i)-y_bot(i);%Diameter for every vertical line a=a+1; end
param.object_diam=sqrt(4*param.object_area/pi);
%Minimum diameter for every frame min_diam(1)=param.object_diam; min_diam(ii)=min(diam);
%Cell arrays with the coordinates x2{z,:}=x_refroi(1):jet_length(z)-1; y_top2{z,:}=y_top(x_refroi(1):jet_length(z)-1); y_bot2{z,:}=y_bot(x_refroi(1):jet_length(z)-1);
%Array where it is stocked the frames which the drops appear frames_rotura(1)=1; frames_rotura(2)=2;
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 69
if z==1 elseif jet_length(z-1)-jet_length(z)>10 if length(frames_rotura)==2 k=k+1; for jj=1:length(bubb) if k==bubb(jj) axes(handles.axes2); imshow(image) hold on plot(B(:,2),B(:,1),'r'); title(num2str(k)) hold off pause(1) end end diam_bubble(k)=min_diam(ii-1);
x2_bubble{k,:}=x2{z-1,:}; y_top2bubble{k,:}=y_top2{z-1,:}; y_bot2bubble{k,:}=y_bot2{z-1,:};
kk=kk+1; frames_rotura(kk)=z; end if z-frames_rotura(kk)>=espaciado k=k+1; for jj=1:length(bubb) if k==bubb(jj) axes(handles.axes2); imshow(image) hold on plot(B(:,2),B(:,1),'r'); title(num2str(k)) hold off pause(1) end end
diam_bubble(k)=min_diam(ii-1);
x2_bubble{k,:}=x2{z-1,:}; y_top2bubble{k,:}=y_top2{z-1,:}; y_bot2bubble{k,:}=y_bot2{z-1,:};
kk=kk+1; frames_rotura(kk)=z; end elseif min_diam(ii)==0 && min_diam(ii-1)>0 if length(frames_rotura)==2 k=k+1; for jj=1:length(bubb) if k==bubb(jj) axes(handles.axes2); imshow(image) hold on plot(B(:,2),B(:,1),'r'); title(num2str(k)) hold off pause(1) end end
70 Código empleado
diam_bubble(k)=min_diam(ii-1);
x2_bubble{k,:}=x2{z-1,:}; y_top2bubble{k,:}=y_top2{z-1,:}; y_bot2bubble{k,:}=y_bot2{z-1,:};
kk=kk+1; frames_rotura(kk)=z; end if z-frames_rotura(kk)>=espaciado k=k+1; for jj=1:length(bubb) if k==bubb(jj) axes(handles.axes2); imshow(image) hold on plot(B(:,2),B(:,1),'r'); title(num2str(k)) hold off pause(1) end
end
diam_bubble(k)=min_diam(ii-1); x2_bubble{k,:}=x2{z-1,:}; y_top2bubble{k,:}=y_top2{z-1,:}; y_bot2bubble{k,:}=y_bot2{z-1,:};
kk=kk+1; frames_rotura(kk)=z;
end
end
waitbar(z/length(param.frnum),voortgang,strcat(int2str(round(100*z/length(par
am.frnum))),'% [',int2str(z),'/',int2str(length(param.frnum)),']'));
ii=ii+1;
end
close(voortgang);
axes(handles.axes2); im=imread('LogoEtsi.png'); imshow(im);
diam_bubb_user=diam_bubble(param.bbnum(1):param.inc_bb:param.bbnum(end)); x_bubb_user=x2_bubble(param.bbnum(1):param.inc_bb:param.bbnum(end),:);
y_top_bubb_user=y_top2bubble(param.bbnum(1):param.inc_bb:param.bbnum(end),:);
y_bot_bubb_user=y_bot2bubble(param.bbnum(1):param.inc_bb:param.bbnum(end),:);
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 71
x_bubb_user(end+1,:)=x_bubb_user(end,:); y_top_bubb_user(end+1,:)=y_bot_bubb_user(end,:); y_bot_bubb_user(end+1,:)=y_bot_bubb_user(end,:);
results_profile.diam=diam_bubb_user; results_profile.x=x_bubb_user; results_profile.y_top=y_top_bubb_user; results_profile.y_bot=y_bot_bubb_user;
% --- Executes on button press in TimeRange16. function TimeRange16_Callback(hObject, eventdata, handles) % hObject handle to TimeRange16 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
global sdir files param background results results_profile info mov
format_index filename jet selected_bubble tau;
texto1=strcat(' -> Number bubbles captured:
',num2str(results(end).totalNrBubbles-1));
set(handles.text1,'String',texto1); set(handles.text2,'String',' '); set(handles.text3,'String',' '); set(handles.text4,'String',' ');
param.bbnum2=1:results(end).totalNrBubbles-1; % total bubbles to be
analyzed
answer_1=inputdlg({'Select bubble [#]'},... '',1,{num2str(param.bbnum2(1))});
param.selected_bubble=str2num(answer_1{1}); selected_bubble=str2num(answer_1{1});
%Se recorre primero para todos los frames del vÌdeo
if format_index==1 %.avi image=read(mov,1); end
if format_index==2 %.tif compressed image=imread(strcat(sdir,filename),1); end
if format_index==3 %.tif descompressed image=imread(strcat(sdir,files(1).name)); end
if format_index==4 %.tif image image=imread(strcat(sdir,filename)); end
%----- Jet ROI
image=imrotate(image,param.rotate,'bilinear','crop');
roi_jet=round([1 size(image,2) 1 size(image,1)]); axes(handles.axes1);
72 Código empleado
imshow(image) hold on, plot([roi_jet(1), roi_jet(2),... roi_jet(2),roi_jet(1),... roi_jet(1)],[roi_jet(3),... roi_jet(3),roi_jet(4),... roi_jet(4), roi_jet(3)], 'r--'), hold off
button=questdlg('Jet region of interest ok?','','Yes','No','Yes'); while ~strcmp(button,'Yes') [x y]=ginput(2); % get two
coordinates for the roi x=sort(x); y=sort(y); if x(1)<1, x(1)=1; end % validate the
coordinates if x(2)>size(image,2), x(2)=size(image,2); end if y(1)<1, y(1)=1; end if y(2)>size(image,1), y(2)=size(image,1); end
roi_jet=int16([x(1) x(2) y(1) y(2)]); % update the
roi
imshow(image) hold on, plot([roi_jet(1), roi_jet(2),... roi_jet(2),roi_jet(1),... roi_jet(1)],[roi_jet(3),... roi_jet(3),roi_jet(4),... roi_jet(4), roi_jet(3)], 'r--'), hold off
button=questdlg('Jet region of interest ok?','','Yes','No','Yes'); end
dial=' -> Jet region of interest is set'; set(handles.text1,'String',dial); set(handles.text2,'String',' '); set(handles.text3,'String',' '); set(handles.text4,'String',' ');
jet(1).roi=roi_jet; %--- Reference line
button='';
button=questdlg('Select reference line','','Ok','Ok'); button='No';
while ~strcmp(button,'Yes') imshow(image) [x_ref y_ref]=ginput(2); x_ref=[x_ref(1) x_ref(1)]; hold on plot(x_ref,y_ref,'r'),hold off button=questdlg('Correct reference line?','','Yes','No','Yes'); end
dial=' -> Jet reference line is set'; set(handles.text1,'String',dial); set(handles.text2,'String',' ');
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 73
set(handles.text3,'String',' '); set(handles.text4,'String',' ');
x_refroi=[x_ref(1)-min([roi_jet(1) roi_jet(2)]), x_ref(1)-min([roi_jet(1)
roi_jet(2)])];%Reference line in the roi coordinates system
%--- Start analazing jet_length=zeros(1,length(param.frnum));%Initialize vector to save every
frame jet length
voortgang=waitbar(0,cat(2,'0%
[0/',int2str(length(param.frnum)),']'),'NumberTitle','off','Name','Analyzing
frames...'); ii=2; k=0; kk=2; espaciado=floor(param.frnum(end)/(results(end).totalNrBubbles-1))-10;
for z=1:length(param.frnum)
framenum=param.frnum(z);
%-- Read image if format_index==1 %.avi image=read(mov,framenum); end
if format_index==2 %.tif compressed image=imread(strcat(sdir,filename),framenum); end
if format_index==3 %.tif descompressed image=imread(strcat(sdir,files(framenum).name)); end
if format_index==4 %.tif image image=imread(strcat(sdir,filename)); end image=imrotate(image,param.rotate,'bilinear','crop'); a_size=size(image); if length(a_size)>2 image=rgb2gray(image); end
%Process image image=image(roi_jet(3):roi_jet(4),roi_jet(1):roi_jet(2)); a_size=size(image); image=~im2bw(image,graythresh(image)); image=bwareaopen(image,10); image(:,1)=1;%Fill with 1s the left border image=imfill(image,'holes');%Fill the jet with 1s
%Calculate jet boundary B=bwtraceboundary(image,[double(a_size(1)-1)
double(1)],'E',8,800,'clockwise'); axes(handles.axes2); imshow(image) hold on plot(B(:,2),B(:,1),'r'); title(num2str(z)) hold off
74 Código empleado
jet(z).boundary=B;
%Calculate jet length jet_length(z)=max(B(:,2))-x_refroi(1);
a=1; %Calculate jet diameter for i=x_refroi(1):jet_length(z)-1 %Look for top limits from reference
line to the end of the jet y_top(i)=max(find(image(:,i)));%Top jet limit y_bot(i)=min(find(image(:,i)));%Bottom jet limit diam(a)=y_top(i)-y_bot(i);%Diameter for every vertical line a=a+1; end
param.object_diam=sqrt(4*param.object_area/pi);
min_diam(1)=param.object_diam; min_diam(ii)=min(diam);
frames_rotura(1)=1; frames_rotura(2)=2;
if z==1 elseif jet_length(z-1)-jet_length(z)>10 if length(frames_rotura)==2 k=k+1; if k==1 frames{1}=1:z; kk=kk+1; frames_rotura(kk)=z; end if k~=1 v=frames{k-1}; frames{k}=v(end):z; kk=kk+1; frames_rotura(kk)=z; end end if z-frames_rotura(kk)>=espaciado k=k+1; if k==1 frames{1}=1:z; kk=kk+1; frames_rotura(kk)=z; end if k~=1 v=frames{k-1}; frames{k}=v(end):z; kk=kk+1; frames_rotura(kk)=z; end end elseif min_diam(ii)==0 && min_diam(ii-1)>0 if length(frames_rotura)==2 k=k+1; if k==1 frames{1}=1:z; kk=kk+1; frames_rotura(kk)=z;
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 75
end if k~=1 v=frames{k-1}; frames{k}=v(end):z; kk=kk+1; frames_rotura(kk)=z; end end if z-frames_rotura(kk)>=espaciado k=k+1; if k==1 frames{1}=1:z; kk=kk+1; frames_rotura(kk)=z; end if k~=1 v=frames{k-1}; frames{k}=v(end):z; kk=kk+1; frames_rotura(kk)=z; end end end
waitbar(z/length(param.frnum),voortgang,strcat(int2str(round(100*z/length(par
am.frnum))),'% [',int2str(z),'/',int2str(length(param.frnum)),']')); ii=ii+1; end
close(voortgang);
axes(handles.axes2); im=imread('LogoEtsi.png'); imshow(im);
texto1=strcat(' -> Number frames taken: '); texto2=strcat(' -> ',num2str(frames{param.selected_bubble}));
frames_bubble=frames{param.selected_bubble};
set(handles.text1,'String',texto1); set(handles.text2,'String',texto2); set(handles.text3,'String',' '); set(handles.text4,'String',' ');
answer=inputdlg({'Moments of time'},... '',1,{num2str(1)});
answer=str2num(answer{1});
%Variable de tiempo adimensional if answer==1 tau=0.00; elseif answer==2 tau=[0.00 0.50]; elseif answer==10 tau=[0.00 0.10 0.20 0.30 0.40 0.50 0.60... 0.70 0.80 0.90]; else tau=length(1:answer); for ii=2:answer tau(1)=0.00;
76 Código empleado
incremento=1/(answer-1); tau(ii)=tau(ii-1)+incremento; end end
%Redondeo a la segunda cifra significativa los tau ndecimals=2; f=10.^ndecimals; tau=round(f*tau)/f;
texto1=strcat(' -> Number of instants of time taken: '); texto2=strcat(' -> ',num2str(tau));
set(handles.text1,'String',texto1); set(handles.text2,'String',texto2); set(handles.text3,'String',' '); set(handles.text4,'String',' ');
incremento_frs=(frames_bubble(end)-frames_bubble(1))/(answer-1); frames2(1)=frames_bubble(1); for ii=2:length(tau) frames2(ii)=frames2(ii-1)+incremento_frs; end frames2=round(frames2);
%Se recorre ahora para los frames seleccionados
if format_index==1 %.avi image=read(mov,1); end
if format_index==2 %.tif compressed image=imread(strcat(sdir,filename),1); end
if format_index==3 %.tif descompressed image=imread(strcat(sdir,files(1).name)); end
if format_index==4 %.tif image image=imread(strcat(sdir,filename)); end
%----- Jet ROI
image=imrotate(image,param.rotate,'bilinear','crop');
roi_jet=round([1 size(image,2) 1 size(image,1)]); axes(handles.axes1); imshow(image) hold on, plot([roi_jet(1), roi_jet(2),... roi_jet(2),roi_jet(1),... roi_jet(1)],[roi_jet(3),... roi_jet(3),roi_jet(4),... roi_jet(4), roi_jet(3)], 'r--'), hold off
button=questdlg('Jet region of interest ok?','','Yes','No','Yes');
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 77
while~strcmp(button,'Yes') [x y]=ginput(2); % get two
coordinates for the roi x=sort(x); y=sort(y); if x(1)<1, x(1)=1; end % validate the
coordinates if x(2)>size(image,2), x(2)=size(image,2); end if y(1)<1, y(1)=1; end if y(2)>size(image,1), y(2)=size(image,1); end
roi_jet=int16([x(1) x(2) y(1) y(2)]); % update the
roi
imshow(image) hold on, plot([roi_jet(1), roi_jet(2),... roi_jet(2),roi_jet(1),... roi_jet(1)],[roi_jet(3),... roi_jet(3),roi_jet(4),... roi_jet(4), roi_jet(3)], 'r--'), hold off
button=questdlg('Jet region of interest ok?','','Yes','No','Yes'); end
dial=' -> Jet region of interest is set'; set(handles.text1,'String',dial); set(handles.text2,'String',' '); set(handles.text3,'String',' '); set(handles.text4,'String',' ');
jet(1).roi=roi_jet; %--- Reference line
button = '';
button = questdlg('Select reference line','','Ok','Ok'); button= 'No';
while ~strcmp(button,'Yes') imshow(image) [x_ref y_ref] = ginput(2); x_ref=[x_ref(1) x_ref(1)]; hold on plot(x_ref,y_ref,'r'),hold off button=questdlg('Correct reference line?','','Yes','No','Yes'); end
dial=' -> Jet reference line is set'; set(handles.text1,'String',dial); set(handles.text2,'String',' '); set(handles.text3,'String',' '); set(handles.text4,'String',' ');
x_refroi=[x_ref(1)-min([roi_jet(1) roi_jet(2)]), x_ref(1)-min([roi_jet(1)
roi_jet(2)])];%Reference line in the roi coordinates system
%--- Start analazing jet_length = zeros(1,length(param.frnum));%Initialize vector to save every
frame jet length
voortgang=waitbar(0,cat(2,'0%
78 Código empleado
[0/',int2str(length(param.frnum)),']'),'NumberTitle','off','Name','Analyzing
frames...');
ii=2; jj=1; for z=frames2
framenum=param.frnum(z);
%-- Read image if format_index==1 %.avi image=read(mov,framenum); end
if format_index==2 %.tif compressed image=imread(strcat(sdir,filename),framenum); end
if format_index==3 %.tif descompressed image=imread(strcat(sdir,files(framenum).name)); end
if format_index==4 %.tif image image=imread(strcat(sdir,filename)); end
image=imrotate(image,param.rotate,'bilinear','crop'); a_size=size(image);
if length(a_size)>2 image=rgb2gray(image); end
%Process image image=image(roi_jet(3):roi_jet(4),roi_jet(1):roi_jet(2)); a_size=size(image); image=~im2bw(image,graythresh(image)); image=bwareaopen(image,10); image(:,1)=1;%Fill with 1s the left border image=imfill(image,'holes');%Fill the jet with 1s
%Calculate jet boundary B=bwtraceboundary(image,[double(a_size(1)-1)
double(1)],'E',8,800,'clockwise'); axes(handles.axes2); imshow(image) hold on plot(B(:,2),B(:,1),'r'); title(num2str(z)) hold off pause(1) jet(z).boundary=B;
%Calculate jet length jet_length(z)=max(B(:,2));
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 79
a=1; %Calculate jet diameter for i=x_refroi(1):jet_length(z)-1 %Look for top limits from reference
line to the end of the jet y_top(i) = max(find(image(:,i)));%Top jet limit y_bot(i) = min(find(image(:,i)));%Bottom jet limit diam(a) = y_top(i)-y_bot(i);%Diameter for every vertical line a=a+1; end
param.object_diam=sqrt(4*param.object_area/pi);
min_diam(1)=param.object_diam; min_diam(ii)=min(diam);
x3{jj,:}=x_refroi(1):jet_length(z)-1; y_top3{jj,:}=y_top(x_refroi(1):jet_length(z)-1); y_bot3{jj,:}=y_bot(x_refroi(1):jet_length(z)-1);
waitbar(z/length(param.frnum),voortgang,strcat(int2str(round(100*z/length(par
am.frnum))),'% [',int2str(z),'/',int2str(length(param.frnum)),']')); ii=ii+1; jj=jj+1; end
close(voortgang);
axes(handles.axes2); im=imread('LogoEtsi.png'); imshow(im);
x3(end+1,:)=x3(end,:); y_top3(end+1,:)=y_bot3(end,:); y_bot3(end+1,:)=y_bot3(end,:);
results_profile.x2=x3; results_profile.y_top2=y_top3; results_profile.y_bot2=y_bot3;
% --- Executes on button press in SaveResults17. function SaveResults17_Callback(hObject, eventdata, handles) % hObject handle to SaveResults17 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
global param results results_profile filename sdir increment bubb
selected_bubble tau fclose('all'); % delete *.txt ;%Remove previous txt files
%--Save parameters and results %Profile es el primer txt donde se guardan parametros de interes title=strcat(filename,'Profile.txt'); profile=fopen(title,'wt');%Save in text file
fprintf(profile,'**PREPROCESSOR**\n'); fprintf(profile,'\nRotation angle: %d ∫\n',param.rotate); fprintf(profile,'Resolution: %d µm/px\n',param.resolution); fprintf(profile,'Framerate: %d fps\n',param.framerate); fprintf(profile,['First frame: ',int2str(param.frnum(1)),'\n']);
80 Código empleado
fprintf(profile,['Last frame: ',int2str(param.frnum(end)),'\n']); fprintf(profile,'Increment: %d \n',increment);
fprintf(profile,'\n**PROFILE**\n'); fprintf(profile,'\n<BUBBLE RANGE>\n'); fprintf(profile,'-->INPUT PARAMETERS\n');
if ~isempty(results) fprintf(profile,'N∫ of bubbles captured: %d
\n',results(end).totalNrBubbles-1); else fprintf(profile,'\n'); end
if ~isempty(param.bbnum) fprintf(profile,['First bubble: ',int2str(param.bbnum(1)),'\n']); fprintf(profile,['Last bubble: ',int2str(param.bbnum(end)),'\n']); fprintf(profile,['Increment: ',int2str(param.inc_bb),'\n']); else fprintf(profile,'\n'); fprintf(profile,'\n'); fprintf(profile,'\n'); end
fprintf(profile,'\n-->RESULTS\n');
if ~isempty(bubb) fprintf(profile,['Bubbles represented: ',int2str(bubb),'\n']); else fprintf(profile,'\n'); end
fprintf(profile,'\n<TIME RANGE>\n'); fprintf(profile,'-->INPUT PARAMETERS\n');
if ~isempty(results) fprintf(profile,'N∫ of bubbles captured: %d
\n',results(end).totalNrBubbles-1); else fprintf(profile,'\n'); end
if ~isempty(selected_bubble) fprintf(profile,'Selected bubble: %d \n',selected_bubble); else fprintf(profile,'\n'); end
fprintf(profile,'\n-->RESULTS\n');
if ~isempty(tau) fprintf(profile,['Number of instants of time represented:
',num2str(tau),'\n']); else fprintf(profile,'\n'); end
fclose(profile);
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 81
SOURCE=title; DESTINATION=strcat(sdir,title); copyfile(SOURCE,DESTINATION);
if ~isempty(param.bbnum) jj=1;
for ii=param.bbnum(1):param.inc_bb:param.bbnum(end)
index=num2str(ii,'%02d'); title=strcat(filename,'b',index,'tau','2.00','.txt'); fileID=fopen(title,'wt');
v=zeros(size(results_profile.x{jj},2),1); v=results_profile.x{jj,:};
u=zeros(size(results_profile.y_top{jj},2),1); u=results_profile.y_top{jj,:};
w=zeros(size(results_profile.y_bot{jj},2),1); w=results_profile.y_bot{jj,:};
A=zeros(size(results_profile.x{jj},2),3); A(:,1)=v; A(:,2)=u; A(:,3)=w; save(title,'A','-ascii');
jj=jj+1;
fclose(fileID); SOURCE=title; DESTINATION=strcat(sdir,title); copyfile(SOURCE,DESTINATION);
end end
jj=1; if ~isempty(tau) for ii=1:length(tau)
bubble=num2str(param.selected_bubble,'%02d');
title2=strcat(filename,'b',bubble,'tau',num2str(tau(ii),'%10.2f'),'.txt');
%10.2 significa que me interesan los dos decimales y f de flotante fileID=fopen(title2,'wt');
v=zeros(size(results_profile.x2{jj},2),1); v=results_profile.x2{jj,:};
u=zeros(size(results_profile.y_top2{jj},2),1); u=results_profile.y_top2{jj,:};
w=zeros(size(results_profile.y_bot2{jj},2),1); w=results_profile.y_bot2{jj,:};
A=zeros(size(results_profile.x2{jj},2),3); A(:,1)=v; A(:,2)=u;
82 Código empleado
A(:,3)=w;
save(title2,'A','-ascii');
jj=jj+1;
fclose(fileID); SOURCE=title2; DESTINATION=strcat(sdir,title2); copyfile(SOURCE,DESTINATION); end end
6.2 Miplot
function varargout = miplot(varargin) % MIPLOT MATLAB code for miplot.fig % MIPLOT, by itself, creates a new MIPLOT or raises the existing % singleton*. % % H = MIPLOT returns the handle to a new MIPLOT or the handle to % the existing singleton*. % % MIPLOT('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in MIPLOT.M with the given input arguments. % % MIPLOT('Property','Value',...) creates a new MIPLOT or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before miplot_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to miplot_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help miplot
% Last Modified by GUIDE v2.5 28-Dec-2017 18:00:04
% Begin initialization code - DO NOT EDIT
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 83
gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @miplot_OpeningFcn, ... 'gui_OutputFcn', @miplot_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end
if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT
% --- Executes just before miplot is made visible. function miplot_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to miplot (see VARARGIN)
%Put the menu in the center of the screen scrsz=get(0,'ScreenSize'); pos_act=get(gcf,'Position'); xr=scrsz(3)-pos_act(3); xp=round(xr/2); yr=scrsz(4)-pos_act(4); yp=round(yr/2); set(gcf,'Position',[xp yp pos_act(3) pos_act(4)]);
%Choose default command line output for miplot handles.output = hObject;
%Update handles structure guidata(hObject, handles);
%UIWAIT makes miplot wait for user response (see UIRESUME) %uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line. function varargout = miplot_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure varargout{1} = handles.output;
% --- Executes on button press in DeleteFigure3. function DeleteFigure3_Callback(hObject, eventdata, handles) % hObject handle to DeleteFigure3 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB
84 Código empleado
% handles structure with handles and user data (see GUIDATA)
panhandle = uipanel('FontSize',12,'BackgroundColor','white','Position',[0.2
0.05 0.77 0.87]); % axes(handles.panhandle) cla reset; % Borra todos los objetos del axes y resetea todas las
propiedades, % excepto posicion y unidades, a sus valores por defecto.
% --- Executes on button press in PlotFigure1. function PlotFigure1_Callback(hObject, eventdata, handles) % hObject handle to PlotFigure1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
global N1 N2 columna1 columna2 columna3 filename_legend filename index_tau
index_bubble index_name sdir
set(handles.text1,'String',' ');
answer=inputdlg({'N∫ de burbujas 1 vÌdeo Û N∫ de vÌdeos de 1 burbuja'},... '',1,{num2str(1)});
N1=str2num(answer{1});
answer=inputdlg({'N∫ de instantes de tiempo para cada burbuja Û para cada
vÌdeo'},... '',1,{num2str(1)});
N2=str2num(answer{1});
[filename,sdir,~]=uigetfile('*.txt','Select the txt
file','MultiSelect','on');
if N1*N2~=size(filename,2) && N1*N2~=1 texto1=strcat(' -> ERROR: Please, select the .txt files correctly'); set(handles.text1,'String',texto1); end
panhandle=uipanel('FontSize',12,'BackgroundColor','white','Position',[0.2
0.0502 0.77 0.87]);
if N1==1 && N2==1
dat=load(filename);
columna1=dat(:,1); columna2=dat(:,2); columna3=dat(:,3);
%Elimina interferencias indice=columna2==columna3; index=find(indice); if length(index)>2 columna1=columna1(1:index(1));
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 85
columna2=columna2(1:index(1)); columna3=columna3(1:index(1)); end columna1=columna1-columna1(end);
x_max=max(abs(columna1));
%Elimina valores sobredimensionados (para aquellos superiores un 50% de
la media) media2=mean(columna2); media3=mean(columna3);
for jj=1:length(columna2) if columna2(jj)>1.5*media2 columna2(jj)=media2; end end
for jj=1:length(columna3) if columna3(jj)>1.5*media3 columna3(jj)=media3; end end
media2=mean(columna2); media3=mean(columna3);
media=(media2+media3)/2;
columna2=columna2-media; columna3=columna3-media; y_max=max(columna2-columna3);
axes(handles.axes1)
plot([columna1;columna1(end:-1:1)],[columna2;columna3(end:-
1:1)],'linewidth',2) grid on axis equal axis([-1.05*x_max 0 -1.5*y_max 1.5*y_max])
filename_legend=filename(1:end-4); lgd=legend(filename_legend,'Location','NorthEastOutside'); set(lgd,'FontSize',12);
else tau=size(filename,2); bubble=size(filename,2); name=cell(1,size(filename,2));
for ii=1:size(filename,2) tau(ii)=str2num(filename{ii}(end-7:end-4)); bubble(ii)=str2num(filename{ii}(end-12:end-11)); name{ii}=(filename{ii}(1:end-14)); end
index_tau=length(tau); index_tau(1)=1; ii=2;
for k=2:length(tau)
86 Código empleado
if any(tau(1:k-1)==tau(k)); [u,pos]=find(tau(1:k-1)==tau(k)); index_tau(k)=index_tau(pos(1)); else index_tau(k)=ii; ii=ii+1; end end
index_bubble=length(bubble); index_bubble(1)=1; ii=2;
for k=2:length(bubble) if any(bubble(1:k-1)==bubble(k)); [u,pos]=find(bubble(1:k-1)==bubble(k)); index_bubble(k)=index_bubble(pos(1)); else index_bubble(k)=ii; ii=ii+1; end end
index_name=size(name,2); index_name(1)=1;
for k=2:size(name,2) if length(name{k})==length(name{k-1}) if name{k}==name{k-1}; index_name(k)=index_name(k-1); else index_name(k)=index_name(k-1)+1; end else index_name(k)=index_name(k-1)+1; end end
filename_legend=cell(N2,N1);
if index_bubble(1:end)==1 for ii=1:size(filename,2) filename_legend{index_tau(ii),index_name(ii)}=filename{ii}(1:end-
4); end else for ii=1:size(filename,2)
filename_legend{index_tau(ii),index_bubble(ii)}=filename{ii}(1:end-4); end end
C={'b','r','g','k','y','m','c','b','r','g','k','y','m','c','b','r','g','k','y
','m','c','b','r','g','k','y','m','c'}; % Cell array of colors.
for ii=1:size(filename,2)
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 87
dat=load(filename{ii});
columna1=dat(:,1); columna2=dat(:,2); columna3=dat(:,3);
%Elimina interferencias indice=columna2==columna3; index=find(indice); if length(index)>2 columna1=columna1(1:index(1)); columna2=columna2(1:index(1)); columna3=columna3(1:index(1)); end columna1=columna1-columna1(end);
x_max=max(abs(columna1));
if ii==1 x_max_2=x_max; elseif x_max_2<x_max x_max_2=x_max; end
%Elimina valores sobredimensionados (para aquellos superiores un 50%
de la media) media2=mean(columna2); media3=mean(columna3);
for jj=1:length(columna2) if columna2(jj)>1.5*media2 columna2(jj)=media2; end end
for jj=1:length(columna3) if columna3(jj)>1.5*media3 columna3(jj)=media3; end end
media2=mean(columna2); media3=mean(columna3);
media=(media2+media3)/2;
columna2=columna2-media; columna3=columna3-media;
y_max=max(columna2-columna3);
if ii==1 y_max_2=y_max; elseif y_max_2<y_max y_max_2=y_max; end
pax11=subplot(N2,1,index_tau(ii),'Parent', panhandle); handles.panhandle=panhandle; handles.pax11=pax11; guidata(hObject, handles);
88 Código empleado
if index_bubble(1:end)==1 plot([columna1;columna1(end:-1:1)],[columna2;columna3(end:-
1:1)],'linewidth',2,'color',C{index_name(ii)}) else plot([columna1;columna1(end:-1:1)],[columna2;columna3(end:-
1:1)],'linewidth',2,'color',C{index_bubble(ii)}) end
hold on grid on axis equal axis([-1.05*x_max_2 0 -1.5*y_max_2 1.5*y_max_2])
lgd=legend(filename_legend{index_tau(ii),:},'Location','NorthEastOutside'); set(lgd,'FontSize',12); end end hold off
% --- Executes on button press in SaveFigure2. function SaveFigure2_Callback(hObject, eventdata, handles) % hObject handle to SaveFigure2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
global N1 N2 filename_legend filename index_tau index_bubble index_name sdir
if N1==1 && N2==1
dat=load(filename);
columna1=dat(:,1); columna2=dat(:,2); columna3=dat(:,3);
%Elimina interferencias indice=columna2==columna3; index=find(indice); if length(index)>2 columna1=columna1(1:index(1)); columna2=columna2(1:index(1)); columna3=columna3(1:index(1)); end columna1=columna1-columna1(end);
x_max=max(abs(columna1));
%Elimina valores sobredimensionados (para aquellos superiores un 50% de
la media) media2=mean(columna2); media3=mean(columna3);
for jj=1:length(columna2) if columna2(jj)>1.5*media2 columna2(jj)=media2; end
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 89
end
for jj=1:length(columna3) if columna3(jj)>1.5*media3 columna3(jj)=media3; end end
media2=mean(columna2); media3=mean(columna3);
media=(media2+media3)/2;
columna2=columna2-media; columna3=columna3-media; y_max=max(columna2-columna3);
figure(1) plot([columna1;columna1(end:-1:1)],[columna2;columna3(end:-
1:1)],'linewidth',2) grid on axis equal axis([-1.05*x_max 0 -1.5*y_max 1.5*y_max]) filename_legend=filename(1:end-4); lgd=legend(filename_legend,'Location','NorthEastOutside'); set(lgd,'FontSize',12);
else
C={'b','r','g','k','y','m','c','b','r','g','k','y','m','c','b','r','g','k','y
','m','c','b','r','g','k','y','m','c'}; % Cell array of colors.
for ii=1:size(filename,2)
dat=load(filename{ii});
columna1=dat(:,1); columna2=dat(:,2); columna3=dat(:,3);
%Elimina interferencias indice=columna2==columna3; index=find(indice); if length(index)>1 columna1=columna1(1:index(1)); columna2=columna2(1:index(1)); columna3=columna3(1:index(1)); end columna1=columna1-columna1(end);
x_max=max(abs(columna1));
if ii==1 x_max_2=x_max; elseif x_max_2<x_max x_max_2=x_max; end
%Elimina valores sobredimensionados (para aquellos superiores un 50%
de la media)
90 Código empleado
media2=mean(columna2); media3=mean(columna3);
for jj=1:length(columna2) if columna2(jj)>1.5*media2 columna2(jj)=media2; end end
for jj=1:length(columna3) if columna3(jj)>1.5*media3 columna3(jj)=media3; end end
media2=mean(columna2); media3=mean(columna3);
media=(media2+media3)/2;
columna2=columna2-media; columna3=columna3-media; y_max=max(columna2-columna3);
if ii==1 y_max_2=y_max; elseif y_max_2<y_max y_max_2=y_max; end
figure(1); subplot(N2,1,index_tau(ii)) if index_bubble(1:end)==1 plot([columna1;columna1(end:-1:1)],[columna2;columna3(end:-
1:1)],'linewidth',2,'color',C{index_name(ii)}) else plot([columna1;columna1(end:-1:1)],[columna2;columna3(end:-
1:1)],'linewidth',2,'color',C{index_bubble(ii)}) end hold on grid on axis equal axis([-1.05*x_max_2 0 -1.5*y_max_2 1.5*y_max_2])
lgd=legend(filename_legend{index_tau(ii),:},'Location','NorthEastOutside'); set(lgd,'FontSize',12); end end hold off
%Nombre del archivo de salida .fig figname=filename{1};
for ii=1:size(filename,2)-1 if size(filename{ii},2)<size(filename{ii+1},2) figname=filename{ii+1};
if filename{ii}(2:3)==filename{ii+1}(2:3)
Desarrollo de un código para el procesado de vídeos en electro-flow-focusing 91
else figname(2:3)='X'; end if figname(end-21:end-18)==filename{ii}(end-21:end-18) else figname(end-21:end-18)='X'; end elseif filename{ii}(2)==filename{ii+1}(2) else figname(2)='X'; end end
p=size(figname,2)-17;
for ii=1:size(filename,2)
v=figname(end-17:end)==filename{ii}(end-17:end); kk=1; for jj=p:size(figname,2) if v(kk)==1 else figname(jj)='X'; end kk=kk+1; end
end
figname(end-2:end)='fig';
hgsave(figure(1),figname) close(figure(1)) SOURCE=figname; DESTINATION=strcat(sdir,figname); copyfile(SOURCE,DESTINATION);
93
REFERENCIAS
[1] Castro-Hernandez, E. (2011). Tesis doctoral: Análisis de los mecanismos de generación y rotura de
burbujas y gotas en corrientes gas-líquido y líquido-líquido. Escuela Técnica Superior de Ingeniería.
Universidad de Sevilla.
[2] Carrión Ronda, F. (2016). Trabajo fin de grado: Desarrollo de un código para el procesado de vídeos
en microfluídica. Escuela Técnica Superior de Ingeniería. Universidad de Sevilla.
[3] Barrero Ripoll, A. & Pérez-Saborid Sánchez-Pastor, M. (2005). Fundamentos y aplicaciones de la
mecánica de fluidos. Mc Graw Hill .
[4] Alzaga Gimeno, J. (2015). Proyecto fin de carrera: Estudio de la influencia de distintos parámetros en
un chorro bajo la acción de un campo eléctrico alterno. Escuela Técnica Superior de Ingeniería.
Universidad de Sevilla.
[5] P. Fernández Pisón, “Rotura de chorros para enriquecimiento de agentes de contraste,” Master’s thesis,
Escuela Técnica Superior de Ingeniería de Sevilla & University of Twente, 2015.
[6] Silas Jurado, A. (2016). Trabajo fin de grado: Estudio de chorros viscosos bajo la acción de un campo
eléctrico alterno en canales de sección cuadrada. Escuela Técnica Superior de Ingeniería. Universidad de
Sevilla.
[7] C-H, E., G, J., F-N, A. & G, J. M. (2016). Drop generation in controlled fluid flows. fluids, colloids
and soft materials: an introduction to soft matter physics. Wiley Vch .
MANUAL DE USUARIO Analizar 2
1. Escribir “analizar2” en el Command Window de Matlab o pulsar botón “Run” del Editor. 2. Seleccionar el vídeo a estudiar. 3. Si el primer fotograma se encuentra girado usar el botón 2 para colocarlo horizontalmente
con las burbujas circulando de izquierda a derecha. Sentido de giro convencional (valores positivos sentido contrario a agujas del reloj).
4. Seleccionar como región de interés (botón 3) la primera burbuja. Para definir la región de interés, es necesario elegir los vértices superior izquierdo e inferior derecho de un rectángulo, la gota debe encontrarse en el interior. En caso de existir interferencias tomar la segunda.
5. Definir el tamaño de la burbuja (botón 7). Para ello, se procede igual que en el paso anterior pero con una región algo más pequeña y ajustada a la burbuja, en caso de haber sido detectada correctamente, la frontera de ésta se tiñe de rojo. Es muy importante que se detecte.
6. Ejecutar el análisis (botón 8) y esperar hasta que se cierre la ventana de progreso. 7. Si se quieren obtener representaciones de los instantes de rotura ejecutar el botón 15.
Escribir las burbujas a representar teniendo en cuenta que debido al incremento es posible que la burbuja seleccionada como última no se tenga en cuenta. Seleccionar la región de interés del chorro, de igual forma que en el paso 4 pero en este caso abarcando todo el chorro, siendo conveniente tomar la primera burbuja. Seleccionar la línea de referencia a partir de la cual se comenzará a medir el chorro. Para ello son necesarios dos puntos, el superior y el inferior (no importa que no esté en la misma vertical, el programa lo hace de forma automática).
8. Guardar archivos (botón 17). Se guardarán los archivos de texto tanto en la carpeta del programa como en la del vídeo en cuestión.
9. Si se quieren obtener representaciones de varios instantes de tiempo ejecutar botón 16. Escribir la burbuja a representar. Seleccionar la región de interés del chorro y la línea de referencia. Escribir el número de instantes de tiempo que se quieren representar. Seleccionar la región de interés del chorro y la línea de referencia.
10. Guardar archivos (botón 17). Se guardarán los archivos de texto tanto en la carpeta del programa como en la del vídeo en cuestión.
Miplot
Paso previo: Copiar y pegar los archivos de texto a la carpeta del programa (en caso de que no se encuentren en ésta).
1. Escribir “miplot” en el Command Window de Matlab o pulsar botón “Run” del Editor. 2. Ejecutar “Plot figure” para representar los chorros.
Escribir el número de burbujas a representar de un mismo vídeo o, fijada una burbuja el número de vídeos. Escribir el número de instantes de tiempo que se quieren representar. Seleccionar los archivos de texto que se quieren representar. Se debe hacer de una sola vez, se recomienda usar la tecla “ctrl” e ir seleccionando. En caso de haber seleccionado un número diferente de archivos se muestra un mensaje de error.
3. Si la representación es la buscada guardar el archivo (.fig) ejecutando el botón 2. En caso de haber seleccionado los archivos de texto desde la carpeta del programa aparece un error en el Command Window, ignorarlo. Si éstos se toman de la carpeta del vídeo se copiará el archivo de salida (.fig) en ambas carpetas.
4. Si no se está conforme con la representación ejecutar el botón 3 para eliminarla y volver a representar.