Here are the notes for part I

Download Report

Transcript Here are the notes for part I

The Picture Lab
Manipulating 2D arrays in Java
RGB colors
• Colors are typically represented by their components in red,
green, and blue
• Each component ranges from 0-255
• Each component requires 8 bits
• See the java.awt.Color class in java
• Consider a 640x480 picture, calculate the required number of:
• Pixels
• Bytes
• Bits
• Let’s run the ColorChooser.java program to look more closely
at how Colors are constructed in Java
ColorChooser.java
• How do you create:
• Red
Green
Blue
Gray
Black
Magenta
Yellow
• How do you create:
• White
• How do you create:
• Cyan
• How do you increase/decrease the intensity of a color
• Light Yellow vs Dark Yellow
Storing pixels in an image
• Run the file PictureExplorer.java
• The image beach.jpg should load a 640x480 image
•
•
•
•
What is the row and column index for the top left corner?
What is the largest row index?
What is the largest column index?
How does the row index change as you move from left to
right?
• How does the column index change as you move from top to
bottom?
Representing pixels in Java
• Most images are manipulated as 2D arrays, an array of arrays
• int[] oneDim = new int[10];
• int[][] twoDim = new int[3][5];
• More dimensions are possible:
• int[][][] threeDim = new int[1][2][3];
• Why an array of arrays?
• Convenient way to represent a table of values
Creating 2D Arrays
// A 2D array with 4 rows,
// 3 columns, 12 elements
int[][] array = {{41,38,91},{63,10,21},{29,28,13},{70,52,39}};
int[][] array = {
{41,38,91},
array[0][0]
41
{63,10,21},
{29,28,13},
array[0][1]
38
{70,52,39}};
array[0][2]
array[1][0]
Col Index
0
1
2
3
Row Index
0
1
2
41
63
38
10
91
21
29
70
28
52
13
39
array[1][1]
array[1][2]
array[2][0]
array[2][1]
array[2][2]
array[3][0]
array[3][1]
array[3][2]
91
63
10
21
29
28
13
70
52
39
2D Arrays of pixels = image
• Instead of ints, it would be better to think of a picture as a 2D
array of pixels:
RGB(255,0,0)
RGB(0,255,0)
RGB(0,0,255)
RGB(255,255,255)
RGB(128,128,128)
RGB(0,0,0)
RGB(255,255,0)
RGB(255,0,255)
RGB(0,255,255)
Pixel[][] data = {{RGB(255,0,0), RGB(0,255,0), RGB(0,0,255)},
{RGB(255,255,255), RGB(128,128,128), RGB(0,0,0)},
{RGB(255,255,0), RGB(255,0,255), RGB(0,255,255)}};
Row Major Representation
• So far, all 2D arrays shown have been in row major order.
• All of the data for the first row is stored before the next row
• int[][] array = {{41,38,91},{63,10,21},{29,28,13},{70,52,39}};
41
38
41
38
91
63
10
21
29
28
13
70
52
39
91
63
10
21
29
28
13
70
52
39
• There is also column major order
• You should assume all 2D arrays are row-major for our
course
• Inner arrays represent columns
Row vs. Column Major
int[][] rowM = {{1,2,3}, {4,5,6} };
int[][] colM = { {1,4}, {2,5}, {3,6} };
Enhanced for loops (for-each)
• When traversing an array of elements the typical
programming pattern is this:
• for(int n = 0; n < array.length; n++)
System.out.println(array[n]);
• This is equivalent syntax to:
• for(int item : array) //for each value in the array
System.out.println(item);
• This loop is a required pattern for our course
• Convenient but…
• Can only loop over every element exactly once
• Avoids missing an item or traversing past the end
Looping a 2D array
• Here is the typical programming pattern:
//the outer loop gets each internal array
//internal arrays = rows when row major order is used
for(int row = 0; row < array.length; row++)
{
//inner loop traverses internal array (a single row).
//Each entry in the row is accessed by its column location
for(int column = 0; column < array[0].length; column++)
{
//array[row][column] is the current element
}
}
• Or with an enhanced for loop (for-each):
for(int[] row : array)//get each internal array from the 2D array
{
for( int entry : row )//get each entry in the internal array
{
//entry is the equivalent to array[row][column] above
}
}
Summary of Operations
Exercise
• The Matrix class
• You will need to complete the skeleton code for the Matrix
class
• This is an exercise intended to help you become more familiar
with 2D arrays before we move on to image processing
• You must use enhanced for loops in your code
• Not every loop but some
• What follows are examples of how the methods in the Matrix
class work and a bit about the algebra of Matrices.
public Matrix(double[][] values)
• This will create a matrix with the given values
• Assume row major order
• For example, Matrix({{1,2},{3,4},{5,6}}) would initialize values_
to
• [1,2]
• [3,4]
• [5,6]
• DO NOT SIMPLY ASSIGN values_ = values;
• This creates a “shallow copy” which is shared by more than just
your object
• That means your object is not the only thing that can change
values_!
• Make a deep copy by creating a new 2D array and copying the
values
public int getRows() and getColumns()
• These accessor methods should tell the caller how many rows
and columns are contained in the Matrix
• Do not store these during construction
• Use the 2D array to retrieve the information
public String toString()
• returns a String representation of the Matrix
• For example, if values_ = {{1,2},{3,4},{5,6}};
• toString would return:
“[1\t2]\n[3\t4]\n[5\t6]”
[1 2]
[3 4]
[5 6]
• Other formats are possible as long as they make some similar
attempt at a pleasing visualization of the array
public Matrix scalar(double value)
• Scalar multiplication of a Matrix is when a number is
multiplied with the Matrix:
 1  1  1 2   1 2   1 2   1
2  0 0 0    2  0
2 0
2  0 
 1 2 3   2 1
2 2
2  3 
  2  2  2
  0
0
0 
 2
4
6 
• Your method should not alter the existing object, but instead
return a new Matrix that represents the scalar product
public Matrix add(Matrix m)
• Addition of two Matrices works as follows:
1 2 5 6 1  5 2  6  6 8 
3 4  7 8  3  7 4  8  10 12

 
 
 

• Your method should not alter any of the existing Matrices
involved in the addition but instead return a new Matrix that
is the resulting sum
• IMPORTANT!!!
• This only works if the two matrices have the same number of
rows and columns
• If they don’t have the same number of rows and columns this
operation is undefined
• return null;
public Matrix subtract(Matrix m)
• Subtraction of two Matrices works as follows:
1 2 5 6 1  5 2  6  4  4
3 4  7 8  3  7 4  8   4  4

 
 
 

• Your method should not alter any of the existing Matrices involved
in the subtraction but instead return a new Matrix that is the
resulting difference
• HINT: Think carefully, you’ve already done all of work needed for
subtraction
• IMPORTANT!!!
• This only works if the two matrices have the same number of rows
and columns
• If they don’t have the same number of rows and columns this
operation is undefined
• return null;
public Matrix multiply(Matrix m)
• When multiplying two Matrices it’s not as obvious how it
works…
• The row of the left matrix is multiplied on each column of the
right matrix.
3
6
• It works like this: 1 2 3
4
5
6

2
5
1
4
1x3+2x2+3x1
1x6+2x5+3x4
4x3+5x2+6x1
4x6+5x5+6x4
10
28
28
73


public Matrix multiply(Matrix m) cont’
• This will (likely) be the trickiest problem for you to solve
• Pre conditions (LM = left Matrix, RM = right Matrix)
• LM.columns = RM.rows
• LM.rows = RM.columns
• Return null if any of these fail
• The resulting Matrix will have:
• rows = LM.rows
• columns = RM.columns
• The method should return a new Matrix and not alter the existing ones
• One of the biggest challenges you may find is that a lot of tasks are
occurring at the same time in order to accomplish this in just one
method
• Good programmers break down difficult problems into manageable
sub problems
public Matrix multiply(Matrix m) cont’
• Suggested helper methods (not required)
• public double[] getRow(int r)
• Gets a single row from the Matrix and returns it as an array
• public double[] getColumn(int c)
• Gets a single column from the Matrix and returns it as an array
• public static double dotProduct(double[] row, double[] col)
• Remember, row.length == col.length or you should have returned
null
• You can now simply loop through each spot doing a product on the
value in the index and a sum of all products
• this method is (and should be) static because it does not access any
private member variables during execution (belongs to no particular
instance of the class)
public Matrix multiply(Matrix m) cont’
1
2
3
3
6
4
5
6
2
5
1
4
Left Matrix (left)
Right Matrix (right)
Now I can fill the example matrix like this (use a loop in your solution)
dotProduct(left.getRow(0), right.getColumn(0)) = 10
dotProduct(left.getRow(0), right.getColumn(1)) = 28
dotProduct(left.getRow(1), right.getColumn(0)) = 28
dotProduct(left.getRow(1), right.getColumn(1)) = 73
public Matrix transpose()
• Transposing a Matrix is the process of exchanging all rows and
columns:
• array[i][j]  array[j][i]
• It’s probably easiest to see in an example:
1
2
3
4
5
6

1
4
2
5
3
6
• Create a method to return a new Matrix which is the
transposed form of this
Solving systems of equations
• One of the major applications of Matrices is solving a system
of equations.
• For example, you may have encountered a math question like
this:
• 2x + 3y = 1
• x – y = –2
• We can think about this as three matrices:
• A coefficient matrix
• A variable matrix
• A constant matrix
2
3
x
1
1
–1
y
–2
Solving Systems of Equations
• Or as a mathematical expression:
2
3
1
–1
• So
x
y


x
y

1
–2
–1
2
3
1
–1

1
–2

–1
1
• x = –1 and y = 1
• In other words, the inverse of the coefficient matrix multiplied by
the constant matrix will give us the solution to the system
• I have written the solve method for you
• Write a main program that takes in the coefficients and constant
terms for a system of equations and solves it using our Matrix class