Link to home
Start Free TrialLog in
Avatar of Guster
Guster

asked on

Copying values from a 2D Array to a 1D Array

Hi,

I'm trying to copy values from a 2D template to a 1D array. I want to put these values in a 1D Array so that I can sort them and then get the median value. Below is the program I'm trying to do it in. Would anyone know how to do this?

import iptoolkit.*;
import uuPack.*;

class Methods2 {
     
public IntImage imageOut = new IntImage(256,256);
     
final int ImageSize = 256;
final int MaxGreyLevel = 255;
final int MinGreyLevel = 0;
     
//constructor method
public Methods2 () {
     
MainWindow mw = new MainWindow();
         
}//Methods2
     
     
//display image on screen
public void display (IntImage imageIn, IntImage imageOut) {
       
imageOut.setScaling(false);
imageIn.displayImage();
imageOut.displayImage();
       
}//display


  public void filter(IntImage imageIn, int[][] template, IntImage imageOut) {
       
       
  IntImage src = new IntImage(ImageSize, ImageSize);
  src = imageIn;
       
  int nMaskRows = template.length;
  int nMaskCols = template[0].length;
       
  int rBorder = nMaskRows / 2;  // integer division
  int cBorder = nMaskCols / 2;
  int sum;
  int[] copy = new int[];

       
  for (int r = 0; r < (ImageSize - nMaskRows + 1); r++) {
   for (int c = 0; c < (ImageSize - nMaskCols + 1); c++) {
     sum = 0;
       for (int mr = 0; mr < nMaskRows; mr++) {
        for (int mc = 0; mc < nMaskCols; mc++) {

THE NEXT TWO LINES ARE WHAT I WAS THINKING OF PUTTING IN HERE BUT ITS NOT WORKING
        for (int i = 0; i < (nMaskRows*nMaskCols); i++) {
                 copy[i] = imageIn.pixels[r+mr][c+mc];
                     
        }//for i
                   
        }//for mc
        }//for mr
             
             
 }//forc
}//forr
         
display(imageIn, imageOut);
         
}//filter
 
}//Methods2

Regards,
Guster


Avatar of imladris
imladris
Flag of Canada image

HMMmm. It would probably be helpful if you described the problem in a bit more detail. Is it a compile error? Or a runtime error? If so, what is the stack trace?

At present I am concerned about this line:

int [] copy=new int[];

That doesn't seem like legal code.
I'm also wonder why, given an image with pixels in a 2D structure, there are 4 nested for loops for getting it out. Shouldn't 2 nested for loops be sufficient?

Avatar of Guster
Guster

ASKER

Hi,

What I'm trying to do is perform edge preserving smoothing using a median filter. The first set of for loops is for going over every pixel of the image with a template (say 3x3). The second set of for loops is for going through each pixel in the template itself. For each iteration of the template I want to read the values of each pixel in the template into a 1D Array so that I can sort the values and then get the median value.
When I try to compile the above program I get an error message pointing to that line 'int[] copy = new int[]' and it says that a '}' is expected?? Is this not a legal way to declare aa array??

Below is the main class where I would call the filter method:

import iptoolkit.*;

public class Test1 {
     
public static void main (String args[]) {
         
  Methods1 method = new Methods1();
         
  String imageDir = "C:/Java_Programs/image_prac/";
  IntImage image = new IntImage(imageDir + "Morse8.raw", 256, 256);
  IntImage image1 = new IntImage(256, 256);
  int[][] temp = { {1, 1, 1},
                {1, 1, 1},
                {1, 1, 1} };
         
         
  //method.convolve(image, temp, image1);
  //image.displayImage();
  method.filter(image, temp, image1);
         
     }

     
} // Test1

Regards,
Guster
Avatar of Guster

ASKER

Hi again,

I changed the line to:
  int[] copy = new int[nMaskRows*nMaskCols];

The program compiles without any errors now but I'm thinking that the lines:

  for (int i = 0; i < (nMaskRows*nMaskCols); i++) {
     copy[i] = imageIn.pixels[r+mr][c+mc];

will simply add the value of the first number in the template to each cell in the array and then it will do the same for the second value of the template and so on.
How can I get the array to hold each of the successive template values together??
Well, that's progress at least. So there was a compiler error and it has been resolved. Now you are looking for assurance you are getting the result you want.

However, I'm not clear on what you're after. Perhaps an example would clarify things. Suppose the beginning of the image lines are:

1, 50, 25, 30, 3, ......
2, 52, 30,  3, 25, .....
1, 53, 33, 30, 5, ......

and the template is the 3x3 ones matrix in your last example, what would you expect to find in your 1D array? Feel free to use different numbers if you think it would be helpful.
Avatar of Guster

ASKER

Hi,

Say I'm running the template over the nine values:

1, 50, 25
2, 52, 30
1, 53, 33

I want to have each of those values in its corresponding cell in the template so that I can calculate the median. To get this I'm going to multiply each '1' value in each cell of the template by the corresponding value in the image. I haven't done this yet in the program as I was just concentrating on getting values in the template into a 1D Array.

I've been able to put the values into a 1D Array successfully. This is shown below. I have also sorted the array values, so now I'm trying to work out how to get the median value from the sorted list(I have what I've done on this so far below as well).

int[] copy = new int[nMaskRows*nMaskCols];
int b;
int x = 0;
int median;

       
  //for (int r = 0; r < (ImageSize - nMaskRows + 1); r++) {
  //for (int c = 0; c < (ImageSize - nMaskCols + 1); c++) {
  //sum = 0;
         
for (int mr = 0; mr < nMaskRows; mr++) {
  for (int mc = 0; mc < nMaskCols; mc++) {
      b = template[mr][mc];
      copy[x] = b;
      ++x;
  }//for mc
}//for mr


for (int ib = 0; ib < x ; ib++)
    {
      System.out.println("This is pixel number " + (ib + 1)+ ", its value is " + copy[ib]);
    }

sort(copy);
for (int ic = 0; ic < copy.length; ic++)
    {
      System.out.println("The sorted pixel value is " + copy[ic]);
    }
median(copy);
       
}//filter
     
         
public static int [] sort(int [] prob){

  int temp;
  int max;
         
for( int index = 0; index < prob.length - 1; index++){
               
  max = index;
               
  for( int scan = index + 1; scan < prob.length; scan++)
    if(prob[scan] > prob[max])
     max = scan;
     temp = prob[max];
     prob[max] = prob[index];
     prob[index] = temp;
                         
  }
     
return prob;
         
}//sort


public void median(int[] values) {
         
  int number = values.length;
  int med = 0;
         
for( int i = 0; i < number; i++){
   if(values[i] == number/2)
      med = values[i] + 1;
}
System.out.println("The median of the list is : " + med);
         
}//median


My median method isn't correct as it's just returning the half the value of the length of the array as opposed to the actual value in the middle cell. Do you know how I could fix this??

Guster
 





Avatar of Guster

ASKER

Hi again,

When I'm doing the sorting and trying to get the median value I'm using different values in the template instead of all the 1's, say:

2, 6, 4
3, 9, 1
7, 5, 8


Guster
Avatar of Guster

ASKER

Hi,

Ive been trying a certain way of calculating the median value of a list. It is shown below:


public int getMax(int[] values){
    //Iterator it = values.iterator();
  int max = 0;//((Integer) it.next()).intValue();
  for (int i = 0; i < values.length; i++) {
    if(values[i]>max) {
       max=values[i];
    }    
  }
  return max;
}//getMax
     
     
public int[] removeMax(int[] values){
  int max = getMax(values);
    //Iterator it = values.iterator();
  for (int i = 0; i < values.length; i++) {
    if(values[i] == max){
       values[i].remove();
       return values;
    }
  }
    return values;//never reaches this point as values contains a max
}//removeMax
     
     
public int getMedian(int[] values){
 int median;
 if(values.length/2 == (values.length+1)/2){//if even number of elements
    for(int i=0;i<(values.length -1)/2;++i){
        removeMax(values);
    }
      median = getMax(values);//median is mean of two central values
      removeMax(values);
      median = median + getMax(values);
      median = median/2;//mean of x,y is (x+y)/2
    }else{//if odd number of elements
      for(int i=0;i<values.length/2;++i){
     removeMax(values);
      }
      median = getMax(values);//median is central value
    }
    return median;
}//getMedian


The only error that I'm getting when I compile the program is an error saying 'int[] cannot be dereferenced' because of the line 'values[i].remove();'.
How can I delete a value from the list without it saying that it can't be dereferenced??

Regards,
Guster
Guster,

in order to help I need to be very clear on what you are attempting to accomplish. An example would be best. You have shown a couple more matrixes, but what I am still unclear on is what result you expect in the 1D array.

Suppose the image values are:

1, 50, 25
2, 52, 30
1, 53, 33

and the template is

2, 6, 4
3, 9, 1
7, 5, 8


what will be in the 1D array? Please provide a list of numbers.
Avatar of Guster

ASKER

Hi,

What I want to accomplish is to move a template over every pixel in an image but the template doesn't actually have any values in it. It uses the corresponding pixel values in the image. Say for an image that has the values:

2, 6, 4
3, 9, 1
7, 5, 8

When the template moves over these I want the template to pick up these values, hence these values will go into the 2D Array. I then want to get the median of these values, so I want to put them into a 1D Array so that I can sort them and pick out the median value. Once I have the median value I want to output this in an output image. This will be performed on every pixel in the image to smooth it.

When I was using the example of the matrix above, I was just assigning these examples to the template to use for practice in sorting the array. In reality I want to pick up the values from the input image.

Guster
Avatar of Guster

ASKER

The result in the ID Array from the above template after sorting it would be:

1, 2, 3, 4, 5, 6, 7, 8, 9

I then want to pick the median value which is 5.
OK, it appears to be a two step process then. You have an image, which is a collection of values in a 2D array. Then you use the template to alter these values in some fashion and the result is again an image which is a 2D array. Finally you transform the 2D array into a 1D array, and find the median. So I would envision something like (this does averages with the 3x3 template):


int i,j,k,l;
int ix1,ix2;

// First create a new image using the original and
   the template
for(i=0; i<rows; ++i)
{   for(j=0; j<cols; ++j)
    {   imageOut.pixels[i][j]=0; // initialize out pixel
        for(k=0; k<=trow; ++k)
        {   for(l=0; l<tcol; ++l)
            {   ix1=i+(k-1);
                ix2=j+(l-1);
                // add surrounding pixels from original
                // multiplied by template value
                if(ix1>=0 && ix2>=0 && ix1<rows && ix2<cols)
                    imageOut.pixels[i][j]+=imageIn.pixels[ix1][ix2]*template[k][l];
            }
        }
        // average resulting value
        imageOut.pixels[i][j]/=9;
    }
}

// Now convert imageOut from 2D to 1D array
int copy[]=new int[rows*cols];
for(i=0; i<rows; ++i)
{   for(j=0; j<cols; ++j)
    {   copy[i*cols+j]=imageOut.pixels[i][j];
    }
}


As you can see every row of the out image is copied into the copy array. Each row starts at i times the number of columns (e.g. row 0 would begin at 0, row 1 at index cols, row 2 at index cols*2 etc.).
Then sort the array, and pick the middle value.

Does that help?

Avatar of Guster

ASKER

That looks good, but how do I pick the middle value from a ID Array of values? Say the array contains 9 values how would I pick out the middle value?? And if I want to get the median for an array that has an even number of values I need to add the two middle values and divide by two, how would I do this?? This is the bit I'm stuck on at the minute

Guster
Avatar of Guster

ASKER

Hi,
 
I think I got it for an odd numbered array. Is it simply something like:

if(values.length == 9) {
   med = values[4];
   System.out.println("The median of the list is : " + med);
}

and so on for the odd numbered templates??
Avatar of Guster

ASKER

Hi,

In my program there's a possibility of the template being different sizes i.e. 5x5, 7x7, 9x9 etc. How could I calculate the median of the array without having to write 'if(values.length == 25)' and 'if(values.length == 49)' etc??

Regards,
Guster
ASKER CERTIFIED SOLUTION
Avatar of imladris
imladris
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Guster

ASKER

Hi,

In my program there's a possibility of the template being different sizes i.e. 5x5, 7x7, 9x9 etc. How could I calculate the median of the array without having to write 'if(values.length == 25)' and 'if(values.length == 49)' etc??

Regards,
Guster