Transformacja obrazu rastrowego

0

Klasa Macierz

public class Macierz {

	public double[][] mnozenie(double[][] l, double[][] r){
		//nie sprawdza czy macierze mozna mnozyc
		double[][] wynik = new double[l.length][r[1].length];
		
		for(int i = 0; i < l.length;i++){//wiersze w macierzy l
			for(int j = 0; j < r[1].length;j++){//kolumny macierzy r
				for(int k = 0; k <r.length; k++ ){//kolumny macierzy l i wiersze macierzy k
					wynik[i][j] += l[i][k] * r[k][j]; 
				}
			}
		}
		
		return wynik;
	}
	public double wyznacznik2x2 (double [] mac)
	{
		
		return mac[0] * mac [3] - mac[2] * mac[1];
	}
	public double wyznacznik3x3(double[][] mac)
	{
		return mac[0][0]*mac[1][1]*mac[2][2] + mac[0][1]*mac[1][2]*mac[2][0]
				+ mac[0][2]*mac[1][0]*mac[2][1] - (mac[2][0]*mac[1][1]*mac[0][2]
						+ mac[0][0]*mac[2][1]*mac[1][2] + mac[1][0]*mac[0][1]*mac[2][2]);
	}
	public double[][] odwrotna(double[][] mac)
	{
		double [][] nowa = new double[3][3];
		double wyznacznik = wyznacznik3x3(mac);
		if (wyznacznik == 0.0 || wyznacznik == -0.0) System.out.println("Macierz jest nieodwracalna!");
		//oblicznie dopełnienia
		for(int i = 0; i < mac.length; i++)
		{
			for(int j = 0; j < mac.length;j++)
			{
				double[] x2 = new double[4];
				int count = 0;
				for(int k = 0; k < mac.length;k++)
				{
					for(int l = 0; l < mac.length; l++)
					{
						if (count < 4)
						{
							if ( k != i && j != l)
							{
								x2[count] = mac[k][l];
								count++;
							}
						}
					}
				}
				double temp = (Math.pow(-1, i+j)*wyznacznik2x2(x2))/wyznacznik;
				if(temp == -0.0) temp = 0.0;
				nowa[i][j] = temp;
			}
		}
		//transponowanie
		double [][] pom = new double [3][3];
		for(int i = 0;i<mac.length;i++)
		{
			for(int j = 0; j<mac.length;j++)
			{
				pom[j][i] = nowa[i][j];
			}
		}
		return pom;
	}
	public static void main(String[] args)
	{
		Macierz m = new Macierz();
		double[][] przeksz ={{2,0,0},{0,2,0},{0,0,1}};
		double[][] punkt = {{1,2,1},{2,-1,2},{-1,81,1}};
		double[][] kon = m.odwrotna(przeksz);
		for(int i = 0; i < kon.length;i++)
		{
			for(int j = 0;j<kon[i].length;j++)
			{
				System.out.print(kon[i][j]+" ");
			}
			System.out.println();
		}
	}
}

Klasa Okno - główna

import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Okienko extends JFrame{
	//panele
	private JPanel vector;
	public JPanel raster;
	//przyciski wektorowe
	private JButton vLoadFile;
	private JButton vLoadTransform;
	private JButton vTransform;
	//przyciski rastrowe
	private JButton rLoadFile;
	private JButton rLoadTransform;
	private JButton rTransform;
	
	public Okienko()
	{
		setBounds(100, 100, 1090, 520);
		setVisible(true);
		setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		setTitle("Graphics Transformations");
		setLayout(null);
		Container  contents = getContentPane();
		vector = new Vector();
		contents.add(vector);
		raster = new Raster();
		contents.add(raster);
		setControls();
	}
	
	private void setControls()
	{
		//grafika wektorowa
		vLoadFile = new JButton("Load File");
		vLoadFile.setBounds(20, 420, 120, 45);
		vLoadFile.addMouseListener(new MouseAdapter() {
			
			public void mouseClicked(MouseEvent e) {
				try {
					((Vector) vector).loadFile();
				} catch (IOException e1) {
					System.out.println("Wczytanie pliku nie powiodlo się");
					e1.printStackTrace();
				}
				
			}
		});
		vLoadTransform = new JButton("Load Transformation");
		vLoadTransform.setBounds(160, 420, 200, 45);
		vLoadTransform.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e) {
				try {
					((Vector) vector).loadTransformation();
				} catch (IOException e1) {
					System.out.println("Wczytanie pliku nie powiodlo się");
					e1.printStackTrace();
				}
				
			}
		});
		vTransform = new JButton("Transform");
		vTransform.setBounds(380, 420, 140, 45);
		vTransform.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e) {
				((Vector) vector).transform();
			}
		});
		add(vLoadFile);
		add(vLoadTransform);
		add(vTransform);
		
		//grafika rastrowa
		rLoadFile = new JButton("Load File");
		rLoadFile.setBounds(550, 420, 120, 45);
		rLoadFile.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e) {
				try {
					((Raster) raster).loadFile();
				} catch (IOException e1) {
					System.out.println("Wczytanie pliku nie powiodlo się");
					e1.printStackTrace();
				}
				
			}
		});
		rLoadTransform = new JButton("Load Transformation");
		rLoadTransform.setBounds(690, 420, 200, 45);
		rLoadTransform.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e) {
				try {
					((Raster) raster).loadTransformation();
				} catch (IOException e1) {
					System.out.println("Wczytanie pliku nie powiodlo się");
					e1.printStackTrace();
				}
			}
		});
		rTransform = new JButton("Transform");
		rTransform.setBounds(910, 420, 140, 45);
		rTransform.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e) {
					((Raster) raster).transform();
			}
		});
		add(rLoadFile);
		add(rLoadTransform);
		add(rTransform);
	}
	
	public static void main(String[] args)
	{
		Okienko o = new Okienko();
	}
}

Klasa Raster - tutaj mam problem

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.io.StringBufferInputStream;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;


public class Raster extends JPanel
{	
	private Macierz m;
	private BufferedImage image;
	//macierz przekształcenia
	private double[][] macierz;
	//punkty startowe
	private int xPosition;
	private int yPosition;
	//punkty kontrolne
	private double[][] p1;
	private double[][] p2;
	private double[][] p3;
	private double[][] p4;
	
	public Raster()
	{
		setLayout(null);
		setBounds(550, 20, 500, 400);
		setBackground(Color.WHITE);
		setBorder(new TitledBorder(new EtchedBorder(), "Raster"));
		m = new Macierz();
	}
	
	public void paintComponent( Graphics g)
	   {
		   super.paintComponent(g);   
	       Graphics2D  g2d = (Graphics2D)g;	
	       if(image != null) g2d.drawImage(image, xPosition + (int)getWidth()/2, yPosition + (int)getHeight()/2, this);
	       g2d.setStroke(new BasicStroke(1));
	       g2d.setColor(Color.BLACK);
	       g2d.drawLine(getWidth()/2, 0, getWidth()/2, getHeight());
	       g2d.drawLine(0, getHeight()/2, getWidth(), getHeight()/2);
	   }	
	public void loadFile() throws IOException
	{
		image = ImageIO.read(new File("C:/Users/psimek/Desktop/obrazRaster.bmp"));
		xPosition = 0;
		yPosition = 0;///////////////////////////////////////javowskie
		//yPosition = -image.getHeight();
		System.out.println("raster - nowy obraz\n"+ xPosition + " " + (-yPosition) + " : " +image.getWidth()+" x " + image.getHeight());
		//punkty kontrolne
		p1 = new double[1][3]; p1[0][0] = xPosition; p1[0][1] = yPosition; p1[0][2] = 1;
		//p1 = {{xPosition,yPosition,1}};
		p2 = new double[1][3]; p2[0][0] = xPosition + image.getWidth(); p2[0][1] = yPosition; p2[0][2] = 1;
		//p2 = {{(xPosition + image.getWidth()),yPosition,1}};
		p3 = new double[1][3]; p3[0][0] = xPosition + image.getWidth(); p3[0][1] = yPosition + image.getHeight(); p3[0][2] = 1;
		//p3 = {{(xPosition + image.getWidth()),(yPosition + image.getHeight()),1}};
		p4 = new double[1][3]; p4[0][0] = xPosition; p4[0][1] = yPosition + image.getHeight(); p4[0][2] = 1;
		//p4 = {{(xPosition),(yPosition + image.getHeight()),1}};
		repaint();
	}
	@SuppressWarnings("deprecation")
	public void loadTransformation() throws IOException
	{
		StreamTokenizer st;
		Scanner sc = new Scanner(new File("C:/Users/psimek/Desktop/macierzR.txt"));
		macierz = new double[3][3];
		for(int i = 0; i<3;i++)
		{
			macierz[i][i] = 1;
		}
		while(sc.hasNextLine())
		{
			double[][] temp = new double[3][3];
			st = new StreamTokenizer(new BufferedReader(new InputStreamReader(new StringBufferInputStream(sc.nextLine()))));
			st.nextToken();
			while(st.ttype != StreamTokenizer.TT_EOF)
			{
				for(int i = 0; i < 3; i++)
				{
					for(int j = 0; j < 3; j++)
					{
						if(st.ttype == StreamTokenizer.TT_EOF || st.ttype == StreamTokenizer.TT_EOL)
						{
							System.out.println("raster - nie można wczytać tej macierzy!");
							macierz = null;
							return;
						}
						temp[i][j] = st.nval;
						st.nextToken();
					}
				}
				break;
			}
			macierz = m.mnozenie(macierz, temp);
			
		}	
		System.out.println("raster - macierz transformacji");
		for(int i = 0;i<3;i++)
		{
			for(int j = 0;j<3;j++)
			{
				System.out.print(macierz[i][j]+"\t");
			}
		}
		System.out.println();
	}
	public void transform()
	{
		try{
			if(image != null && macierz != null)
			{
				double[][] odwrotna = m.odwrotna(macierz);
				BufferedImage temp;
				//kontury nowego obrazu
				//p1
				System.out.println("raster - transformacja");
				System.out.print("p1\t"+p1[0][0]+"\t"+p1[0][1] +"\t -> ");
				p1 = m.mnozenie(p1,macierz);
				System.out.println("\t"+p1[0][0]+"\t"+p1[0][1]);
				//p2
				System.out.print("p2\t"+p2[0][0]+"\t"+p2[0][1] +"\t -> ");
				p2 = m.mnozenie(p2,macierz);
				System.out.println("\t"+p2[0][0]+"\t"+p2[0][1]);
				//p3
				System.out.print("p3\t"+ p3[0][0]+"\t"+p3[0][1] +"\t -> ");
				p3 = m.mnozenie(p3,macierz);
				System.out.println("\t"+p3[0][0]+"\t"+p3[0][1]);
				//p4
				System.out.print("p4\t"+p4[0][0]+"\t"+p4[0][1] +"\t -> ");
				p4 = m.mnozenie(p4,macierz);
				System.out.println("\t"+p4[0][0]+"\t"+p4[0][1]);
				
				//height
				double h1 = Math.abs(p1[0][1] - p2[0][1]);
				double h2 = Math.abs(p1[0][1] - p3[0][1]);
				double h3 = Math.abs(p1[0][1] - p4[0][1]);
				double h4 = Math.abs(p2[0][1] - p3[0][1]);
				double h5 = Math.abs(p2[0][1] - p4[0][1]);
				double h6 = Math.abs(p3[0][1] - p4[0][1]);
				int height = (int)Math.max(h1, Math.max(h2, Math.max(h3, Math.max(h4, Math.max(h5, h6)))));
				
				//width
				double w1 = Math.abs(p1[0][0] - p2[0][0]);
				double w2 = Math.abs(p1[0][0] - p3[0][0]);
				double w3 = Math.abs(p1[0][0] - p4[0][0]);
				double w4 = Math.abs(p2[0][0] - p3[0][0]);
				double w5 = Math.abs(p2[0][0] - p4[0][0]);
				double w6 = Math.abs(p3[0][0] - p4[0][0]);
				int width = (int)Math.max(w1, Math.max(w2, Math.max(w3, Math.max(w4, Math.max(w5, w6)))));
				
				//nowy obraz
				temp = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
				//ustalanie nowej pozycji rysowania obrazu
				int nxPosition = (int)Math.min(p1[0][0], Math.min(p2[0][0], Math.min(p3[0][0], p4[0][0])));
				int nyPosition = (int)Math.min(p1[0][1], Math.min(p2[0][1], Math.min(p3[0][1], p4[0][1])));///////////////////////////////////////obroty javowskie min bez minusa
				
//				for(int i = 0; i < image.getWidth(); i++)
//				{
//					for(int j = 0; j < image.getHeight();j++)
//					{
//						System.out.println(i+", "+j);
//					}
//				}

				System.out.println("szerokość x wysokość : "+temp.getWidth()+" x "+temp.getHeight());

				for(int i = 0; i < temp.getWidth(); i++)
				{
					for(int j = 0; j < temp.getHeight();j++)
					{
						try{
						double[][] current = {{i,j,1}};
						double[][] pom = m.mnozenie(current, odwrotna);
						System.out.print(current[0][0] +" "+current[0][1]+" -> "+(pom[0][0])+" "+pom[0][1]+4);
						System.out.println("\t-> "+(pom[0][0]+3)+" "+(pom[0][1]));
						
						temp.setRGB(i, j, image.getRGB((int)(pom[0][0]), (int)(pom[0][1]+4)));

						}
						catch(Exception e)
						{
							
							temp.setRGB(i, j, 0);
						}
					}
				}
				
				System.out.println("początek "+xPosition+" "+yPosition+" -> "+nxPosition+" "+nyPosition);
				image = temp;
				xPosition = nxPosition;
				yPosition = nyPosition;
			}
			else
			{
				System.out.println("raster - nie można wykonać transformacji!");
			}
			repaint();
		}
		catch(OutOfMemoryError e)
		{
			System.out.println("raster - obraz poza skalą!");
		}
		catch(IllegalArgumentException ex)
		{
			System.out.println("raster - obraz poza skalą!");
		}
		catch(Exception exc)
		{
			System.out.println("raster - nie można wykonać transformacji!");
		}
	}
}

Klasa vector - żadnych problemów

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.io.StringBufferInputStream;
import java.util.LinkedList;
import java.util.Scanner;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;


public class Vector extends JPanel
{
	private Macierz m;
	private LinkedList<Punkt> punkty;
	private LinkedList<Linia> linie;
	private double[][] macierz;
	
	public Vector()
	{
		setLayout(null);
		setBounds(20, 20, 500, 400);
		setBackground(Color.WHITE);
		setBorder(new TitledBorder(new EtchedBorder(), "Vector"));
		m = new Macierz();
	}
	
	public void paintComponent( Graphics g)
	   {
		   super.paintComponent(g);   
	       Graphics2D  g2d = (Graphics2D)g;	  
	       g2d.setStroke(new BasicStroke(1));
	       g2d.setColor(Color.BLACK);
	       g2d.drawLine(getWidth()/2, 0, getWidth()/2, getHeight());
	       g2d.drawLine(0, getHeight()/2, getWidth(), getHeight()/2);
	       g2d.setStroke(new BasicStroke(3));
	       if (linie != null)
	       {
	    	   for(int i = 0; i < linie.size();i++)
	    	   {
	    		   Linia l = linie.get(i);
	    		   Punkt poc = punkty.get((int) l.getPon());
	    		   Punkt kon = punkty.get((int) l.getKon());
	    		   /*g2d.drawLine((int)poc.getX()+getWidth()/2, (int)poc.getY()+getHeight()/2,
	    				   (int)kon.getX()+getWidth()/2, (int)kon.getY()+getHeight()/2);*///uklad javowski
	    		   g2d.drawLine((int)poc.getX()+getWidth()/2, (int)(-poc.getY()+getHeight()/2),
	    				   (int)kon.getX()+getWidth()/2, (int)(-kon.getY()+getHeight()/2));//układ kartezjański
	    	   }
	       }
	       g2d.setStroke(new BasicStroke(1));
	   }
	@SuppressWarnings("deprecation")
	public void loadFile() throws IOException
	{
		StreamTokenizer st;
		Scanner sc = new Scanner(new File("C:/Users/psimek/Desktop/obrazWektor.txt"));
		punkty = new LinkedList<Punkt>();
		linie = new LinkedList<Linia>();
		while(sc.hasNextLine())
		{
			st = new StreamTokenizer(new BufferedReader(new InputStreamReader(new StringBufferInputStream(sc.nextLine()))));
			st.nextToken();
			String current = st.sval;
			if(current.equals(new String("punkt")))
			{
				st.nextToken();
				st.nextToken();
				double x = st.nval;
				st.nextToken();
				double y = st.nval;
				punkty.add(new Punkt(x,y));
			}
			
			if(current.equals(new String("kreska")))
			{
				st.nextToken();
				double poc = st.nval;
				st.nextToken();
				double kon = st.nval;
				linie.add(new Linia(poc,kon));
			}
		}
		System.out.println("vector - nowy obraz\n"+punkty.toString());
		repaint();
	}
	@SuppressWarnings("deprecation")
	public void loadTransformation() throws IOException
	{
		StreamTokenizer st;
		Scanner sc = new Scanner(new File("C:/Users/psimek/Desktop/macierzV.txt"));
		macierz = new double[3][3];
		for(int i = 0; i<3;i++)
		{
			macierz[i][i] = 1;
		}
		while(sc.hasNextLine())
		{
			double[][] temp = new double[3][3];
			st = new StreamTokenizer(new BufferedReader(new InputStreamReader(new StringBufferInputStream(sc.nextLine()))));
			st.nextToken();
			while(st.ttype != StreamTokenizer.TT_EOF)
			{
				for(int i = 0; i < 3; i++)
				{
					for(int j = 0; j < 3; j++)
					{
						if(st.ttype == StreamTokenizer.TT_EOF || st.ttype == StreamTokenizer.TT_EOL)
						{
							System.out.println("vector - nie można wczytać tej macierzy!");
							macierz = null;
							return;
						}
						temp[i][j] = st.nval;
						st.nextToken();
					}
				}
				break;
			}
			macierz = m.mnozenie(macierz, temp);
			
		}	
		System.out.print("vector - macierz przekształcenia\n");
		for(int i = 0;i<3;i++)
		{
			for(int j = 0;j<3;j++)
			{
				System.out.print(macierz[i][j]+"\t");
			}
		}
		System.out.println();
	}
	public void transform()
	{
		if (macierz != null)
		{
			LinkedList<Punkt> temp = new LinkedList<Punkt>();
			System.out.println("vector - transformacja");
			while(!punkty.isEmpty())
			{
				Punkt current = punkty.pop();
				double[][] punkt ={{current.getX(),current.getY(),1}};
				double[][] pom = m.mnozenie(punkt, macierz);
				System.out.println(current.getX()+"\t"+ current.getY()+"\t -> \t"+pom[0][0] + "\t"+pom[0][1]);
				temp.add(new Punkt(pom[0][0],pom[0][1]));
			}
			//System.out.println("\n" + temp.toString());
			punkty = temp;
		}
		else
		{
			System.out.println("vector - nie można dokonać przeksztaucenia!");
		}
		repaint();
	}
}

Dokładnie ta część klasy Raster odpowiada za odwoływanie się do odpowiednich pokseli

 for(int i = 0; i < temp.getWidth(); i++)
				{
					for(int j = 0; j < temp.getHeight();j++)
					{
						try{
						double[][] current = {{i,j,1}};
						double[][] pom = m.mnozenie(current, odwrotna);
						System.out.print(current[0][0] +" "+current[0][1]+" -> "+(pom[0][0])+" "+pom[0][1]+4);
						System.out.println("\t-> "+(pom[0][0]+3)+" "+(pom[0][1]));
						
						temp.setRGB(i, j, image.getRGB((int)(pom[0][0]), (int)(pom[0][1]+4)));

						}
						catch(Exception e)
						{
							
							temp.setRGB(i, j, 0);
						}
					}
				}

Przykładowa macierz przekształcenia z pliku(może być ich kilka
0 1 0 -1 0 0 0 0 1</code><code class="java">

Mój problem polega na tym,że przy przekształceniu obrazu wejściowego dowolnymi macierzami nie potrafię odwołać się do odpowiednich pikseli ze starego obrazu, aby przenieść ich wartości RGB ze starego do nowo powstałego obrazka.
W tym celu oczywiście używam macierz odwrotną do zadanego przekształcenia.
W pierwszej kolejności staram się to wykonać przy pomocy interpolacji liniowej(docelowo dwuliniowej).

Proszę o pomoc przy rozwiązaniu problemu odwołania się do odpowiednich pikseli.

0

Problem rozwiązany

 for(int i = 0; i < temp.getWidth(); i++)
				{
					for(int j = 0; j < temp.getHeight();j++)
					{
						try{
						double[][] current = {{i+nxPosition,j+nyPosition,1}};
						double[][] pom = m.mnozenie(current, odwrotna);
						
//						System.out.print(current[0][0] +" "+current[0][1]+" -> "+(pom[0][0])+" "+pom[0][1]);
//						System.out.println("\t-> "+(pom[0][0]-xPosition)+" "+(pom[0][1]-yPosition));
						
						temp.setRGB(i, j, image.getRGB((int)(pom[0][0]-xPosition), (int)(pom[0][1]-yPosition)));
						}
						catch(Exception e)
						{
							
							temp.setRGB(i, j, 0);
						}
					}
				}
				

1 użytkowników online, w tym zalogowanych: 0, gości: 1