Reputation: 227
I have a 2D array which consist of image pixels which its size depends on the size of the input image. I need to break it into smaller 9x9 arrays. To give a clearer picture, I try to illustrate the situation:
//The number of rows and columns of the smallerArray will look something like this: It should copy them from the imagePixels array iterating through each 8 columns, then move on to the next 8 rows.
1st small 2nd small 3rd small and so on..
array: array: array:
012345678 91011121314151617 181920212223242526 ....
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
Then move on to next 8 rows:
012345678 91011121314151617 181920212223242526 ....
9 9 9
10 10 10
11 11 11
12 12 12
13 13 13
14 14 14
15 15 15
16 16 16
17 17 17
.
.
.
I have done the following code but could not get my logic right. How can I stop the iteration:
Copy up until the 9th column or row, store it in an array, resume copying on the 10th column/row, stop when it reaches 9 column/row after, store it in another array, and keep on doing that till it finishes copying the imagePixels array.
I tried to store the arrays in an ArrayList so it would be easier for me to manipulate and do calculation stuffs with all the smallerArrays.
ArrayList<double[][]> collectionofSmallArrays = new ArrayList();
double[][] imagePixels = new double[1600][1000]; //Lets say this is the size of the image
double[][] smallerArray = new double[9][9];
for(int a = 0; a<smallerArray.length; a++)
{
for(int b =0; b<smallerArray[a].length; b++)
{
for(int c=0; c<imagePixels.length; c++)
{
for(int d=0; d<imagePixels[c].length; d++)
{
smallerArray[a][b] = imagePixels[c][d];
...(code to stop the iteration if it reaches 9, store it in array then resume where it stops with another new array)
collectionofSmallArrays.add(smallerArray);
}
}
}
}
Can anyone work around the code to achieve the expected result? Appreciate it.
Upvotes: 1
Views: 1906
Reputation: 599
smallerArray
. Create the instance inside the for loop and store the size in a constant.Upvotes: 0
Reputation: 54659
You should probably provide more context information. Saying that an array of double
values represents pixels sounds dubios. If you are working with images, then you might find solutions on a completely different level of abstraction (I'm thinking about BufferedImage#createSubImage here).
However, to answer the question: You should break the task up into smaller parts. Particularly, it might be easier to implement two methods:
In pseudocode:
for (each coordinates (9*r,9*c)) {
copy the rectange (9*r,9*c)-(9*r+9,9*c+9) of the input array into an array
A very simple implementation/test is shown in the following example. Note that this could be generalized and improved, but I think it shows the basic idea:
import java.util.ArrayList;
import java.util.List;
public class SubArrayTest
{
public static void main(String[] args)
{
double inputArray[][] = createInputArray(160, 100);
System.out.println("inputArray: "+toString(inputArray));
List<double[][]> subArrays = createSubArrays(inputArray, 9, 9);
for (double subArray[][] : subArrays)
{
System.out.println("subArray:\n"+toString(subArray));
}
}
private static List<double[][]> createSubArrays(
double inputArray[][], int subRows, int subCols)
{
List<double[][]> subArrays = new ArrayList<double[][]>();
for (int r=0; r<inputArray.length; r+=subRows)
{
for (int c=0; c<inputArray[r].length; c+=subCols)
{
double subArray[][] = new double[subRows][subCols];
fillSubArray(inputArray, r, c, subArray);
subArrays.add(subArray);
}
}
return subArrays;
}
private static void fillSubArray(
double[][] inputArray, int r0, int c0, double subArray[][])
{
for (int r=0; r<subArray.length; r++)
{
for (int c=0; c<subArray[r].length; c++)
{
int ir = r0 + r;
int ic = c0 + c;
if (ir < inputArray.length &&
ic < inputArray[ir].length)
{
subArray[r][c] = inputArray[ir][ic];
}
}
}
}
//===Test methods=========================================================
private static double[][] createInputArray(int rows, int cols)
{
double array[][] = new double[rows][cols];
for (int r=0; r<array.length; r++)
{
for (int c=0; c<array[r].length; c++)
{
array[r][c] = r*100+c;
}
}
return array;
}
private static String toString(double array[][])
{
String format = "%7.1f";
StringBuilder sb = new StringBuilder();
for (int r=0; r<array.length; r++)
{
for (int c=0; c<array[r].length; c++)
{
sb.append(String.format(format, array[r][c])+" ");
}
sb.append("\n");
}
return sb.toString();
}
}
Side notes:
You should always declare variables with their interface type. This means that you should not write
ArrayList<String> x = new ArrayList<String>();
but always
List<String> x = new ArrayList<String>();
In the posted code, you seemed to always add the same instance of the sub-array to the list. This means that in the end you would have many instances of the same array in the list, all with the same content. Somewhere in between you have to create a new double[9][9]
array.
Upvotes: 1
Reputation: 20544
smallerArray[a][b] = imagePixels[c][d]
line looks strange. You reuse same array instance. Your output array list will contain multiple reference to same array.
Upvotes: 0