我正在尝试为灰度 bmp 图像制作卷积算法。下面的代码来自 Udemy 上的图像处理课程,但是关于使用的变量和公式的解释有点短。问题出在二维离散卷积部分,我无法理解此处实现的公式
struct Mask{
int Rows;
int Cols;
unsigned char *Data;
};
int main()
{
int imgWidth, imgHeight, imgBitDepth;
unsigned char imgHeader[BMP_HEADER_SIZE];
unsigned char imgColorTable[BMP_COLOR_TABLE_SIZE];
unsigned char imgBuffer[CUSTOM_IMG_SIZE];
unsigned char imgBuffer2[CUSTOM_IMG_SIZE];
const char imgName[] = "images/cameraman.bmp";
const char newImgName[] = "images/cameraman_new.bmp";
struct Mask lpMask;
signed char *tmp;
int i;
lpMask.Cols = lpMask.Rows = 5;
lpMask.Data = (unsigned char *)malloc(25);
/* -1 -1 -1 -1 -1
-1 -1 -1 -1 -1
-1 -1 24 -1 -1
-1 -1 -1 -1 -1
-1 -1 -1 -1 -1*/
//set all mask values to -1
tmp = (signed char *)lpMask.Data;
for (i = 0; i < 25; ++i)
{
*tmp = -1;
++tmp;
}
//set middle value to 24
tmp = (signed char *)lpMask.Data + 13;
*tmp = 24;
imageReader(imgName, &imgHeight, &imgWidth, &imgBitDepth, imgHeader, imgColorTable, imgBuffer);
Convolve(imgHeight, imgWidth, &lpMask, imgBuffer, imgBuffer2);
imageWriter(newImgName, imgHeader, imgColorTable, imgBuffer2, imgBitDepth);
printf("Success!\n");
return 0;
}
//2D Discrete Convolution
void Convolve(int imgRows, int imgCols, struct Mask *myMask, unsigned char *input_buf, unsigned char *output_buf)
{
long i, j, m, n, idx, jdx;
int ms, im, val;
unsigned char *tmp;
//outer summation loop - image
for (i = 0; i < imgRows; ++i)
//inner summation loop - image
for (j = 0; j < imgCols; ++j)
{
val = 0;
//outer summation loop - mask
for (m = 0; m < myMask->Rows; ++m)
//inner summation loop - mask
for (n = 0; n < myMask->Cols; ++n)
{
//Issue in understanding below part
ms = (signed char)*(myMask->Data + m * myMask->Rows + n);
// index of input img, used for checking boundary
idx = i - m;
jdx = j - n;
if (idx >= 0 && jdx >= 0) //ignore input samples which are out of bound
im = *(input_buf + idx * imgRows + jdx);
val += ms * im;
}
//truncate values to remain inside 0to255 range
if (val > 255) val = 255;
if (val < 0) val = 0;
tmp = output_buf + i * imgRows + j;
*tmp = (unsigned char)val;
}
}
在 3 行中,使用的公式相似且最难理解其实现,如果可能,请帮助理解这些代码逻辑或它们到底在做什么:
ms = (signed char)*(myMask->Data + m * myMask->Rows + n);
im = *(input_buf + idx * imgRows + jdx);
tmp = output_buf + i * imgRows + j;
对于使用的公式/伪代码,请查看以下网站上的卷积部分:- https://en.wikipedia.org/wiki/Kernel_(image_processing)
或者
g(x,y) = ∑k= -n2 to n2 ∑j= -m2 to m2 h(j,k) * f(xj, yk) ,其中 m2 = 掩码宽度的一半 & n2 = 掩码高度的一半
或者