Я пытаюсь пошаговый детектор краев Sobel для школьного проекта, и я не могу обернуть голову, где я иду не так. Не вдаваясь в детали, я думаю, что большая их часть сводится к приведенному ниже коду. Когда я положил изображение lenna.pgm:
из-за 2D-маски вдоль x-градиента я получаю много шума.
Я обсудил код с моим инструктором, и я делаю то, что он говорит, чтобы сделать.
Вот код для свертки в направлении x:
void applySobel(int maskX[3][3], int maskY[3][3], int maskWidth, int imageH, int imageW,
int threshold, int*** generated){
int sumX, sumY;
// convolve smoothed image with Sobel mask in the X-direction
for(int i = 0; i < imageH; i++) {
for(int j = 0; j < imageW; j++) {
if(i == 0 || i >= imageH - 1 || j == 0 || j >= imageW - 1) {
sumX = 0;
} else {
sumX = 0;
for(int x = -1; x <= 1; x++) {
for(int y = -1; y <= 1; y++) {
sumX += generated[0][i+x][j+y] * maskX[x+1][y+1];
}
}
}
generated[1][i][j] = sumX;
}
}
}
Я также пытался нормализовать изображение перед выводом в файл, но изображение становится темным.
for(int a = 1; a < 6; a++) {
min = imageOUT[a][0][0];
max = 0;
// normalize the pixel values and then write to files
for(int i = 0; i < M; i++) {
for(int j = 0; j < N; j++) {
pixel = imageOUT[a][i][j];
if(pixel < min) {
min = pixel;
} if(pixel > max) {
max = pixel;
}
}
}
for(int i = 0; i < M; i++) {
for(int j = 0; j < N; j++) {
imageOUT[a][i][j] = (int)(imageOUT[a][i][j] - min) * (255/(max-min));
}
}
WriteImage(fileOutName[a-1].c_str(), imageOUT[a], M, N, Q);
}
Я глубоко ценю любое понимание. Это держит меня в течение нескольких дней.
ОБНОВЛЕНИЕ: вот решение, к которому я пришел. По сути, я взял только объекты, представляющие интерес, в маске, вместо того, чтобы умножать и складывать все, так что нулевые пробелы были опущены.
void applySobel(int maskX[3][3], int maskY[3][3], int maskWidth, int imageH, int imageW,
int threshold, int*** generated){
int sumX, sumY;
// convolve smoothed image with Sobel mask in the X-direction
for(int i = 0; i < imageH; i++) {
for(int j = 0; j < imageW; j++) {
if(i == 0 || i == imageH - 1 || j == 0 || j == imageW - 1) {
sumX = generated[0][i][j];
} else {
sumX = (int)(generated[0][i-1][j-1]*maskX[0][0] +
generated[0][i][j-1]*maskX[1][0] +
generated[0][i+1][j-1]*maskX[2][0] +
generated[0][i-1][j+1]*maskX[0][2] +
generated[0][i][j+1]*maskX[1][2]+
generated[0][i+1][j+1]*maskX[2][2])/2;
}
generated[1][i][j] = sumX/3;
}
}
И прекрасная Ленна после применения градиента X-Direction:
Спасибо всем большое за ваши предложения.