Solved

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

Posted on 2002-07-24
16
235 Views
Last Modified: 2012-06-21
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


0
Comment
Question by:Guster
  • 11
  • 5
16 Comments
 
LVL 16

Expert Comment

by:imladris
ID: 7175746
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?

0
 

Author Comment

by:Guster
ID: 7175860
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
0
 

Author Comment

by:Guster
ID: 7175894
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??
0
 
LVL 16

Expert Comment

by:imladris
ID: 7177576
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.
0
 

Author Comment

by:Guster
ID: 7178171
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
 





0
 

Author Comment

by:Guster
ID: 7178176
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
0
 

Author Comment

by:Guster
ID: 7178206
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
0
 
LVL 16

Expert Comment

by:imladris
ID: 7178396
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.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:Guster
ID: 7178552
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
0
 

Author Comment

by:Guster
ID: 7178555
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.
0
 
LVL 16

Expert Comment

by:imladris
ID: 7178605
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?

0
 

Author Comment

by:Guster
ID: 7178687
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
0
 

Author Comment

by:Guster
ID: 7178704
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??
0
 

Author Comment

by:Guster
ID: 7179947
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
0
 
LVL 16

Accepted Solution

by:
imladris earned 50 total points
ID: 7180326
The median value for a sorted array would be in its middle. The middle can be calculated based on its length. For an even array there isn't an exact middle. I don't think you should get the two middle and divide by 2 if you want a median. One of the key differences between a median and an average is precisely that a median *is* one of the datapoints.

Anyway, the medianindex can be computed with:

int medianindex=value.length/2;

For an odd length array, this will give you the middle. For an even length array, it will give you the value to the "right" of the middle. To get the "left" one you could subtract one, if the array is even length (value.length%2==0). Code would be something like:

int medianindex=value.length/2+(value.length%2==0?-1:0);


If you must average the two you could get them both and divide. In total it could then look something like this to get the median:

int median;
if(value.length%2==0)
{   // even length case
    int ix=value.length/2;
    median=(value[ix-1]+value[ix])/2;
}
// odd length case
else median=value[value.length/2];

0
 

Author Comment

by:Guster
ID: 7180343
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
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Starting to learn JAVA, 7 59
eclipse formatting 6 70
micro services spring boot application error 3 139
what is a "java.lang.System Property"   ? 20 56
For beginner Java programmers or at least those new to the Eclipse IDE, the following tutorial will show some (four) ways in which you can import your Java projects to your Eclipse workbench. Introduction While learning Java can be done with…
Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:

930 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now