Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Algoritmi - Texture e trasformazioni affini
Forum - Algoritmi - Texture e trasformazioni affini

Avatar
Bonnox (Member)
Pro


Messaggi: 85
Iscritto: 23/08/2014

Segnala al moderatore
Postato alle 14:40
Venerdì, 12/08/2016
Buongiorno, ho cercato ovunque su internet ma non ho trovato molto.
Sto cercando di replicare l'effetto "mode 7" dello SNES e del GBA in software, sul computer, senza usare API. Infatti so che in java esiste una classe per le trasformazioni affini, che si possono applicare ad un'immagine per poi disegnarla. Finchè si tratta di un insieme di punti mi va anche bene, basta semplicemente moltiplicare il vettore del punto per la matrice. Ma io vorrei farlo per le immagini (leggi: texture), ma non riesco a capire che algoritmo devo usare. posso utilizzare un singolo pixel come se fosse un punto? Non verrebbe un po' "bruttino"?

E poi, domanda dal quadro più ampio:
se io avessi un piano normalissimo, e una "faccia" (un poligono giacente su un altro piano), come posso calcolare la matrice di trasformazione per la texture considerando la proiezione della faccia sul piano iniziale?

Spero di essere stato abbastanza chiaro. grazie.

Ultima modifica effettuata da Bonnox il 12/08/2016 alle 14:41
PM Quote
Avatar
Bonnox (Member)
Pro


Messaggi: 85
Iscritto: 23/08/2014

Segnala al moderatore
Postato alle 22:55
Lunedì, 15/08/2016
up, mi servirebbe soltanto sapere un algoritmo per fare in software il texture mapping...

PM Quote
Avatar
Bonnox (Member)
Pro


Messaggi: 85
Iscritto: 23/08/2014

Segnala al moderatore
Postato alle 18:51
Sabato, 20/08/2016
ho provato a fare qualcosa, ma al momento ho un paio di problemi.

Codice sorgente - presumibilmente Java

  1. package testmapping;
  2.  
  3. import java.awt.Color;
  4.  
  5. public class Texel
  6. {
  7.         public int              x;
  8.         public int              y;
  9.         public Color    clr;
  10.                                        
  11.         public Texel (int i, int j, Color c)
  12.         {
  13.                
  14.                 x = i;
  15.                 y = j;
  16.                 clr = c;
  17.         }
  18. }



Codice sorgente - presumibilmente Java

  1. package testmapping;
  2.  
  3. import java.awt.Color;
  4. import java.awt.Graphics;
  5. import java.awt.Graphics2D;
  6. import java.awt.Point;
  7. import java.util.ArrayList;
  8.  
  9. import javax.swing.JComponent;
  10.  
  11. public class DrawingPlane extends JComponent
  12. {
  13.         boolean                                 trans           = true;
  14.                                                                                
  15.         ArrayList<Texel[]>              immagini        = new ArrayList<Texel[]>();
  16.         ArrayList<double[][]>   matrici         = new ArrayList<double[][]>();
  17.                                                                                
  18.         @Override
  19.         protected void paintComponent(Graphics g)
  20.         {
  21.                 // Auto-generated method stub
  22.                 super.paintComponent(g);
  23.                
  24.                 Graphics2D g2 = (Graphics2D) g;
  25.                
  26.                 int xglob = getSize().width;
  27.                 int yglob = getSize().height;
  28.                
  29.                 // Point origin = new Point(xglob / 2, yglob / 2);
  30.                
  31.                 if (!trans) paintNorm(g2);
  32.                 else
  33.                         paintAffine(g2);
  34.         }
  35.        
  36.         private void paintAffine(Graphics2D g2)
  37.         {
  38.                 for (int h = 0; h < immagini.size(); h++)
  39.                         {
  40.                                
  41.                                 for (int i = 0; i < immagini.get(h).length; i++)
  42.                                         {
  43.                                                 try
  44.                                         {
  45.                                                 int vect[] = { immagini.get(h)[i].x, immagini.get(h)[i].y, 1 };
  46.                                                
  47.                                                 double fin[] = new double[3];
  48.                                                
  49.                                                 fin[0] = vect[0] * matrici.get(h)[0][0] + vect[1] * matrici.get(h)[0][1] + vect[2] * matrici.get(h)[0][2];
  50.                                                 fin[1] = vect[0] * matrici.get(h)[1][0] + vect[1] * matrici.get(h)[1][1] + vect[2] * matrici.get(h)[1][1];
  51.                                                 fin[2] = vect[0] * matrici.get(h)[2][0] + vect[1] * matrici.get(h)[2][1] + vect[2] * matrici.get(h)[2][1];
  52.                                                
  53.                                                                 // fin[0] /= fin[2];
  54.                                                                 // fin[1] /= fin[2];
  55.                                                 g2.setColor(immagini.get(h)[i].clr);
  56.                                                 int x1 = (int) Math.round(fin[0]);
  57.                                                 int y1 = (int) Math.round(fin[1]);
  58.                                                 g2.drawLine(x1, y1, x1, y1);
  59.                                                         } catch (Exception e)
  60.                                                         {
  61.                                                                 // System.err.println(i);
  62.                                                                
  63.                                                         }
  64.                                                         }
  65.                                        
  66.                         }
  67.                        
  68.         }
  69.        
  70.         private void paintNorm(Graphics2D g2)
  71.         {
  72.                 for (int h = 0; h < immagini.size(); h++)
  73.                         {
  74.                                 for (int i = 0; i < immagini.get(h).length; i++)
  75.                                        
  76.                                         {
  77.                                                 try
  78.                                                         {
  79.                                                 g2.setColor(immagini.get(h)[i].clr);
  80.                                                 int x = immagini.get(h)[i].x;// % mappingmain.DIM;
  81.                                                 int y = immagini.get(h)[i].y; // mappingmain.DIM;
  82.                                                 g2.drawLine(x, y, x, y);
  83.                                                         } catch (Exception e)
  84.                                                         {
  85.                                                        
  86.                                                         }
  87.                                         }
  88.                         }
  89.         }
  90.        
  91.         public DrawingPlane (Texel[] img, double[][] mtr)
  92.         {
  93.                
  94.                 immagini.add(img);
  95.                 matrici.add(mtr);
  96.         }
  97.        
  98.         public void addImage(Texel[] img, double[][] mtr)
  99.         {
  100.                
  101.                 immagini.add(img);
  102.                 matrici.add(mtr);
  103.         }
  104.        
  105. }



Codice sorgente - presumibilmente Java

  1. package testmapping;
  2.  
  3. import java.awt.BorderLayout;
  4. import java.awt.Color;
  5. import java.awt.EventQueue;
  6. import java.awt.image.BufferedImage;
  7. import java.awt.image.DataBufferInt;
  8. import java.io.File;
  9. import java.io.IOException;
  10.  
  11. import javax.imageio.ImageIO;
  12. import javax.swing.JFrame;
  13.  
  14. public class mappingmain
  15. {
  16.         private static final double     matrix1[][]     = { { 0.56826, -0.33442, 131 }, { 0.19429, 0.65218, +38 }, { -0.00018, 0, 0 } };
  17.                                                                                        
  18.         // private static final double matrix2[][] = { { 1.5, -0.866, 200 }, {
  19.         // 0.866, 1.5, 200 }, { 0, 0, 1 } };
  20.        
  21.         /**
  22.          * @Deprecated
  23.          */
  24.         // public static final int DIM = 200;
  25.         private JFrame                          frame;
  26.                                                                
  27.         /**
  28.          * Launch the application.
  29.          */
  30.                                                                 public static void main(String[] args)
  31.         {
  32.                 EventQueue.invokeLater(new Runnable()
  33.                 {
  34.                         public void run()
  35.                         {
  36.                                 try
  37.                                         {
  38.                                                 mappingmain window = new mappingmain();
  39.                                                 window.frame.setVisible(true);
  40.                                         } catch (Exception e)
  41.                                         {
  42.                                                 e.printStackTrace();
  43.                                         }
  44.                         }
  45.                 });
  46.         }
  47.        
  48.         /**
  49.          * Create the application.
  50.          */
  51.         public mappingmain () throws IOException
  52.         {
  53.                 initialize();
  54.                
  55.         }
  56.        
  57.         private Texel[] readimg(String percorso) throws IOException
  58.         {
  59.                
  60.                 BufferedImage bi = ImageIO.read(new File(percorso));
  61.                
  62.                 int my = bi.getHeight();
  63.                 int mx = bi.getWidth();
  64.                
  65.                 int npix = mx * my;
  66.                
  67.                 Texel[] immagine = new Texel[npix];
  68.                
  69.                 // int[] data = ((DataBufferInt)
  70.                 // bi.getRaster().getDataBuffer()).getData();
  71.                
  72.                 for (int i = 0; i < npix; i++)
  73.                         {
  74.                                 try
  75.                                         {
  76.                                                 immagine[i] = new Texel(i / mx, i % mx, new Color(bi.getRGB(i / mx, i % mx)));
  77.                                         } catch (Exception e)
  78.                                         {
  79.                                                 System.err.println(i);
  80.                                         }
  81.                                        
  82.                         }
  83.                        
  84. //              for (int i = 0; i < mx; i++)
  85. //                      {
  86. //                              for (int j = 0; j < my; j++)
  87. //                                      {
  88. //                                              immagine[i] = new Texel(i, j, new Color(bi.getRGB(i, j)));
  89. //                                      }
  90. //                      }
  91. //                     
  92.                 return immagine;
  93.                
  94.         }
  95.        
  96.         /**
  97.          * Initialize the contents of the frame.
  98.          */
  99.         private void initialize() throws IOException
  100.         {
  101.                 frame = new JFrame();
  102.                 frame.setBounds(100, 100, 800, 800);
  103.                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  104.                 frame.setLayout(new BorderLayout());
  105.                 DrawingPlane dp = new DrawingPlane(readimg("D:/jpg_file_37138.jpg"), mappingmain.matrix1);
  106.                 frame.add(dp);
  107.                
  108.                 // dp.addImage(initimg2(), matrix2);
  109.                
  110.         }
  111.        
  112.         /*
  113.          * private Texel[] initimg()
  114.          * {
  115.          * Texel[] immagine = new Texel[DIM * DIM];
  116.          *
  117.          * for (int i = 0; i < immagine.length / 2; i++)
  118.          * {
  119.          * if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
  120.          * Color.RED);
  121.          * else
  122.          * immagine[i] = new Texel(i % DIM, i / DIM, Color.YELLOW);
  123.          *
  124.          * }
  125.          * for (int i = immagine.length / 2; i < immagine.length; i++)
  126.          * {
  127.          *
  128.          * if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
  129.          * Color.GREEN);
  130.          * else
  131.          * immagine[i] = new Texel(i % DIM, i / DIM, Color.BLUE);
  132.          *
  133.          * }
  134.          * return immagine;
  135.          * }
  136.          */
  137.        
  138.         /*
  139.          * private Texel[] initimg1()
  140.          * {
  141.          * Texel[] immagine = new Texel[DIM * DIM];
  142.          *
  143.          * for (int i = 0; i < immagine.length / 2; i++)
  144.          * {
  145.          * if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
  146.          * Color.RED);
  147.          * else
  148.          * immagine[i] = new Texel(i % DIM, i / DIM, Color.YELLOW);
  149.          *
  150.          * }
  151.          * for (int i = immagine.length / 2; i < immagine.length; i++)
  152.          * {
  153.          *
  154.          * if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
  155.          * Color.GREEN);
  156.          * else
  157.          * immagine[i] = new Texel(i % DIM, i / DIM, Color.BLUE);
  158.          *
  159.          * }
  160.          * for (int i = 0; i < immagine.length; i++)
  161.          * {
  162.          * int riga = i / DIM;
  163.          * int colonna = i % DIM;
  164.          *
  165.          * if (riga + colonna > DIM) immagine[i] = new Texel(immagine[i].x,
  166.          * immagine[i].y, new Color(238, 238, 238));
  167.          *
  168.          * }
  169.          *
  170.          * return immagine;
  171.          * }
  172.          */
  173.        
  174.         /*
  175.          * private Texel[] initimg2()
  176.          * {
  177.          * Texel[] immagine = new Texel[DIM * DIM];
  178.          *
  179.          * for (int i = 0; i < immagine.length / 2; i++)
  180.          * {
  181.          * if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
  182.          * Color.RED);
  183.          * else
  184.          * immagine[i] = new Texel(i % DIM, i / DIM, Color.YELLOW);
  185.          *
  186.          * }
  187.          * for (int i = immagine.length / 2; i < immagine.length; i++)
  188.          * {
  189.          *
  190.          * if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
  191.          * Color.GREEN);
  192.          * else
  193.          * immagine[i] = new Texel(i % DIM, i / DIM, Color.BLUE);
  194.          *
  195.          * }
  196.          * for (int i = 0; i < immagine.length; i++)
  197.          * {
  198.          * int riga = i / DIM;
  199.          * int colonna = i % DIM;
  200.          *
  201.          * if (riga + colonna <= DIM) immagine[i] = new Texel(immagine[i].x,
  202.          * immagine[i].y, new Color(238, 238, 238));
  203.          *
  204.          * }
  205.          *
  206.          * return immagine;
  207.          * }
  208.          *
  209.          */
  210.        
  211. }
  212.  
  213. /*
  214.  *
  215.  * */



screenshot:

normale:
https://s4.postimg.org/o42em3wgd/Cattura.png
rotazione 45 gradi:
https://s3.postimg.org/pao9lkrr7/Cattura.png
(va be non è interpolato non mi interessa al momento)


i problemi sono che se l'immagine non è perfettamente quadrata, dei pixel del lato lungo vengono tagliati. Ma credo che questo dipenda dal mio algoritmo.
Mentre invece per quanto riguarda la trasformazione va bene. cioè se metto una matrice affine funziona (scalatura trasposizione e rotazione). il problema è che non mi fa la trasformazione prospettica. E sì che la matrice l'ho presa da GIMP! l'ho aperto, ho applicato lo strumento prospettiva ad una immagine e ho copiato la matrice. finchè i 4 lati rimangono paralleli a coppie funziona. se muovo i vertici in modo che sembra proiettato, no. talvolta non va neanche.

in particolare, sto cercando un effetto del genere:
http://i.stack.imgur.com/5Cceq.gif

Ma si svolge in maniera diversa questo effetto?
Secondo voi è alta la difficoltà di reperire questo comportamento nel sorgente di GIMP??

qualcuno ne sa di più in merito? grazie.

Ultima modifica effettuata da Bonnox il 21/08/2016 alle 10:30
PM Quote
Avatar
Bonnox (Member)
Pro


Messaggi: 85
Iscritto: 23/08/2014

Segnala al moderatore
Postato alle 17:24
Domenica, 21/08/2016
ok ora va già meglio. ho corretto già il secondo bug relativo alla parte più importante, la moltiplicazione riga * colonna !!
Ora se copio una matrice di GIMP e la metto dentro, si assomigliano, ovvero "c'è un barlume di prospettiva", ma ancora i lati rimangono paralleli. ecco un paragone di esempio.

https://s10.postimg.org/6i02qx7fd/Immagine.png

(hpo usato la prima immagine disponibile, uno screenshot del VBA:rotfl: )

PM Quote