3

I am trying to apply the sobel filter algorithm to a given picture (grayscale in this case) given my approach to accessing the pixels of the picture. Since I am accessing them in a way that doesn't use libraries, I am having trouble figuring out how to apply the algorithm given this approach. This first part of the code is just accessing pixel data:

Part 1:

CKingimageDoc* pDoc = GetDocument();      // get picture

int iBitPerPixel = pDoc->_bmp->bitsperpixel;    // used to see if grayscale(8 bits) or RGB (24 bits)
int iWidth = pDoc->_bmp->width;
int iHeight = pDoc->_bmp->height;
BYTE *pImg = pDoc->_bmp->point;     // pointer used to point at pixels in the image
const int area = iWidth * iHeight;

int Wp = iWidth;
int intensity;

if (iBitPerPixel == 8)  ////Grayscale 8 bits image
{
    int r = iWidth % 4;     // pixels leftover from width (remainder has to be factor of 8 or 24)
    int p = (4-r) % 4;      // has to be a factor of number of bits in pixel, num leftover to take care of
    Wp = iWidth + p;

Part 2 (The actual application of the sobel filter algorithm):

    float kernelx[3][3] = { { -1, 0, 1 },
    { -2, 0, 2 },
    { -1, 0, 1 } };

    float kernely[3][3] = { { -1, -2, -1 },
    { 0,  0,  0 },
    { 1,  2,  1 } };

    double magX = 0.0; // this is your magnitude

    for (int a = 0; a < 3; a++) {
        for (int b = 0; b < 3; b++) {
            magX += pImg[i*Wp + j] * kernelx[a][b];   // where i get confused
        }
    }
}

Any and all help is greatly appreciated.

evanhaus
  • 727
  • 3
  • 12
  • 30

2 Answers2

1

You have to use appropriate pixel from neighborhood of center pixel to multiply with kernel entry:

//row, col - coordinates of central pixel for calculation
for (int row = 1; row < height - 1; row++) {
    for (int col = 1; col < width - 1; col++) {
        double magX = 0.0; // this is your magnitude

        for (int a = 0; a < 3; a++) {
            for (int b = 0; b < 3; b++) {
                magX += pImg[(row - 1 + a) * Wp + col - 1 + b] * kernelx[a][b];   
            }
        }
        resultImg[row * Wp + col] = magX;  
   }
}

I omitted border pixels

MBo
  • 77,366
  • 5
  • 53
  • 86
  • And for the border pixels is that where I set it to 255 if its greater than 255 and 0 if its below 0? – evanhaus Jul 12 '17 at 19:14
  • Border pixels - first and last column, first and last row. 0/255 - saturation issue - should be applied everywhere – MBo Jul 13 '17 at 03:12
0
CKingimageDoc* pDoc = GetDocument(); // get picture

int iBitPerPixel = pDoc->_bmp->bitsperpixel; // used to see if grayscale(8b) or RGB(24b)
int iWidth = pDoc->_bmp->width;
int iHeight = pDoc->_bmp->height;
BYTE *pImg = pDoc->_bmp->point; // pointer used to point at pixels in the image
const int area = iWidth * iHeight;
BYTE *pImg2 = new BYTE[area];

if (iBitPerPixel == 8) // Grayscale 8bit image
{
    int pixel_x;
    int pixel_y;

    float sobel_x[3][3] =
    { { -1, 0, 1 },
      { -2, 0, 2 },
      { -1, 0, 1 } };

    float sobel_y[3][3] =
    { { -1, -2, -1 },
      { 0,  0,  0 },
      { 1,  2,  1 } };

    for (int x=1; x < iWidth-1; x++)
    {
        for (int y=1; y < iHeight-1; y++)
        {

            pixel_x = (sobel_x[0][0] * pImg[iWidth * (y-1) + (x-1)])
                    + (sobel_x[0][1] * pImg[iWidth * (y-1) +  x   ])
                    + (sobel_x[0][2] * pImg[iWidth * (y-1) + (x+1)])
                    + (sobel_x[1][0] * pImg[iWidth *  y    + (x-1)])
                    + (sobel_x[1][1] * pImg[iWidth *  y    +  x   ])
                    + (sobel_x[1][2] * pImg[iWidth *  y    + (x+1)])
                    + (sobel_x[2][0] * pImg[iWidth * (y+1) + (x-1)])
                    + (sobel_x[2][1] * pImg[iWidth * (y+1) +  x   ])
                    + (sobel_x[2][2] * pImg[iWidth * (y+1) + (x+1)]);

            pixel_y = (sobel_y[0][0] * pImg[iWidth * (y-1) + (x-1)])
                    + (sobel_y[0][1] * pImg[iWidth * (y-1) +  x   ])
                    + (sobel_y[0][2] * pImg[iWidth * (y-1) + (x+1)])
                    + (sobel_y[1][0] * pImg[iWidth *  y    + (x-1)])
                    + (sobel_y[1][1] * pImg[iWidth *  y    +  x   ])
                    + (sobel_y[1][2] * pImg[iWidth *  y    + (x+1)])
                    + (sobel_y[2][0] * pImg[iWidth * (y+1) + (x-1)])
                    + (sobel_y[2][1] * pImg[iWidth * (y+1) +  x   ])
                    + (sobel_y[2][2] * pImg[iWidth * (y+1) + (x+1)]);

            int val = (int)sqrt((pixel_x * pixel_x) + (pixel_y * pixel_y));

            if(val < 0) val = 0;
            if(val > 255) val = 255;

            pImg2[iHeight * y + x] = val;
        }
    }
}
Khaled.K
  • 5,828
  • 1
  • 33
  • 51
  • 1
    -2 at for loops should be -1, multiply with `iHeight` should be multiply with `iWidth`, and there is a missing +1 at the one before the last tag in the calculation of pixel_y. – geza Jul 12 '17 at 11:42
  • @geza notes fixed now. – Khaled.K Jul 12 '17 at 15:54