what vectorizer vectorized vectorize org images extension are app image-processing colors vectorization reduction

image-processing - vectorizer - vectorized graphics



¿Convertir la imagen BMP en un conjunto de instrucciones para un trazador? (1)

Tengo un plotter como este:

La tarea que tengo que implementar es la conversión de BMP de 24 bits a un conjunto de instrucciones para este trazador. En el plotter puedo cambiar 16 colores comunes. La primera complejidad que enfrento es la reducción de colores. La segunda complejidad que enfrento es cómo transformar píxeles en un conjunto de instrucciones de dibujo.

Como herramienta de dibujo se utilizará pincel con pintura al óleo. Significa que las líneas de dibujo del trazador no serán tan pequeñas y serán relativamente cortas.

¿Sugiere algoritmos que se puedan usar para resolver este problema de conversión de datos de imagen?

Algunos resultados iniciales:


Tramado

Bueno, tengo algo de tiempo para esto hoy, así que aquí está el resultado. No proporcionó su paleta de colores del trazador, así que la extraje de sus imágenes resultantes, pero puede usar cualquiera. La idea detrás del tramado es simple: nuestra percepción integra el color en el área, no los píxeles individuales, por lo que debe usar un acumulador de diferencia de color de lo que se procesa y lo que se debe renderizar, y agregar esto al siguiente píxel ...

De esta manera, el área tiene aproximadamente el mismo color, pero solo se utiliza un número discreto de colores en el real. La forma de cómo actualizar esta información puede diferenciar el dithering de ramificación de resultados en muchos métodos. El simple y sencillo es este:

  1. restablecer el acumulador de color a cero
  2. procesar todos los píxeles
    1. para cada píxel agregue su color al acumulador
    2. encuentre la coincidencia más cercana del resultado en su paleta
    3. renderizar el color de la paleta seleccionada
    4. restar el color de la paleta seleccionada del acumulador

Aquí su imagen de entrada (los puse juntos):

Aquí imagen del resultado para su fuente:

Los cuadrados de color en la esquina superior izquierda son solo la paleta que utilicé (extraída de su imagen).

Aquí el código ( C ++ ) hago esto con:

picture pic0,pic1,pic2; // pic0 - source img // pic1 - source pal // pic2 - output img int x,y,i,j,d,d0,e; int r,g,b,r0,g0,b0; color c; List<color> pal; // resize output to source image size clear with black pic2=pic0; pic2.clear(0); // create distinct colors pal[] list from palette image for (y=0;y<pic1.ys;y++) for (x=0;x<pic1.xs;x++) { c=pic1.p[y][x]; for (i=0;i<pal.num;i++) if (pal[i].dd==c.dd) { i=-1; break; } if (i>=0) pal.add(c); } // dithering r0=0; g0=0; b0=0; // no leftovers for (y=0;y<pic0.ys;y++) for (x=0;x<pic0.xs;x++) { // get source pixel color c=pic0.p[y][x]; // add to leftovers r0+=WORD(c.db[picture::_r]); g0+=WORD(c.db[picture::_g]); b0+=WORD(c.db[picture::_b]); // find closest color from pal[] for (i=0,j=-1;i<pal.num;i++) { c=pal[i]; r=WORD(c.db[picture::_r]); g=WORD(c.db[picture::_g]); b=WORD(c.db[picture::_b]); e=(r-r0); e*=e; d =e; e=(g-g0); e*=e; d+=e; e=(b-b0); e*=e; d+=e; if ((j<0)||(d0>d)) { d0=d; j=i; } } // get selected palette color c=pal[j]; // sub from leftovers r0-=WORD(c.db[picture::_r]); g0-=WORD(c.db[picture::_g]); b0-=WORD(c.db[picture::_b]); // copy to destination image pic2.p[y][x]=c; } // render found palette pal[] (visual check/debug) x=0; y=0; r=16; g=pic2.xs/r; if (g>pal.num) g=pal.num; for (y=0;y<r;y++) for (i=0;i<g;i++) for (c=pal[i],x=0;x<r;x++) pic2.p[y][x+(i*r)]=c;

donde picture es mi clase de imagen, así que aquí algunos miembros:

  • resolución xs,ys
  • color p[ys][xs] acceso directo a píxeles (formato de píxeles de 32 bits, 8 bits por canal)
  • clear(DWORD c) llena la imagen con color c

El color es solo la union de DWORD dd y BYTE db[4] para un acceso simple al canal.

La List<> es mi plantilla (matriz dinámica / lista>

  • List<int> a es lo mismo que int a[] .
  • add(b) agregar b al final de la lista
  • num es el número de elementos en la lista

Ahora, para evitar demasiados puntos (durante la vida útil de su plotter), puede usar diferentes patrones de línea, etc., pero eso requiere mucha prueba / error ... Por ejemplo, puede contar cuántas veces se usa un color en alguna área y a partir de esa proporción, use diferentes patrones de relleno (basados ​​en líneas). Debe elegir entre calidad de imagen y velocidad de renderizado / durabilidad ...

Sin más información sobre las capacidades de su trazador (velocidades, método de cambio de herramienta, comportamiento de combinación de colores) es difícil decidir el mejor método para formar un flujo de control. Mi apuesta es que cambie los colores manualmente para que renderice cada color a la vez. Entonces, extraiga todos los píxeles con el color de la primera herramienta, combine los píxeles adyacentes en líneas / curvas y renderice ... luego muévase al siguiente color de herramienta ...