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.