Я пытаюсь применить алгоритм фильтра sobel к заданному изображению (в данном случае в оттенках серого), учитывая мой подход к доступу к пикселям изображения. Поскольку я обращаюсь к ним способом, который не использует библиотеки, у меня возникают проблемы с выяснением того, как применить алгоритм с учетом этого подхода. Эта первая часть кода просто обращается к пиксельным данным:
Часть 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;
Часть 2 (Фактическое применение алгоритма фильтра sobel):
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
}
}
}
Любая помощь очень ценится.
Вы должны использовать соответствующий пиксель из окрестности центрального пикселя для умножения на вход в ядро:
//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;
}
}
Я опустил границы пикселей
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;
}
}
}