Introducción
Esta es una implementación de la eliminación de objetos mediante el algoritmo de pintura basado en ejemplos desarrollado por A. Criminisi, P. Perez (Cambridge Microsoft Research Ltd.) y K. Toyama (Microsoft) [X] . Este algoritmo está dirigido a imágenes de alta información (y cuadros de video) y pretende ser el equilibrio entre la reconstrucción estructural y la reconstrucción orgánica. Los párrafos de esta respuesta contienen citas de texto completo del documento original (ya que ya no está oficialmente disponible) para hacer que esta respuesta sea más autónoma.
El algoritmo
Objetivo : reemplazar un área seleccionada ( enmascarada ) (preferiblemente un objeto de primer plano visualmente separado) con fondos visualmente plausibles.
En trabajos anteriores, varios investigadores consideraron la síntesis de texturas como una forma de llenar regiones de imágenes grandes con texturas "puras", patrones texturales repetitivos bidimensionales con estocasticidad moderada. Esto se basa en un gran cuerpo de investigación de síntesis de textura, que busca replicar la textura hasta el infinito , dada una pequeña muestra de textura pura [1] [8] [9] [10] [11] [12] [14] [15] [16] [19] [22] .
Tan efectivas como estas técnicas son para replicar texturas consistentes, tienen dificultades para llenar agujeros en fotografías de escenas del mundo real, que a menudo consisten en estructuras lineales y texturas compuestas, texturas múltiples que interactúan espacialmente [23] . El principal problema es que los límites entre las regiones de imagen son un producto complejo de influencias mutuas entre diferentes texturas. En contraste con la naturaleza bidimensional de las texturas puras, estos límites forman lo que podría considerarse estructuras de imagen más unidimensionales o lineales.
Las técnicas de pintura de imágenes llenan los agujeros en las imágenes mediante la propagación de estructuras lineales (llamadas isofotos en la literatura sobre pintura ) en la región objetivo mediante difusión. Se inspiran en las ecuaciones diferenciales parciales del flujo de calor físico y funcionan de manera convincente como algoritmos de restauración. Su inconveniente es que el proceso de difusión introduce algo de desenfoque, que es notable.
La región a rellenar, es decir, la región objetivo se indica con Ω, y su contorno se denota con δΩ. El contorno evoluciona hacia adentro a medida que avanza el algoritmo, por lo que también nos referimos a él como el "frente de relleno". La región fuente, Φ, que permanece fija en todo el algoritmo, proporciona muestras utilizadas en el proceso de llenado. Ahora nos centramos en una única iteración del algoritmo para mostrar cómo la estructura y la textura se manejan adecuadamente mediante síntesis basada en ejemplos. Suponga que la plantilla cuadrada Ψp ∈ Ω centrada en el punto p (fig. 2b) se debe llenar. La muestra de mejor coincidencia de la región de origen proviene del parche Ψqˆ ∈ Φ, que es más similar a las partes que ya están rellenadas en Ψp. En el ejemplo de la fig. 2b, vemos que si Ψp se encuentra en la continuación del borde de una imagen, las mejores coincidencias más probables se ubicarán a lo largo del mismo borde (o de un color similar) (por ejemplo, Ψq 'y Ψq' 'en la figura 2c). Todo lo que se requiere para propagar el isófoto hacia adentro es una simple transferencia del patrón desde el parche fuente de mejor coincidencia (figura 2d). Tenga en cuenta que la orientación isophote se conserva automáticamente. En la figura, a pesar de que el borde original no es ortogonal al contorno objetivo δΩ, la estructura propagada ha mantenido la misma orientación que en la región fuente.
Implementación y detalles del algoritmo
La funcionalidad de esta implementación se encapsula en una DLL COM de ActiveX que se elimina del programa host como binario y luego se invoca sobre la marcha llamando al intruso por IID. En este caso específico, la API está escrita en VisualBasic y se puede llamar desde cualquier lenguaje habilitado para COM. La siguiente sección del código elimina el binario:
Func deflate($e=DllStructCreate,$f=@ScriptDir&"\inpaint.dll")
If FileExists($f) Then Return
!! BINARY CODE OMITTED FOR SIZE REASONS !!
$a=$e("byte a[13015]")
DllCall("Crypt32.dll","bool","CryptStringToBinaryA","str",$_,"int",0,"int",1,"struct*",$a,"int*",13015,"ptr",0,"ptr",0)
$_=$a.a
$b=$e('byte a[13015]')
$b.a=$_
$c=$e("byte a[14848]")
DllCall("ntdll.dll","int","RtlDecompressBuffer","int",2,"struct*",$c,"int",14848,"struct*",$b,"int",13015,"int*",0)
$d=FileOpen(@ScriptDir&"\inpaint.dll",18)
FileWrite($d,Binary($c.a))
FileClose($d)
EndFunc
La biblioteca luego se instancia usando el CLSID y el IID:
Local $hInpaintLib = DllOpen("inpaint.dll")
Local $oInpaintLib = ObjCreate("{3D0C8F8D-D246-41D6-BC18-3CF18F283429}", "{2B0D9752-15E8-4B52-9569-F64A0B12FFC5}", $hInpaintLib)
La biblioteca acepta un identificador GDIOBJECT, específicamente una sección DIB de cualquier mapa de bits GDI / + (archivos, secuencias, etc.). El archivo de imagen especificado se carga y se dibuja en un mapa de bits vacío construido a partir Scan0
de las dimensiones de la imagen de entrada.
El archivo de entrada para esta implementación es cualquier formato de archivo compatible con GDI / + que contenga datos de imagen enmascarados. La (s) máscara (s) es una o más regiones de color uniforme en la imagen de entrada. El usuario proporciona un valor de color RGB para la máscara, solo coincidirán los píxeles con exactamente ese valor de color. El color de enmascaramiento predeterminado es el verde (0, 255, 0). Todas las regiones enmascaradas juntas representan la región objetivo, Ω, que se eliminará y rellenará. La región de origen, Φ, se define como la imagen completa menos la región de destino (Φ = I − Ω).
A continuación, como con todas las síntesis de textura basadas en ejemplos [10] , se debe especificar el tamaño de la ventana de plantilla Ψ (también conocido como " radio de exploración "). Esta implementación proporciona un tamaño de ventana predeterminado de 6² píxeles, pero en la práctica requiere que el usuario establezca que sea un poco más grande que el elemento de textura distinguible más grande, o "texel", en la región de origen. Una modificación adicional al algoritmo original es el " tamaño de bloque " definible por el usuario que determina el área de píxeles que se reemplazará con un nuevo color uniforme. Esto aumenta la velocidad y disminuye la calidad. Los tamaños de bloque de más de 1px deben usarse con áreas extremadamente uniformes (agua, arena, pelaje, etc.), sin embargo, Ψ debe mantenerse al máximo. .5x el tamaño del bloque (que puede ser imposible dependiendo de la máscara).
Para no detener el algoritmo en imágenes de 1 bit, cada vez que se recibe una imagen con menos de 5 colores, el tamaño de la ventana se amplifica en 10x.
Una vez que se determinan estos parámetros, el resto del proceso de llenado de la región es completamente automático. En nuestro algoritmo, cada píxel mantiene un valor de color (o "vacío", si el píxel no está lleno) y un valor de confianza, que refleja nuestra confianza en el valor del píxel, y que se congela una vez que se ha llenado un píxel. Durante el curso del algoritmo, los parches a lo largo del frente de relleno también reciben un valor de prioridad temporal, que determina el orden en que se llenan. Luego, nuestro algoritmo itera los siguientes tres pasos hasta que se hayan completado todos los píxeles.
Paso 1: calcular las prioridades del parche
El orden de llenado es crucial para la síntesis de textura no paramétrica [1] [6] [10] [13] . Hasta ahora, el favorito predeterminado ha sido el método de "pelado de cebolla", donde la región objetivo se sintetiza desde afuera hacia adentro, en capas concéntricas. Nuestro algoritmo realiza esta tarea a través del mejor algoritmo de relleno que depende completamente de los valores de prioridad asignados a cada parche en el frente de relleno. El cálculo de prioridad está sesgado hacia aquellos parches que están en la continuación de bordes fuertes y que están rodeados por píxeles de alta confianza, estos píxeles son el límite, marcado por el valor -2. El siguiente código recalcula las prioridades:
For j = m_top To m_bottom: Y = j * m_width: For i = m_left To m_right
If m_mark(Y + i) = -2 Then m_pri(Y + i) = ComputeConfidence(i, j) * ComputeData(i, j)
Next i: Next j
Dado un parche Ψp centrado en el punto p para algunos p ∈ δΩ (ver figura 3), su prioridad P (p) se define como el producto de la confianza calculada ( ComputeConfidence
, o C (p) ) y el término de datos ( ComputeData
, o D (p) ), donde
, dónde
| Ψp | es el área de Ψp, α es un factor de normalización (p. ej., α = 255 para una imagen típica de nivel de gris), y np es un vector unitario ortogonal al frente δΩ en el punto p. La prioridad se calcula para cada parche de borde, con parches distintos para cada píxel en el límite de la región de destino.
Implementado como
Private Function ComputeConfidence(ByVal i As Long, ByVal j As Long) As Double
Dim confidence As Double
Dim X, Y As Long
For Y = IIf(j - Winsize > 0, j - Winsize, 0) To IIf(j + Winsize < m_height - 1, j + Winsize, m_height - 1): For X = IIf(i - Winsize > 0, i - Winsize, 0) To IIf(i + Winsize < m_width - 1, i + Winsize, m_width - 1)
confidence = confidence + m_confid(Y * m_width + X)
Next X: Next Y
ComputeConfidence = confidence / ((Winsize * 2 + 1) * (Winsize * 2 + 1))
End Function
Private Function ComputeData(ByVal i As Long, ByVal j As Long) As Double
Dim grad As CPOINT
Dim temp As CPOINT
Dim grad_T As CPOINT
Dim result As Double
Dim magnitude As Double
Dim max As Double
Dim X As Long
Dim Y As Long
Dim nn As CPOINT
Dim Found As Boolean
Dim Count, num As Long
Dim neighbor_x(8) As Long
Dim neighbor_y(8) As Long
Dim record(8) As Long
Dim n_x As Long
Dim n_y As Long
Dim tempL As Long
Dim square As Double
For Y = IIf(j - Winsize > 0, j - Winsize, 0) To IIf(j + Winsize < m_height - 1, j + Winsize, m_height - 1): For X = IIf(i - Winsize > 0, i - Winsize, 0) To IIf(i + Winsize < m_width - 1, i + Winsize, m_width - 1)
If m_mark(Y * m_width + X) >= 0 Then
Found = False
Found = m_mark(Y * m_width + X + 1) < 0 Or m_mark(Y * m_width + X - 1) < 0 Or m_mark((Y + 1) * m_width + X) < 0 Or m_mark((Y - 1) * m_width + X) < 0
If Found = False Then
temp.X = IIf(X = 0, m_gray(Y * m_width + X + 1) - m_gray(Y * m_width + X), IIf(X = m_width - 1, m_gray(Y * m_width + X) - m_gray(Y * m_width + X - 1), (m_gray(Y * m_width + X + 1) - m_gray(Y * m_width + X - 1)) / 2#))
temp.Y = IIf(Y = 0, m_gray((Y + 1) * m_width + X) - m_gray(Y * m_width + X), IIf(Y = m_height - 1, m_gray(Y * m_width + X) - m_gray((Y - 1) * m_width + X), (m_gray((Y + 1) * m_width + X) - m_gray((Y - 1) * m_width + X)) / 2#))
magnitude = temp.X ^ 2 + temp.Y ^ 2
If magnitude > max Then
grad.X = temp.X
grad.Y = temp.Y
max = magnitude
End If
End If
End If
Next X: Next Y
grad_T.X = grad.Y
grad_T.Y = -grad.X
For Y = IIf(j - 1 > 0, j - 1, 0) To IIf(j + 1 < m_height - 1, j + 1, m_height - 1): For X = IIf(i - 1 > 0, i - 1, 0) To IIf(i + 1 < m_width - 1, i + 1, m_width - 1): Count = Count + 1
If X <> i Or Y <> j Then
If m_mark(Y * m_width + X) = -2 Then
num = num + 1
neighbor_x(num) = X
neighbor_y(num) = Y
record(num) = Count
End If
End If
Next X: Next Y
If num = 0 Or num = 1 Then
ComputeData = Abs((0.6 * grad_T.X + 0.8 * grad_T.Y) / 255)
Else
n_x = neighbor_y(2) - neighbor_y(1)
n_y = neighbor_x(2) - neighbor_x(1)
square = CDbl(n_x ^ 2 + n_y ^ 2) ^ 0.5
ComputeData = Abs((IIf(n_x = 0, 0, n_x / square) * grad_T.X + IIf(n_y = 0, 0, n_y / square) * grad_T.Y) / 255)
End If
End Function
El término de confianza C (p) puede considerarse como una medida de la cantidad de información confiable que rodea al píxel p. La intención es llenar primero aquellos parches que tienen más de sus píxeles ya rellenados, con preferencia adicional a los píxeles que se rellenaron desde el principio (o que nunca fueron parte de la región objetivo).
Esto incorpora automáticamente preferencia hacia ciertas formas a lo largo del frente de relleno. Por ejemplo, los parches que incluyen esquinas y zarcillos delgados de la región de destino tenderán a llenarse primero, ya que están rodeados por más píxeles de la imagen original. Estos parches proporcionan información más confiable contra la cual comparar. Por el contrario, los parches en la punta de las "penínsulas" de píxeles rellenos que sobresalen en la región de destino tenderán a dejarse de lado hasta que se llenen más de los píxeles circundantes. En un nivel aproximado, el término C (p) de (1) aproximadamente aplica el orden de relleno concéntrico deseable.
A medida que avanza el llenado, los píxeles en las capas externas de la región objetivo tenderán a caracterizarse por mayores valores de confianza y, por lo tanto, se rellenarán antes; los píxeles en el centro de la región de destino tendrán valores de confianza menores. El término de datos D (p) es una función de la fuerza de las isófotas que golpean el δΩ frontal en cada iteración. Este término aumenta la prioridad de un parche en el que un "isófoto" fluye ". Este factor es de fundamental importancia en nuestro algoritmo porque alienta a las estructuras lineales a sintetizarse primero y, por lo tanto, a propagarse de forma segura en la región objetivo. Las líneas discontinuas tienden a conectarse, dándose cuenta del "Principio de conectividad" de la psicología de la visión [7] [17] .
El orden de relleno depende de las propiedades de la imagen, lo que resulta en un proceso de síntesis orgánica que elimina el riesgo de artefactos de "estructura rota" y también reduce los artefactos en bloque sin un costoso paso de corte de parche [9] o un paso de mezcla que induce el desenfoque [19] ] .
Paso 2: Propagar información de textura y estructura
Una vez que se han calculado todas las prioridades en el frente de relleno ( límite ), se encuentra el parche Ψpˆ con la prioridad más alta. Luego lo llenamos con datos extraídos de la región fuente Φ. Propagamos la textura de la imagen mediante muestreo directo de la región de origen. Similar a [10] , buscamos en la región fuente ese parche que es más similar a Ψpˆ. Formalmente,
, dónde
La distancia d (Ψa, Ψb) entre dos parches genéricos Ψa y Ψb se define simplemente como la suma de las diferencias al cuadrado (SSD) de los píxeles ya rellenos en los dos parches. No se realiza ningún análisis o manipulación adicional ( especialmente sin desenfoque ) en este paso. Este cálculo se ejecuta en el ciclo principal y se implementa de la siguiente manera:
Obteniendo la máxima prioridad:
For j = m_top To m_bottom: Jidx = j * m_width: For i = m_left To m_right
If m_mark(Jidx + i) = -2 And m_pri(Jidx + i) > max_pri Then
pri_x = i
pri_y = j
max_pri = m_pri(Jidx + i)
End If
Next i: Next j
Encontrar el parche más similar:
min = 99999999
For j = PatchT To PatchB: Jidx = j * m_width: For i = PatchL To PatchR
If m_source(Jidx + i) Then
sum = 0
For iter_y = -Winsize To Winsize: target_y = pri_y + iter_y
If target_y > 0 And target_y < m_height Then
target_y = target_y * m_width: For iter_x = -Winsize To Winsize: target_x = pri_x + iter_x
If target_x > 0 And target_x < m_width Then
Tidx = target_y + target_x
If m_mark(Tidx) >= 0 Then
source_x = i + iter_x
source_y = j + iter_y
Sidx = source_y * m_width + source_x
temp_r = m_r(Tidx) - m_r(Sidx)
temp_g = m_g(Tidx) - m_g(Sidx)
temp_b = m_b(Tidx) - m_b(Sidx)
sum = sum + temp_r * temp_r + temp_g * temp_g + temp_b * temp_b
End If
End If
Next iter_x
End If
Next iter_y
If sum < min Then: min = sum: patch_x = i: patch_y = j
End If
Next i: Next j
Paso 3: actualizar los valores de confianza
Después de que el parche Ψpˆ se haya llenado con nuevos valores de píxeles, la confianza C (p) se actualiza en el área delimitada por Ψpˆ de la siguiente manera:
Esta simple regla de actualización nos permite medir la confianza relativa de los parches en el frente de relleno, sin parámetros específicos de la imagen. A medida que avanza el relleno, los valores de confianza disminuyen, lo que indica que estamos menos seguros de los valores de color de los píxeles cerca del centro de la región objetivo. Implementado aquí (junto con todas las demás actualizaciones necesarias):
x0 = -Winsize
For iter_y = -Winsize To Winsize: For iter_x = -Winsize To Winsize
x0 = patch_x + iter_x
y0 = patch_y + iter_y
x1 = pri_x + iter_x
y1 = pri_y + iter_y
X1idx = y1 * m_width + x1
If m_mark(X1idx) < 0 Then
X0idx = y0 * m_width + x0
PicAr1(x1, y1) = m_color(X0idx)
m_color(X1idx) = m_color(X0idx)
m_r(X1idx) = m_r(X0idx)
m_g(X1idx) = m_g(X0idx)
m_b(X1idx) = m_b(X0idx)
m_gray(X1idx) = CDbl((m_r(X0idx) * 3735 + m_g(X0idx) * 19267 + m_b(X0idx) * 9765) / 32767)
m_confid(X1idx) = ComputeConfidence(pri_x, pri_y)
End If
Next iter_x: Next iter_y
For Y = IIf(pri_y - Winsize - 2 > 0, pri_y - Winsize - 2, 0) To IIf(pri_y + Winsize + 2 < m_height - 1, pri_y + Winsize + 2, m_height - 1): Yidx = Y * m_width: For X = IIf(pri_x - Winsize - 2 > 0, pri_x - Winsize - 2, 0) To IIf(pri_x + Winsize + 2 < m_width - 1, pri_x + Winsize + 2, m_width - 1)
m_mark(Yidx + X) = IIf(PicAr1(X, Y).rgbRed = MaskRed And PicAr1(X, Y).rgbgreen = MaskGreen And PicAr1(X, Y).rgbBlue = MaskBlue, -1, Source)
Next X: Next Y
For Y = IIf(pri_y - Winsize - 2 > 0, pri_y - Winsize - 2, 0) To IIf(pri_y + Winsize + 2 < m_height - 1, pri_y + Winsize + 2, m_height - 1): Yidx = Y * m_width: For X = IIf(pri_x - Winsize - 2 > 0, pri_x - Winsize - 2, 0) To IIf(pri_x + Winsize + 2 < m_width - 1, pri_x + Winsize + 2, m_width - 1)
If m_mark(Yidx + X) = -1 Then
Found = (Y = m_height - 1 Or Y = 0 Or X = 0 Or X = m_width - 1) Or m_mark(Yidx + X - 1) = Source Or m_mark(Yidx + X + 1) = Source Or m_mark((Y - 1) * m_width + X) = Source Or m_mark((Y + 1) * m_width + X) = Source
If Found Then: Found = False: m_mark(Yidx + X) = -2
End If
Next X: Next Y
For i = IIf(pri_y - Winsize - 3 > 0, pri_y - Winsize - 3, 0) To IIf(pri_y + Winsize + 3 < m_height - 1, pri_y + Winsize + 3, m_height - 1): Yidx = i * m_width: For j = IIf(pri_x - Winsize - 3 > 0, pri_x - Winsize - 3, 0) To IIf(pri_x + Winsize + 3 < m_width - 1, pri_x + Winsize + 3, m_width - 1)
If m_mark(Yidx + j) = -2 Then m_pri(Yidx + j) = ComputeConfidence(j, i) * ComputeData(j, i)
Next j: Next i
Código completo
Aquí está el código ejecutable, completo con el código fuente de las bibliotecas como comentarios.
El código es invocado por
inpaint(infile, outfile, blocksize, windowsize, r, g, b)
Se incluyen ejemplos en forma de
;~ inpaint("gothic_in.png", "gothic_out.png")
;~ inpaint("starry_in.png", "starry_out.png")
;~ inpaint("scream_in.png", "scream_out.png")
;~ inpaint("mona_in.png", "mona_out.png")
;~ inpaint("maze_in.png", "maze_out.png")
;~ inpaint("checker_in.png", "checker_out.png")
simplemente descomente el ejemplo que desea ejecutar con CTRL+ Q.
Archivos de prueba oficiales
Este algoritmo está hecho para ajustarse para cada imagen. Por lo tanto, los valores predeterminados (y también las máscaras predeterminadas) son completamente subóptimos. Los valores predeterminados se eligen para que cada muestra se pueda procesar en un período de tiempo razonable. Recomiendo jugar con máscaras de formas irregulares y mejores tamaños de ventana. Haga clic en las imágenes para ampliar!
Tablero de damas
→
gótico americano
→
Laberinto
→
Mona Lisa
→
(máscara terrible)
Gritar
→
Estrellado
→
Ejemplos del mundo real
Todos estos usan máscaras personalizadas dibujadas a mano.
Si tiene otras imágenes interesantes que le gustaría ver incluidas, deje un comentario.
Mejoras EBII
Existen múltiples variantes de EBII, creadas por varios investigadores. AnkurKumar Patel me llamó la atención con su colección de documentos [24] sobre varias mejoras de EBII.
Específicamente, el documento " Algoritmo robusto mejorado para la incrustación de imágenes basadas en ejemplos " [25] menciona dos mejoras en la ponderación de los valores de prioridad.
El mejoramiento
La modificación efectiva se encuentra en el Paso 1 (ver arriba) del algoritmo, y extiende el efecto C (p) y D (p) en la clasificación de prioridad para este píxel usando esto:
En la fórmula para C y D dada anteriormente, y son respectivamente el factor de normalización (p. Ej., Α = 255), el vector isófoto y el vector unitario ortogonal al frente en el punto p.
Promover, adicional,
La función de prioridad se define como la suma ponderada del término de confianza regularizado C (p) y el nuevo término de datos D (p) . Donde α es el coeficiente de ajuste, la satisfacción de 0Rp (p) se define a continuación:
Donde α y β son respectivamente los pesos componentes de la confianza y los términos de datos. Tenga en cuenta que α + β = 1 .
Puntuación objetiva
Sin embargo, lo que es realmente interesante es que este documento contiene un método propuesto (¡y simple!) Para calificar el rendimiento de los algoritmos EBII. Sin embargo, tome esto con un grano de sal, ya que este es un método elegido por los propios autores del artículo para verificar la efectividad del enfoque de variación propuesto y la mejora en varias imágenes.
La evaluación del resultado se realiza comparando el PSNR (la relación señal / ruido de pico [26] ) entre la imagen restaurada y la imagen original. Generalmente, cuanto mayor es el valor de PSNR, mayor es la similitud de la imagen reparada con el original. La ecuación para calcular el PSNR es la siguiente:
Estas son las asombrosas 2 (¡dos!) Imágenes de prueba del mundo real que utilizaron:
La conclusión es tan decepcionante como la calidad del papel en sí. Muestra muy poca mejora. Lo principal aquí es un posible método de puntuación de objetos para este tipo de desafío (y otros desafíos de reparación de imágenes):
+-------+---------------+----------+
| Image | EBII Original | Improved |
+-------+---------------+----------+
| 1 | 52.9556 | 53.7890 |
| 2 | 53.9098 | 53.8989 |
+-------+---------------+----------+
Meh
Investigación por hacer
(Específico para EBII)
a) Preprocesamiento
Todo se reduce al principio de "Borrado mágico" de que el algoritmo debería "simplemente funcionar" para todo. Mi solución ingenua para esto es una amplificación basada en el color (ver arriba), pero hay mejores formas. Estoy pensando en reconocer la media geométrica de todos los texels trazables para ajustar automáticamente el tamaño de la ventana y hacer que el tamaño del sello (también mi mejora) dependa de la resolución de texel e imagen completa. La investigación tiene que hacerse aquí.
b) Postprocesamiento
Los autores originales ya hicieron un gran trabajo al desacreditar todos los filtros de procesamiento posterior que vienen en mente. Hoy, probé algo más, inspirado en la siempre extraña Mona Lisa (gracias metro subterráneo). Si toma solo la región pintada y aplica una nueva máscara a todos los bloques extraños de color y la introduce en un algoritmo de eliminación de errores, tendrá un resultado casi perfecto. Puedo explorar esto en algún momento en el futuro.
[X] - Eliminación de objetos por pintura basada en ejemplos por A. Criminisi, P. Perez, K. Toyama
[1] - M. Ashikhmin. Sintetizando texturas naturales. En proc. ACM Symp. on Interactive 3D Graphics, págs. 217–226, Research Triangle Park, Carolina del Norte, marzo de 2001.
[5] - M. Bertalmio, L. Vese, G. Sapiro y S. Osher. Estructura simultánea e imagen de textura en pintura. a aparecer, 2002
[6] - R. Bornard, E. Lecan, L. Laborelli y JH. Chenot Falta la corrección de datos en imágenes fijas y secuencias de imágenes. En ACM Multimedia, Francia, diciembre de 2002.
[7] - TF Chan y J. Shen. Pintura sin textura mediante difusiones conducidas por curvatura (CDD). J. Visual Comm. Representante de imagen, 4 (12), 2001.
[8] - JS de Bonet. Procedimiento de muestreo multirresolución para análisis y síntesis de imágenes de textura. En proc. ACM Conf. Comp. Gráficos (SIGGRAPH), volumen 31, págs. 361–368, 1997.
[9] - A. Efros y WT Freeman. Acolchado de imagen para síntesis y transferencia de textura. En proc. ACM Conf. Comp. Gráficos (SIGGRAPH), págs. 341–346, Eugene Fiume, agosto de 2001.
[10] - A. Efros y T. Leung. Síntesis de textura por muestreo no paramétrico. En proc. ICCV, págs. 1033–1038, Kerkyra, Grecia, septiembre de 1999.
[11] - WT Freeman, EC Pasztor y OT Carmichael. Aprendizaje de visión de bajo nivel. En t. J. Computer Vision, 40 (1): 25–47, 2000.
[12] - D. Garber. Modelos computacionales para análisis de textura y síntesis de textura. Tesis doctoral, Univ. del sur de California, Estados Unidos, 1981.
[13] - P. Harrison. Un procedimiento no jerárquico para la resíntesis de textura compleja. En proc. En t. Conf. Europa Central Comp. Gráficos, Visua. y Comp. Vision, Plzen, República Checa, febrero de 2001.
[14] - DJ Heeger y JR Bergen. Análisis / síntesis de textura basada en pirámides. En proc. ACM Conf. Comp. Gráficos (SIGGRAPH), volumen 29, págs. 229–233, Los Ángeles, CA, 1995.
[15] - A. Hertzmann, C. Jacobs, N. Oliver, B. Curless y D. Salesin. Analogías de imagen. En proc. ACM Conf. Comp. Gráficos (SIGGRAPH), Eugene Fiume, agosto de 2001.
[16] - H. Igehy y L. Pereira. Reemplazo de imagen mediante síntesis de textura. En proc. En t. Conf. Procesamiento de imágenes, págs. III: 186–190, 1997.
[17] - G. Kanizsa. Organización en visión. Praeger, Nueva York, 1979.
[19] - L. Liang, C. Liu, Y.-Q. Xu, B. Guo y H.-Y. Shum Síntesis de textura en tiempo real mediante muestreo basado en parches. En ACM Transactions on Graphics, 2001.
[22] - L.-W. Wey y M. Levoy. Síntesis de textura rápida usando cuantificación vectorial estructurada en árbol. En proc. ACM Conf. Comp. Gráficos (SIGGRAPH), 2000.
[23] - A. Zalesny, V. Ferrari, G. Caenen y L. van Gool. Síntesis de textura compuesta paralela. En el taller Texture 2002 - (en conjunto con ECCV02), Copenhague, Dinamarca, junio de 2002.
[24] - AkurKumar Patel, Universidad Tecnológica de Gujarat, Ciencias de la Computación e Ingeniería
[25] - Algoritmo robusto mejorado para la impresión de imágenes basadas en ejemplos
[26] - Wikipedia, relación señal-ruido-pico
inpaint.exe left top width height img.jpg
)?