![]() |
Ampliar imagen o parte de ella - Interpolacion Lineal
Buenas foristas,
Lo que pretendo es muy simple. Aplicar una función que permita ampliar una zona determinada de la imagen (o incluso, entera). Se que hay dos métodos: 1. Por repetitción: que consiste en repetir cada pixel K veces en k-1 columnas y filas siguientes. Es sencillo, pero para niveles de K grandes, se produce un efecto cuadriculado. 2. Por interpolación lineal. El proceso se detalla para una K = 2. Primeramente se arma la imagen de tamaño (kM x kN). Segundo, cada pixel de la zona se ingresa en la imagen ampliada dejando un pixel en el medio (valor cero). Por ejemplo: x 0 x 0 0 0 x 0 x 0 x 0 Donde x es el valor del pixel (ojo... a nivel de gris). Posteriormente se hace un especie de "filtrado" convolucionando la zona a ampliar con una plantilla (o matriz). Para una k = 2 (es decir ampliar en 200%) se tiene la matrix: ((1/4,1/2,1/4),(1/2,1,1/2),(1/4,1/2,1/4). Una vez realizado esto, se repite la ultima fila y columna. Según la bibliografía que consulto: Cita:
Mi pregunta por tanto es... ¿Alguien conoce como realizar el algoritmo para una k cualquiera? Seoane, lo mas seguro es que si te das una vuelta por aqui... te pongas a escribir codigo:D Y es muy probable de que te sepas esto;) Desde ya, muchas gracias a todos por robarles su tiempo para leer este post. Saludos, |
He logrado avanzar un poco...
1 Archivos Adjunto(s)
Buenas, de lo que pude averiguar buscando en la gran red de redes, he podido encontrar la forma genérica de calcular el valor correspondiente a cada pixel de acuerdo a la dimensión.
Entiendo el algoritmo, y es como detallo a continuación: 1) Armar una imagen temporal de tamaño (kM x kN), siendo k el factor de ampliación. 2) Por cada pixel de la imagen original se debe colocar intercalando (k-1) ceros entre ellos hasta alcanzar el tamaño (kM x kN): Por ejemplo: 5-11 8-25 se transforma a (con k = 3) 5-0-0-11-0-0 0-0-0- 0-0-0 0-0-0- 0-0-0 8-0-0-25-0-0 0-0-0- 0-0-0 0-0-0- 0-0-0 Hasta allí barbaro, logro hacer dicho procedimiento... La cosa se complica al calcular los valores intermedios entre ellos, es decir los ceros. Si A y B son dos puntos originales de la imagen, cualquier k-1 puntos entre ellos (no diagonal) se determina: x = (i*A + j*B)/k ,i = k-1,..,1 j = 1..k-1 ,k >= 3 x = (A + B)/2 ,k >= 2 Mientras i va decrementado, j aumenta lo cual permite asignar valores intermedios entre A y B de modo tal que se produzca una transición suave entre ellos. Para rellenar estos valores, primero se calculan en las filas: 5-7-9-11-0-0 0-0-0-0-0-0 0-0-0-0-0-0 8-14-19-25-0-0 0-0-0-0-0-0 0-0-0-0-0-0 Luego se aplica sobre las columnas: 5-7-9-11-0-0 6-9-12-16-0-0 7-12-16-20-0-0 8-14-19-25-0-0 0-0-0-0-0-0 0-0-0-0-0-0 Los ceros restantes, toman el valor de la ultima columna, y fila: 5-7-9-11-11-11 6-9-12-16-16-16 7-12-16-20-20-20 8-14-19-25-25-25 8-14-19-25-25-25 8-14-19-25-25-25 Y alli termina el algoritmo. ¿Sencillo no? Pues, en palabras... pues me he quedado encerrado tratando de ver como lo puedo llevar a cabo. Mi algoritmo solo me ha llegado hasta intercalar los ceros. Lo siguiente no tengo idea de como hacerlo. Adjunto lo que logrado hacer. Si alguien puede darme un consejo de como proseguir se lo agradecería. Yo hasta el momento estaba empleando scanline(), para moverme entre los pixeles. Es rápido... pero estaba pensando que con pixels[] sería más sencillo... pero muy lento. No se.. escucho alternativas. saludos, |
Una forma podría ser utilizar matrices. De hecho, es lo que usan los programas como potochop, The Gimp y similares. Intentaré explicarlo, a ver qué tal me sale.
Primero amplias la imagen por el método uno. Cita:
Después recorres la imagen ampliada (cuyo tamaño es, por ejemplo <w, h>) y, sumas los pesos de los puntos que rodean el pixel según indica la matriz. El pixel resultante es dicha suma dividido por el total de los pesos:
No he comprobado el código y lo he hecho de memoria, así que revísalo, en especial la parte de cálculo de coordenadas. De todas formas creo que se entiende lo que quiero hacer, ¿no? En resumidas cuentas se busca la media ponderada del color de los píxeles que rodean a uno dado. En cuanto a la velocidad, eso se lo dejo a otro, que mi neurona no da ya para más. :D |
Hola Ñuño, estoy leyendo tu método, y si no leí mal se trata de agrandar y luego suavizar la imagen. Este método de aplicar una matriz para suavizar la imagen ya lo discutimos aquí, usando Scanline y todo :p .Pero me queda la duda si quedara bien, si primero añades un montón de ceros y luego aplicas la matriz, lo unico que conseguirás es oscurecer la imagen :confused:
|
Cita:
Cita:
5-11 8-25 se transforma a (con k = 3) 5-5-5-11-11-11 5-5-5-11-11-11 5-5-5-11-11-11 8-8-8-25-25-25 8-8-8-25-25-25 8-8-8-25-25-25 Por otro lado, obtengo el valor del pixel de ImagenAmpliada pero el resultado lo guardo en ImagenFinal. Esto es importante para evitar pisar los datos. De todas formas, si llego a a saber que ya se habló de aplicar filtros a una imagen mediante matrices, me ahorro todo ese código y la mayor parte de las explicaciones :rolleyes: . [edit] error en el código que puse: Olvidé poner un "PesoTotal := 0" antes del bucle interno. Ahora ya está bien. |
Cita:
Una opción seria agrandar la imagen como siempre, usando la API de windows, que su métodos tendrá, y luego aplicar el suavizado. Aunque no se si el objetivo de Delphius es puramente teórico, es decir, quiere saber como agrandar, o practico, es decir, necesita agrandar una imagen dentro de su programa. Si es el primer caso no le quedara mas remedio que romperse la cabeza hasta encontrar el super algoritmo :p , si es lo segundo usar la API puede servir, o GDI+, o cualquier otra librería gráfica. Cita:
|
gracias por ayudar
Cita:
Lamentablemente si necesito agrandar una imagen y tiene que ser código mio. Podría usar la API, la verdad es que no me fijé si había alguna... yo me estoy basando en un libro y de alli estoy sacando los elementos que voy necesitando, pues ya he presentado mis fuentes bibliográficas ante mis tutores (no puedo cambiarlas ahora). Por lo que no puedo hacer uso de librerias gráficas, el objetivo es que yo las implemente. Asi lo impuse yo para mi trabajo. Ahora me doy cuenta de que esto no era la papa (fàcil)... Y si... como dices: me tendré que romper el coco tratando de sacarle el algoritmo. Nuño: gracias por tu aporte. Ese algoritmo es relativamente sencillo. Es repetir... a ese lo tengo. Es por el otro método (interpolación lineal) el que me estoy dando golpes en la cabeza con el martillo que tengo al lado:D Como habrás notado el método por repetición es casi elemental pero sufre de una gran problema, cuanto más elevado sea el factor k, la imagen queda totalmente dibujada en bloques. El segundo método trata de evitar este efecto, pero claro... a niveles altos también falla: la imagen queda borrosa. Cita:
Gracias seoane, no es mi intención de que me hagas la tarea... en otro hilo tu ayuda vino bárbara. Yo prefiero una directrices, tips... Pero debo admitir de que si tu no hubieras puesto ese código, tal vez yo no hubiera avanzado mucho. * como dicen en Argentina: ¡me volví mono! Seguiré dandome golpes... a ver si no quedo loco antes:p. Gracias a ambos |
No puedo, no me sale... no se como...
Buenas de nuevo. Disculpen por abrir de nuevo este hilo, pero la verdad es que este algoritmo me ha dejado sin cerebro... por más que lo piense... y lo piense... no logro encontrarle manera de codificarlo. Lo entiendo al algoritmo, pero en la práctica mi cerebro queda frito.
Lo he pensado incluso en papel para guiarme, en forma manual lo saco... Pero al momento de "traducirlo" empleando tanto Pixels[] como Scanline() no puedo, sinceramente, se me borra todo de mi mente... Este algoritmo me ha dejado mal parado... he podido continuar con otras partes de mi proyecto, pero lamentablemente he llegado a un punto en donde no puedo avanzar si no logro implementar al (disculpen mis palabras) maldito algoritmo de zoom por interpolación lineal. Si alguno puede darme alguna orientación le estaría muy agradecido. Muchas gracias, |
Bueno, una primera aproximacion seria la siguiente:
Puede que tenga fallos, es solo una primera aproximación, además tiene que haber una solución mejor donde el Zoon no tenga que ser un numero entero. Todo se andará ... :p |
Muchísimas gracias por tu infinita ayuda
seoane, muchísimas gracias por brindar nuevamente tus conocimientos en la materia. A simple vista no lo entiendo mucho... pero como tu dices:
Cita:
Primeramente deberé refrescar mi cerebro. Nunca me ha pasado algo así: generalmente logro "sacar" algoritmos en cuestión de no más de 3 días... pero quedarme en blanco... es de no creer! Se nota que lo he forzado mucho. Bueno, unas horas de siesta y retorno el trabajo. Nuevamente muchas gracias, como he dicho antes: hay lugar en mi lista de agradecimientos y cumplidos para todos aquellos que han aportado altruistamente sus conocimientos y ayuda. ¡Muchas gracias! Saludos, |
¿QUerés hacer algo como esto? O quizás te orienta ya que tiene el source
http://img255.imageshack.us/img255/5277/dibujowf4.jpg Hay un componente que te lo permite: TMagnify 2.0 ( FULL SOURCE free ) Saludos |
Zeta, de lo que se trata es de implementar un algoritmo de interpolación. El componente que tu indicas se limita a usar las funciones de dibujo de la API para agrandar el dibujo, y te puedo asegurar que la api, en este caso, no utiliza ningún tipo de interpolación :) . Además como ya explico Delphius necesita implementar su propio algoritmo, no le sirve con utilizar funciones de la API o librerías de terceros.
|
La franja horaria es GMT +2. Ahora son las 06:34:20. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi