0

I have this code that implements Prewitt edge detection. What I need to do is to implement it with only one buffer, meaning, I will not create copy of the image but edit original image. So if i want to change pixel with value 78, I cant put the new value e.g. 100 until all surrounding pixels have read value 78. Color values of the pixels. I have tried all day to figure it out but couldn't, if someone would write me some kind of pseudocode I would be very grateful

void filter_serial_prewitt(int *inBuffer, int *outBuffer, int width, int height){
   for (int i = 1; i < width - 1; i ++) {
     for (int j = 1; j < height - 1; j ++) {
        int Fx = 0;
        int Fy = 0;
        int F = 0;
        for (int m = -1; m <= 1; m++) {
            for (int n = -1; n <= 1; n++) {
                Fx += inBuffer[(j + n) * width + (i + m)] * n;
                Fy += inBuffer[(j + n) * width + (i + m)] * m;
            }
        }
            F = abs(Fx) + abs(Fy);

            if (F < THRESHOLD){
                outBuffer[j * width + i] = 255;
            } else{
                outBuffer[j * width + i] = 0;
            }
       }
   }
}
Web_Designer
  • 72,308
  • 93
  • 206
  • 262
Torima
  • 157
  • 2
  • 13
  • Why do you need to do it with only 1 buffer? Not every image processing technique can be done in-place, and many are more efficient if you can break them into multiple passes (especially certain types of convolutions). One alternative is to use a buffer that's only a few lines long instead of an entire second image. Is that an acceptable answer? – user1118321 Dec 23 '16 at 23:48
  • @user1118321 Well I know it's lot easier and better with two buffers but that's the point of my assignment. Only edit original image. Well I would probably need some buffer for keeping the values until they can replace original ones, but as I said, I have no idea how to do it. I have to do it in serial and parallel way if that changes anything.. – Torima Dec 23 '16 at 23:58

1 Answers1

1

One thing to know about a Prewitt operator is that it is separable. See the Wikipedia article for details.

To calculate a single output row, you need to do the following (pseudocode):

int* buffer = malloc (sizeof(int) * width);
for (int i = 0; i < width; i++)
{
    // Do the vertical pass of the convolution of the first 3 rows into
    // the buffer.
    buffer [ i ] = vertical_convolve(inBuffer [ i ], vertical_kernel);
}

// Next, do the horizontal convolution of the first row. We need to 
// keep the previous value in a temp buffer while we work
int temp0 = horizontal_convolve(buffer [ 0 ], horizontal_kernel);
for (int i = 1; i < width; i++)
{
    int temp1 = horizontal_convolve(buffer[ i ], horizontal_kernel);
    inBuffer [ i - 1 ] = temp0;
    temp0 = temp1;
}

That requires a buffer that is 1 pixel tall and the width of the image.

To work on the whole image, you need to keep 2 of the above buffers around and after you calculate a pixel on the third line, you can replace the first pixel of the first line of the image with the first pixel of the first buffer. Then you can put the newly calculated value into the buffer.

So in this scenario, you won't keep around an entire second image, but will need to keep around 2 1-pixel tall buffers that are as wide as the image.

user1118321
  • 25,567
  • 4
  • 55
  • 86