gpt4 book ai didi

c++ - sobel 算子 - 假边自然图像

转载 作者:搜寻专家 更新时间:2023-10-31 01:12:50 30 4
gpt4 key购买 nike

我在使用 Sobel 算子进行边缘检测时遇到问题:它会产生太多假边缘,效果如下图所示。我正在使用 3x3 sobel 运算符 - 首先提取垂直然后水平,最终输出是每个滤波器输​​出的幅度。合成图像的边缘被正确提取,但自然图像产生的错误边缘或“噪声”太多,即使图像已通过应用模糊或中值滤波器进行预处理。这可能是什么原因造成的?是实现问题(然后:为什么合成图像很好?)还是我需要做更多的预处理?

原文:
orig

输出:
out

代码:

void imageOp::filter(image8* image, int maskSize, int16_t *mask)
{
if((image == NULL) || (maskSize/2 == 0) || maskSize < 1)
{
if(image == NULL)
{
printf("filter: image pointer == NULL \n");
}
else if(maskSize < 1)
{
printf("filter: maskSize must be greater than 1\n");
}
else
{
printf("filter: maskSize must be odd number\n");
}
return;
}

image8* fImage = new image8(image->getHeight(), image->getWidth());
uint16_t sum = 0;
int d = maskSize/2;
int ty, tx;

for(int x = 0; x < image->getHeight(); x++) //
{ // loop over image
for(int y = 0; y < image->getWidth(); y++) //
{
for(int xm = -d; xm <= d; xm++)
{
for(int ym = -d; ym <= d; ym++)
{
ty = y + ym;
if(ty < 0) // edge conditions
{
ty = (-1)*ym - 1;
}
else if(ty >= image->getWidth())
{
ty = image->getWidth() - ym;
}

tx = x + xm;
if(tx < 0) // edge conditions
{
tx = (-1)*xm - 1;
}
else if(tx >= image->getHeight())
{
tx = image->getHeight() - xm;
}

sum += image->img[tx][ty] * mask[((xm+d)*maskSize) + ym + d];
}
}

if(sum > 255)
{
fImage->img[x][y] = 255;
}
else if(sum < 0)
{
fImage->img[x][y] = 0;
}
else
{
fImage->img[x][y] = (uint8_t)sum;
}
sum = 0;
}
}


for(int x = 0; x < image->getHeight(); x++)
{
for(int y = 0; y < image->getWidth(); y++)
{
image->img[x][y] = fImage->img[x][y];
}
}

delete fImage;
}

最佳答案

这似乎是由于您的代码中某处存在数学错误。按照我的评论,这是我在此处通过 Sobel 运算符运行您的图像时得到的结果(边缘强度由输出图像的亮度表示):

Image after Sobel operator

我使用了 GLSL 片段着色器来生成这个:

 precision mediump float;

varying vec2 textureCoordinate;
varying vec2 leftTextureCoordinate;
varying vec2 rightTextureCoordinate;

varying vec2 topTextureCoordinate;
varying vec2 topLeftTextureCoordinate;
varying vec2 topRightTextureCoordinate;

varying vec2 bottomTextureCoordinate;
varying vec2 bottomLeftTextureCoordinate;
varying vec2 bottomRightTextureCoordinate;

uniform sampler2D inputImageTexture;

void main()
{
float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;
float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;
float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;
float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;
float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;
float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;
float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;
float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;
float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;
float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;

float mag = length(vec2(h, v));

gl_FragColor = vec4(vec3(mag), 1.0);

你没有显示你的掩码值,我假设它包含 Sobel 内核。在上面的代码中,我硬编码了针对 3x3 Sobel 内核中每个像素的红色 channel 执行的计算。这纯粹是为了在我的平台上表现。

我在您的代码中没有注意到的一件事(同样,我可能会遗漏它,就像我将总和设置回 0 一样)是确定 Sobel 运算符的两个部分的 vector 大小。如果存在的话,我希望能在某处看到平方根运算。

关于c++ - sobel 算子 - 假边自然图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13363918/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com