viernes, 6 de agosto de 2010

Hiperenfocando por Ordenador

Bueno, lo mismo me estoy poniendo ya pesado con el tema xD... pero ya que he estado jugando con ello, pues lo cuelgo, que para eso la página es mia xD!

Publiqué una primera entrada donde hablábamos de la profundidad de campo y de las curiosas propiedades de la distancia hiperfocal, desde un punto de vista fotográfico. Luego, me picó el gusanillo científico y el físico que llevo dentro (que debería estar estudiando xD, pero no lo hace) se dedicó a intentar dar una explicación al fenómeno desde el punto de vista de la óptica geométrica. Hoy vamos a abordar el problema de una tercera forma, con el enfoque de: "yo no sé nada, pero a mi ordenador no le importa estar todo el día dando palos de ciego" xD!

A esta curiosa filosofía se le llama en ciencia con el rimbombante nombre de "Métodos de MonteCarlo".

Pues bien, el truco es bien sencillo: vamos a hacer que el ordenador trace todos los rayos que se le ocurra con la condición de que pasen por el borde del diafragma, y luego seleccionaremos los que caigan dentro del círculo de confusión (ver entrada anterior sobre esto). El código (para MATLAB) vendría a ser algo como esto:

function [sh,sl]=hiperfocal(f,N,Xo,I)
%
% Este script calcula por métodos de montecarlo la mínima y máxima distancia de enfoque dando:
%
% a) La focal del objetivo en milímetros (ejemplo: 18mm).
% b) El número f (relacionado con la apertura del diafragma). Ejemplo: F5 ó F/5 => debemos poner 5.
% c) El punto de enfoque donde esté nuestro objeto (la distancia a la que apuntemos).
% d) El número de iteraciones del programa (contra mayor sea, más preciso, pero más lento).
%
% Creado por Astaroth (O.R.G.) - http://astarothsworld.blogspot.com
%
% Propiedades de la lente:
C=0.02; % Círculo de confusión (mm).
D=f/N; % Apertura del diafragma.
zoo=Xo-f;
zii=f^2/zoo;
h=D;
disp(' ')
disp ('DATOS:')
disp(' ')
fprintf(['Focal de nuestra lente: ',num2str(f),' mm.\n'])
fprintf(['Apertura (f-number): ',num2str(N),'.\n'])
fprintf(['Posición del objeto: ',num2str(Xo),' mm.\n'])
fprintf(['Posición de la imagen: ',num2str(-zii-f),' mm.\n'])
fprintf(['Número de iteraciones: ',num2str(I),'.\n'])
% Rayo bueno:
close all
xo=linspace(0,zoo+f);
yo=-h/(zoo+f)*xo+h;
plot(xo,yo,'b')
hold on
plot(xo,-yo,'b')
xi=linspace(-zii-f,0);
yi=h/(zii+f)*xi+h;
plot(xi,yi,'b')
plot(xi,-yi,'b')
% Esqueleto:
Z=2*max(zii+f,zoo+f);
plot(linspace(-Z,Z,1000),0)
plot(0,linspace(-D, D,1000))
plot(-zii-f,linspace(-C,C))
plot(-f,linspace(-D/2,D/2),'r')
plot(f,linspace(-D/2,D/2),'r')
grid on
zh=zoo;
zl=zoo;
% Rayos de prueba:
for (i=1:I)
    % Condición: if(rand > 0.5)
      zo=rand/(1e-5^rand)-f;
    else
      zo=rand/(1e-3^rand)-f;
    end zi=f^2/zo; h=D; if ( abs(h/(zi+f)*(-zii-f)+h) < C )
      xo=linspace(0,zo+f);
      yo=-h/(zo+f)*xo+h;
      plot(xo,yo,'--g')
      plot(xo,-yo,'--g')
      xi=linspace(-zii-2*f,0);
      yi=h/(zi+f)*xi+h;
      plot(xi,yi,'--g')
      plot(xi,-yi,'--g')
      zh=min(zh,zo);
      zl=max(zl,zo);
    end
end
text(zoo+f,-D/10,'Objeto','HorizontalAlignment','center')
text(-zii-f,D/10,'Imagen','HorizontalAlignment','center')
text(f,-(1+1/10)*D/2,'Foco Objeto','HorizontalAlignment','center')
text(-f,(1+1/10)*D/2,'Foco Imagen','HorizontalAlignment','center')
disp(' ')
disp(' ')
disp ('RESULTADOS:')
disp(' ')
sh=zh+f; sl=zl+f;
fprintf(['Punto de enfoque más cercano: ',num2str(sh),' mm.\n'])
fprintf(['Punto de enfoque más lejano: ',num2str(sl),' mm.\n'])
(Podéis descargároslo de aquí. Es mucho más recomendable* que copiar el código de arriba)
 
Como resultado, el programa nos da la distancia mínima y máxima de enfoque:

Ejecución del comando "Hiperfocal" en MATLAB y resultados obtenidos

Podemos comparar estas distancias con los resultados de la web DOF master para una focal de 18mm, una apertura de f/16 y enfocando a una distancia de 30cm.

La distancia mínima a la que podemos enfocar en la web es de 23'5 cm, que es la misma que obtenemos nosotros al redondear a esa cifra decimal. La distancia máxima en la web es de 41'6 cm frente  los 41'5 cm que obtenemos nosotros (en este caso, y usando 10000 iteraciones).

Como vemos, los resultados concuerdan bastante bien. Además de los numeritos, ya sabéis por la entrada anterior cuánto me gustan los dibujitos xD, así que el programa (no podía ser de otra manera) también hace dibujitos para ver qué es lo que pasa en realidad:


Lo que estamos viendo es el trazado de rayos: al rededor del rayo que parte del objeto (el realmente exacto) tenemos una nube de rayos que podemos incluir aceptando que existe un círculo de confusión en el que no distinguimos el desenfoque. La zona en verde que hay rodeando al objeto (en el eje óptico) es la zona que saldría enfocada en nuestra foto. Ahora ya no es un punto, sino una región: ese es el campo enfocado, y la profundidad de campo es su tamaño.

Nota: para sacar la distancia hiperfocal, dado que ésta se define como la mínima distancia de enfoque cuando enfocamos al infinito, debemos poner nuestro objeto "en el infinito", por ejemplo, si hacemos la foto con un 55m, con una apertura del diafragma F5, podemos poner:
Hiperfocal(55,5,1e99,10000)
Y el punto más cercano de enfoque será bastante similar a la hiperfocal.


Situaciones y Dibujos

Vamos a ver las gráficas correspondientes a distintas situaciones y su relación con el tipo de fotografía que queramos realizar. Pinchando sobre ellas se pueden ver a tamaño completo.

Qué ocurre si disparamos con un gran angular (18mm), pero con el diafragma muy extremadamente (F1) a una distancia de 100mm?

Conseguimos muy poca profundidad de campo. Podríamos utilizarlo para hacer una foto a una flor, en la que el primer plano (situado a 10cm de la cámara) saldría enfocado mientras el fondo estaría completamente difuminado.

Pero es aún peor si disparamos con un teleobjetivo (300mm), aún con el diafragma relativamente cerrado (F16), a una distancia de medio metro.

En este caso se puede decir que sólo se enfoca un plano, puesto que el campo enfocado es del orden media décima de milímetro. Quizá podríamos utilizarlo para hacer un retrato a una persona, situada a medio metro de la cámara, quedando enmarcada por un fondo completamente difuminado. Otro problema distinto es el campo visual: puede que con un 300mm, al enfocar a una persona que esté a medio metro, sólo abarquemos un ojo suyo en vez de toda la cara :p! Quizá podríamos enfocar la punta de la nariz desenfocando el resto de la cara :)! (basta con que la nariz de nuestra modelo tenga más de media décima de milímetro y creo que hay muchos modelos con "esas medidas" :p!).

Una situación intermedia es la que vemos con un teleobjetivo de 150mm, con el diafragma bastante cerrado (F32) cuando disparamos a unos 10m (algo así como un tercio de su distancia hiperfocal).

Aquí vemos ya una profundidad de campo aceptable, entre los 8 y 14 metros más o menos. Podemos fotografiar cualquier escena que transcurra a estas distancias y saldrá todo bien enfocado, difuminando los primeros planos (todo aquello que esté, por ejemplo, a menos de 5m) y el fondo (si está a más de, por ejemplo, 20m).

Y ya, para terminar, qué es lo que ocurre cuando disparamos a la distancia hiperfocal o muy próximos a ella? Por qué tanto royo con esta distancia "mágica"?

No es difícil ver a simple vista que estamos cerca de un punto "especial" en la física de este sistema. La profundidad de campo ha crecido enormemente. Aquí es donde el algoritmo es más sensible (el resultado que debería dar debería tender a "infinito", pero no es fácil llegar hasta el infinito probando aleatoriamente con un ordenador, así que lo que conseguimos son números "muy grandes"). Contra más iteraciones permitamos, más posibilidades de que se "dispare" alguna de ellas y llegue más lejos, acercándonos cada vez más a ese "infinito" (que en este dibujo se queda en casi los 100m).

La diferencia con los casos anteriores es abismal. Esta es la explicación gráfica de por qué aumenta tanto el campo enfocado a la distancia hiperfocal: pura geometría.


Actualización*

Aprovecho para decir que "Hiperfocal.m" se ha ido actualizando cada cierto tiempo, como pasa con casi todos mis scripts (sobre todo los primeros días, puesto que es cuando más interesado estoy en perfeccionarlos). Por eso siempre aconsejo bajárselos de 4Shared en lugar de copiar el código directamente de esta página, puesto que:
  1. Es sólo la idea inicial, luego se va refinando y ese código no se actualiza.
  2. El código, al copiarlo en una página HTML, a veces da problemas (se auto(mal)interpreta y puede dar lugar a código erróneo).
  3. Es más cómodo tenerlo todo ya en un archivo.
Os informo de que, en este caso concreto, se han añadido mejoras tanto gráficas (de las cuales ya había imágenes colgadas en la sección "Situaciones y Dibujos", aunque se ha retocado alguna tontería más desde entonces):


Como en el programa en sí, que ahora calcula explícitamente la profundidad de campo y te guía para intentar garantizar buenos resultados (catalogando un experimento como "poco fiable" cuando se cuenta con menos de un rayo por milímetro en la zona enfocada y aconsejándote el valor aproximado de "rayos prueba" que daría un resultado más aceptable).


En general, para todos mis scripts, recordad que las versiones más recientes se encuentran en 4Shared.

1 comentario:

  1. ok no entendí pero da igual mi inteligencia esta dormida a estas horas xDDD solo pasaba a decir FELIZ CUMPLEAÑOS FELIZ CUMPLEAÑOS FELIZ CUMPLEAÑOS FELIZ CUMPLEAÑOS FELIZ CUMPLEAÑOS!!!!!!!!

    como tu vives en la tierra y yo en martes xDD me gusta dejar mensajitos por todos lados donde estemos conectados =P y pos como olvidar el Blog acá te deje mi primer comentario, creo xD

    espero te alegre saber que te comprare un pastel y me lo comeré por ti jjejejeje

    Besitoooooss!!!

    ResponderEliminar

Querido astarothista!,

Si te ha gustado la entrada y quieres dejar constancia de ello, tienes alguna sugerencia para completarla o corregirla, quieres mostrar tu opinión respecto a algo de lo que se haya hablado en esta entrada (con respeto) o simplemente quieres dejarme un mensaje a mi o a la comunidad, no dudes en comentar ;)!

Recuerda que también estamos en Facebook y en Google+.