c++ - 为什么使用可分离内核时我的 sobel 滤波器输出如此明亮?
问题描述
我正在尝试从头开始实现 Sobel 过滤器。我正在使用https://en.wikipedia.org/wiki/Sobel_operator#Technical_details中描述的可分离过滤器。
这是我转换为灰度的原始图像: 灰度图像
我的 Sobel X-gradient 的输出很好:x-gradient sobel filtered image
但是,我的 Sobel y-gradient 图像不正确:y-gradient sobel filtered image
在我看来,像素值太高了。[1, 2, 1]
这是 y 梯度图像在与内核 水平卷积之后但在垂直卷积之前的样子:仅 y 梯度水平
这是代码。请注意,对于 y 梯度,我只是复制粘贴了 x 梯度代码并交换了首先使用的内核(如维基百科页面所示):
int sobel_1[3] = {1, 0, -1};
int sobel_2[3] = {1, 2, 1};
Image Image::sobel_x(){
Image grayscale = this->grayscale();
Image sobel_x = Image(m_width, m_height, m_max);
int r_delta[3] = {-1, 0, 1};
int c_delta[3] = {-1, 0, 1};
for (int row = 0; row < m_height; row++){
for (int col = 0; col < m_width; col++){
Color new_color = Color();
for (int i = 0; i < 3; i++){
int new_c = col + c_delta[i];
if (new_c >= 0 && new_c < m_width){
new_color = new_color + (grayscale.getRGB(row, new_c) * sobel_1[i]);
}
}
new_color = Color(abs(new_color.get_r()), abs(new_color.get_g()), abs(new_color.get_b()));
new_color.clamp();
sobel_x.setColor(row, col, new_color);
}
}
for (int row = 0; row < m_height; row++){
for (int col = 0; col < m_width; col++){
Color new_color = Color();
for (int i = 0; i < 3; i++){
int new_r = row + r_delta[i];
if (new_r >= 0 && new_r < m_height){
new_color = new_color + (sobel_x.getRGB(new_r, col) * sobel_2[i]);
}
}
new_color = Color(abs(new_color.get_r()), abs(new_color.get_g()), abs(new_color.get_b()));
new_color.clamp();
new_color = new_color / 8;
sobel_x.setColor(row, col, new_color);
}
}
return sobel_x;
}
Image Image::sobel_y(){
Image grayscale = this->grayscale();
Image sobel_y = Image(m_width, m_height, m_max);
int r_delta[3] = {-1, 0, 1};
int c_delta[3] = {-1, 0, 1};
for (int row = 0; row < m_height; row++){
for (int col = 0; col < m_width; col++){
Color new_color = Color();
for (int i = 0; i < 3; i++){
int new_c = col + c_delta[i];
if (new_c >= 0 && new_c < m_width){
new_color = new_color + (grayscale.getRGB(row, new_c) * sobel_2[i]);
}
}
new_color = Color(abs(new_color.get_r()), abs(new_color.get_g()), abs(new_color.get_b()));
new_color.clamp();
sobel_y.setColor(row, col, new_color);
}
}
for (int row = 0; row < m_height; row++){
for (int col = 0; col < m_width; col++){
Color new_color = Color();
for (int i = 0; i < 3; i++){
int new_r = row + r_delta[i];
if (new_r >= 0 && new_r < m_height){
new_color = new_color + (sobel_y.getRGB(new_r, col) * sobel_1[i]);
}
}
new_color = Color(abs(new_color.get_r()), abs(new_color.get_g()), abs(new_color.get_b()));
new_color.clamp();
new_color = new_color / 8;
sobel_y.setColor(row, col, new_color);
}
}
return sobel_y;
}
解决方案
推荐阅读
- xamarin.forms - FFImageloading - 检查图像是否存在于缓存中?
- salesforce - 在 Salesforce 相关内容(如联系人)中设置自定义字段(或)查找对象的样式
- python - 如何使用 cython 多次有效地组装刚度矩阵
- paypal - 使用 Phonegap 应用程序中的 REST API 的 Paypal 定期付款
- python-3.x - Vasya - 文员 ----- codewars kata
- android - Android gradle build 引起:java.lang.RuntimeException: java.io.IOException: Failed to read manifest
- jquery - 不满足验证条件时避免滚动顶部
- ios - 在 MVVM 中工作时如何组织和命名代码
- javascript - Javascript字符串从随机字符动画到预定义
- docker - 在 Linux Ubuntu 18.04 上安装 Docker 时出错