26
The Picture Lab Manipulating 2D arrays in Java

The Picture Lab Manipulating 2D arrays in Java. RGB colors Colors are typically represented by their components in red, green, and blue Each component

Embed Size (px)

Citation preview

The Picture LabManipulating 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

• How do you create:• White Gray Black

• How do you create:• Cyan Magenta Yellow

• 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

63

2813

2129

913841

10

705239

array[0][1]

array[1][0]

array[1][1]

array[0][0]

array[0][2]

array[2][0]

array[2][2]

array[3][0]

array[1][2]

array[2][1]

array[3][1]

array[3][2]

// A 2D array with 4 rows, // 3 columns, 12 elements

0 1 2

0 41 38 911 63 10 212 29 28 133 70 52 39

Row Index

Col Index

int[][] array = { {41,38,91}, {63,10,21},

{29,28,13}, {70,52,39}};

int[][] array = {{41,38,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}};

• There is also column major order• You should assume all 2D arrays are row-major for our course• Inner arrays represent columns

41 38 91 63 10 21 29 28 13 70 52 39

41 38 91

63 10 21

29 28 13

70 52 39

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 usedfor(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

locationfor(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

• 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 String toString()

public Matrix scalar(double value)

• Scalar multiplication of a Matrix is when a number is multiplied with the Matrix:

• Your method should not alter the existing object, but instead return a new Matrix that represents the scalar product

642

000

222

322212

020202

121212

321

000

111

2

public Matrix add(Matrix m)

• Addition of two Matrices works as follows:

• 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;

1210

86

8473

6251

87

65

43

21

public Matrix subtract(Matrix m)

• Subtraction of two Matrices works as follows:

• 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;

44

44

8473

6251

87

65

43

21

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.

• It works like this: 1 2 3

4 5 6

3 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

4 5 6

3 6

2 5

1 4Left 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)) = 10dotProduct(left.getRow(0), right.getColumn(1)) = 28dotProduct(left.getRow(1), right.getColumn(0)) = 28dotProduct(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:

• Create a method to return a new Matrix which is the transposed form of this

1 2 3

4 5 6 1 4

2 5

3 6

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

1 –1

x

y

1

–2

Solving Systems of Equations

• Or as a mathematical expression:

• So

• 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

2 3

1 –1

x

y

1

–2

x

y

2 3

1 –1 1

–2

–1

–1

1