拉普拉斯过滤器非常暗。几乎不起作用
Laplacian filter is VERY dark. Almost doesn't work
我尝试实现拉普拉斯滤波器。我想我实现它是正确的,但它 returns 非常暗的图像。这是我的代码。
values
是一个包含像素值的数组。每个像素表示为三个值 (rgb)。 (values[0]
= 第一个像素红色,values[1]
= 第一个像素绿色,values[2]
= 第一个像素蓝色,values[3]
= 第二个像素红色 e.t.c。)
数组 indeces/wrong channels/wrong pointers/e.t.c 不能出错。因为我从工作正常的高斯滤波器中复制了这部分。
我使用整数数组存储 eaxh 像素的平均值,然后将它们缩放到 0...255 并复制到无符号字符数组。
在这里,我还添加了 min/max,总和,我认为,将值缩放到 0...255 或在某处溢出可能有问题...
请帮我找出一个错误。或者我做错了什么?
void Laplacian::filter3x3(unsigned char* values, int rows, int cols){
unsigned char mask [3][3]= {{1, 1, 1},{1,-8, 1},{1, 1, 1}};
int* intValues = new int[rows*cols];
// For each channel(RGB).
for(int c=0; c <= BLUE; ++c){
int min = 8*255;
int max = -8*255;
for(int i=1; i<rows-1; i+=1){
for(int j=c+3; j<cols-3; j+=3){
double sum = 0;
for(int x=-1; x<=1; ++x)
for(int y=-1; y<=1; ++y){
sum += values[(i+x)*cols + j+y*3] * mask[x+1][y+1];
}
if(sum < min)
min = sum;
if(sum > max)
max = sum;
intValues[i*cols + j] = sum;
}
}
int delta = max - min;
std::cout<<"Delta: "<<delta<<"\tMin: "<<min<<"\tMax:"<<max<<"\n";
for(int i=1; i<rows-1; i+=1)
for(int j=c+3; j<cols-3; j+=3){
values[i*cols + j] =(unsigned char)((intValues[i*cols + j] - min)/delta*255);
}
}
}
这是图片示例:输入和输出。
以及带有 min/max/delta 值的控制台屏幕截图(红色,然后是绿色,然后是蓝色)。看起来他们工作正常。
是否有另一种方法来规范化这些值?
unsigned char mask [3][3]= {{1, 1, 1},{1,-8, 1},{1, 1, 1}};
您在 unsigned
中有一个 -8
看起来很可疑。
values[i*cols + j] =(unsigned char)((intValues[i*cols + j] - min)/delta*255);
首先除以 delta
意味着您将产生一个小于 1.0 的分数,它将作为整数数学舍入为 0,然后乘以 255 将不执行任何操作。
如果你这样做* 255 / delta
,只要中间值不溢出(这似乎是合理的),你就会避免这个问题。
我尝试实现拉普拉斯滤波器。我想我实现它是正确的,但它 returns 非常暗的图像。这是我的代码。
values
是一个包含像素值的数组。每个像素表示为三个值 (rgb)。 (values[0]
= 第一个像素红色,values[1]
= 第一个像素绿色,values[2]
= 第一个像素蓝色,values[3]
= 第二个像素红色 e.t.c。)
数组 indeces/wrong channels/wrong pointers/e.t.c 不能出错。因为我从工作正常的高斯滤波器中复制了这部分。
我使用整数数组存储 eaxh 像素的平均值,然后将它们缩放到 0...255 并复制到无符号字符数组。 在这里,我还添加了 min/max,总和,我认为,将值缩放到 0...255 或在某处溢出可能有问题... 请帮我找出一个错误。或者我做错了什么?
void Laplacian::filter3x3(unsigned char* values, int rows, int cols){
unsigned char mask [3][3]= {{1, 1, 1},{1,-8, 1},{1, 1, 1}};
int* intValues = new int[rows*cols];
// For each channel(RGB).
for(int c=0; c <= BLUE; ++c){
int min = 8*255;
int max = -8*255;
for(int i=1; i<rows-1; i+=1){
for(int j=c+3; j<cols-3; j+=3){
double sum = 0;
for(int x=-1; x<=1; ++x)
for(int y=-1; y<=1; ++y){
sum += values[(i+x)*cols + j+y*3] * mask[x+1][y+1];
}
if(sum < min)
min = sum;
if(sum > max)
max = sum;
intValues[i*cols + j] = sum;
}
}
int delta = max - min;
std::cout<<"Delta: "<<delta<<"\tMin: "<<min<<"\tMax:"<<max<<"\n";
for(int i=1; i<rows-1; i+=1)
for(int j=c+3; j<cols-3; j+=3){
values[i*cols + j] =(unsigned char)((intValues[i*cols + j] - min)/delta*255);
}
}
}
这是图片示例:输入和输出。
以及带有 min/max/delta 值的控制台屏幕截图(红色,然后是绿色,然后是蓝色)。看起来他们工作正常。
是否有另一种方法来规范化这些值?
unsigned char mask [3][3]= {{1, 1, 1},{1,-8, 1},{1, 1, 1}};
您在 unsigned
中有一个 -8
看起来很可疑。
values[i*cols + j] =(unsigned char)((intValues[i*cols + j] - min)/delta*255);
首先除以 delta
意味着您将产生一个小于 1.0 的分数,它将作为整数数学舍入为 0,然后乘以 255 将不执行任何操作。
如果你这样做* 255 / delta
,只要中间值不溢出(这似乎是合理的),你就会避免这个问题。