Help with image smoothing

Discussion in 'Mac Programming' started by jcmoney1010, Sep 29, 2012.

  1. jcmoney1010 macrumors newbie

    Joined:
    Sep 21, 2007
    #1
    alright so I'm taking a class in C and this weeks assignment has me pulling my hair out. The assignment is supposedly pretty basic, but I'm stuck on how to accomplish the last step.

    I need to take in user input which outputs a matrix of integers, then that matrix must be "smoothed" using a means filter to output a new matrix. Right now I have it to where I can take in the user input and output a matrix using randomly generated numbers, but i'm stumped as to how to accomplish this. PLEASE HELP!!

    Below is the original instructions:

    Write a program that will take as input an image, represented as a 2D array of pixel values (for simplicity, each pixel can be represented by an integer). Output the resulting smoothened image by applying the mean filter to every pixel in the array. Note that some pixels do not have 4 neighbors (for instance, pixels in the corners have only 2 neighbors; pixels in the top row and not in the corners have only 3 neighbors, and so on). Your program must take this into account and always use all available values but never use a non-valid (out of array) value.
     
  2. chown33, Sep 29, 2012
    Last edited: Sep 29, 2012

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    Break It Down.
    Start with the simplest case: a pixel not near an edge.

    So describe an algorithm, or write the code, that performs the action for exactly one non-edge pixel. It should be expressed in terms of a row-number R and a column-number C. Or if you prefer Cartesian terminology, in terms of a horizontal position X and a vertical position Y.

    If you can do the simplest case, then you will have accomplished the following:
    A. You will have a clear statement (in plain language or code) of exactly what calculations are needed for the mean of each non-edge pixel.
    B. You will also have a clear idea of how to express the position of the pixel being operated on, and each of the pixels that are its neighbors and contribute to the calculated result.
    C. You will know exactly how many pixels contribute to the calculated result.

    Conversely, if you are unable to describe an algorithm for one pixel, it suggests one or more of the following:
    1. You don't have a clear idea of how to express which pixels are neighbors of a given pixel.
    2. You don't have a clear idea of how to calculate a mean.
    3. You don't have a clear idea of how many pixels to use.

    To solve #1, I suggest drawing a diagram with a 3x3 pixel grid, and figure out how to express the neighbors of the central pixel. The expression will probably use terms like "current row", "current row minus one", "current column", "current column plus one", etc.

    To solve #2, look up the term "mean" on a simple reference like Wikipedia.

    To solve #3, refer to the 3x3 grid and count the neighbors of the center pixel.


    Once the problem is solved for a non-edge pixel, draw a 3x3 diagram and work out how to change it for one of the edge pixels. Finally, do the same thing for one of the corner pixels.

    Then write the loops that apply an appropriate single-pixel case to:
    a. All the non-edge pixels.
    b. All the edge-but-not-corner pixels.
    v. All the corner pixels.


    If it's still unclear how to proceed, please explain exactly where you're stuck.
     
  3. jcmoney1010, Sep 29, 2012
    Last edited: Sep 29, 2012

    jcmoney1010 thread starter macrumors newbie

    Joined:
    Sep 21, 2007
    #3
    I guess my issue is a syntactical one. Instead of it outputting a new smoothed image or matrix, all its doing is reprinting the same matrix over again.

    Heres what I have right now

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <time.h>
    void fillArray(int a[10][20], int m, int n)
    {
          int random;
          int i,j;   
              for (i=0;i<m;i++)
              {
                  for (j=0;j<n;j++)
                  {
                                   random=rand()%100;
                                   a[i][j]=random;
                                   }
                                   }
    }
    
    void printarray (int a[10][20], int m, int n)
    {
         int i,j;
        for (i=0;i<m;i++) 
        {
            for (j=0;j<n;j++)
                {
                             printf("%4d", a[i][j]);
                             }
                             printf("\n");
                             }
    }
    
    void smooth (int a[10][20], int m, int n)
    {
         b[10][20];
         int i,j,x,y;
         for (i=0;i<m;i++) 
        {
            for (j=0;j<n;j++)
            {
                b[i][j]=(a[i-1][j]+a[i][j-1]+a[i+1][j]+a[i][j+1])/4;
                printf("%4d",a[i][j]);
                }
                printf("\n");
    }
    }
    int main()
    {
        
     int a[10][20];
     int m,n;
     srand(time(NULL));
     printf("please enter number of columns and rows");
     scanf("%d %d", &m,&n);
     fillArray(a,m,n);
     printarray (a,m,n);
     printf("The smoothed image is\n");
     smooth(a,m,n);
    getch();
    return 0;
    }
    
    
     
  4. chown33, Sep 29, 2012
    Last edited: Sep 29, 2012

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    1. Post the results.
    2. Explain why you think they're weird.


    EDIT

    You may or may not be aware of it, but the posted code is not complying with the bold part of the problem statement:
    Write a program that will take as input an image, represented as a 2D array of pixel values (for simplicity, each pixel can be represented by an integer). Output the resulting smoothened image by applying the mean filter to every pixel in the array. Note that some pixels do not have 4 neighbors (for instance, pixels in the corners have only 2 neighbors; pixels in the top row and not in the corners have only 3 neighbors, and so on). Your program must take this into account and always use all available values but never use a non-valid (out of array) value.
    In short, your code fails for all edge and corner pixels, because it references pixels which are outside the valid bounds. The simplest example of this is the filtering of the first row (row 0). For the entire row, the expression i-1 will be -1, which is invalid.

    This isn't necessarily the only error in the code. Which is one reason I need you to explain exactly what "weird" means, by posting your data and explaining what you expected to happen.
     
  5. jcmoney1010 thread starter macrumors newbie

    Joined:
    Sep 21, 2007
    #5
    When the program starts, it asked for the user to enter columns and rows. if you enter say 3 and 3 it will output the first random number matrix

    ex.
    12 45 6
    34 3 23
    11 56 90

    then when it prints out the "smoothed" matrix it comes out like this:

    123569879008766
    45 2367890
    9298470753498594553

    basically my intended results were to work on calculating the mean for numbers with 4 neighbors first, and then after I discovered the right way to do that I would move on to working on the edge integers.

    thats what my intentions were for this line of code, but again I may have butchered it and thats why it isn't working correctly.

    Code:
    b[i][j]=(a[i-1][j]+a[i][j-1]+a[i+1][j]+a[i][j+1])/4
    this is very frustrating because up until this week when we started working on arrays, this class was a breeze. I appreciate your help and patience
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    Your printf() is using the format "%4d". Think about what happens when the value being printed is 4 digits or more. You may need to consult the printf reference doc (i.e. its man page or builtin Xcode doc) in order to do this. Or write a test program where you print out numbers from 990 to 1010 using "%4d".

    If you can't figure it out from that, try rethinking what you want the output to be: a number preceded by a space. What is a format string that will produce that?


    Your second issue is that you're seeing out-of-range numbers, i.e. numbers that exceed 100, precisely because your code is calculating means using invalid array locations. If you refer to a row that doesn't exist, because the first calculations uses -1 as one of the rows, then what do you think you'll get? Invalid values.

    So change your basic code so it only calculates the means for pixels that occupy the central non-edge region. That means the first row to have means calculated for it will be row 1, not row 0. You will also have to avoid column 0 and the last column, for every row. Also avoid the last row.

    Reread my first post, and figure out what the valid central region of a 3x3 array is. Then figure it out for a 4x4 and 4x10 array.


    Again, these are not the only errors in your code. But if you solve these, the cause of some other errors may become plain.
     

Share This Page