gpt4 book ai didi

r - 如何标准化卷积图像?我是不是该?

转载 作者:行者123 更新时间:2023-12-04 10:26:24 25 4
gpt4 key购买 nike

我正在尝试使用卷积进行边缘检测。我想我需要在卷积后对图像进行归一化。

我正在使用此处指定的卷积矩阵:
https://en.wikipedia.org/wiki/Kernel_(image_processing)#Convolution

附件是一些r代码,以及源和输出图像......

require(jpeg)
myjpg <- readJPEG("mtg.jpg")

grayImg <- myjpg[,,1]+myjpg[,,2]+myjpg[,,3] # reduce to gray
grayImg <- grayImg/max(grayImg) # normalize
dim(grayImg)


convolve <- function(img, f){
newimg <- img
radius <- as.integer(nrow(f)/2)+1
print(radius)
for(i in c(1:nrow(img))){
for(j in c(1:ncol(img))){
f_sub <- f[c(max(1,radius-i+1):min(nrow(f),nrow(img)-i+radius)),c(max(1,radius-j+1):min(ncol(f),ncol(img)-j+radius))]
img_sub <- img[c(max(1,i-radius+1):min(nrow(img),i+radius-1)),c(max(1,j-radius+1):min(ncol(img),j+radius-1))]
wavg <- sum(as.vector(f_sub)*as.vector(img_sub))# / sum(as.vector(f_sub)) # todo, not sure about this division
newimg[i,j] <- wavg
}
}
return(newimg)
}

edgeFilter <- matrix(c(-1,-1,-1,-1,8,-1,-1,-1,-1), ncol = 3)

outimg <- convolve(grayImg,edgeFilter)

outimg <- outimg - min(outimg)
outimg <- outimg/max(outimg)

plot(c(0,1),c(0,1),t='n')
rasterImage(outimg, 0,0,1,1)

处理前的灰度图像:

enter image description here

处理后的灰度图:

enter image description here

我很困惑,因为在我看到的例子中,卷积后的图像是黑白的。在这里,我的卷积需要归一化,而且,它不是纯黑白的。

最佳答案

你的可视化是完全正常的。发生的情况是您正在重新映射像素值,以便将最低强度设置为 0,将最高强度设置为 1。所有其他值都被线性重新映射以符合 [0,1]范围。您可能只看到黑白的原因是由于剪辑 .发布这些结果的用户可能已经截断了动态范围,其中任何小于 0 的值都设置为 0,任何大于 1 的值(或您正在查看的数据类型的最大值)是设置为 1。

您正在计算内核/掩码具有负系数的边缘检测,因此您完全有可能在结果中同时获得负值和正值。以这种方式重新缩放图像,您会看到 0 的值被映射到灰色(大约 0.5 左右),因为最小的负强度被拉到 0,这自然意味着您的 0 值被拉到一些非零数。同样,那些非常大的值被归一化为 1。

但是,在执行标准化时, 是标准做法。规范化内核 .原因是这样做可以确保每个像素的输出值永远不会超出数据类型的动态范围。通过对内核进行归一化,您可以确保所有系数的权重在 [0,1] 之间。并且内核的总和为 1。通过这样做,您可以确保您永远不必检查输出并在必要时裁剪值。这也确保您不需要除以卷积代码中每个像素的权重总和,因为内核标准化步骤已经处理了该标准化。您只需标准化一次。但是,当内核中有负系数时,这是一件棘手的事情。如果存在负系数,则很少进行归一化……至少我在实践中看到的。

现在,回到“黑白”的东西,如果你使用另一个过滤器......比如说......一个平均过滤器,你肯定会得到一个“黑白”图片,因为没有任何值是负面的.... 即使将输出标准化为 [0,1]通过最小-最大方法。请记住,这将执行 对比拉伸(stretch) 如果您的强度集中在 [0,1] 的一小部分范围内,输出将拉伸(stretch),使最低强度下降到 0,最大强度映射到 1。

我已经修改了你的代码来做到这一点。请记住,我找不到没有轴线的原始图像,所以我拍了一张快照并将其保存为 PNG。因此,我使用了 png包而不是 jpeg包裹:

require(png) # Change
myjpg <- readPNG("mtg.png") # Change

grayImg <- myjpg[,,1]+myjpg[,,2]+myjpg[,,3] # reduce to gray
grayImg <- grayImg/max(grayImg) # normalize
dim(grayImg)


convolve <- function(img, f){
newimg <- img
radius <- as.integer(nrow(f)/2)+1
print(radius)
for(i in c(1:nrow(img))){
for(j in c(1:ncol(img))){
f_sub <- f[c(max(1,radius-i+1):min(nrow(f),nrow(img)-i+radius)),c(max(1,radius-j+1):min(ncol(f),ncol(img)-j+radius))]
img_sub <- img[c(max(1,i-radius+1):min(nrow(img),i+radius-1)),c(max(1,j-radius+1):min(ncol(img),j+radius-1))]
wavg <- sum(as.vector(f_sub)*as.vector(img_sub))# / sum(as.vector(f_sub)) # todo, not sure about this division
newimg[i,j] <- wavg
}
}
return(newimg)
}

#edgeFilter <- matrix(c(-1,-1,-1,-1,8,-1,-1,-1,-1), ncol = 3)
averageFilter <- matrix(c(1,1,1,1,1,1,1,1,1), ncol=3) / 9# Change

#outimg <- convolve(grayImg,edgeFilter) # Change
outimg <- convolve(grayImg,averageFilter)

outimg <- outimg - min(outimg)
outimg <- outimg/max(outimg)

plot(c(0,1),c(0,1),t='n')
rasterImage(outimg, 0,0,1,1)

这是我得到的:

enter image description here

将其与原始图像进行比较:

enter image description here

如果你更仔细地观察它,你会发现两者之间有些模糊。如果您增加平均过滤器大小...比如说... 7 x 7,您会看到更多模糊:
averageFilter <- matrix(rep(1,49), ncol=7) / 49

这样做,这是我们得到的图像:

enter image description here

正如我们所料......更加模糊。但是,这里的重点是,当您决定通过 min-max 方式对其进行标准化时,数据的动态范围将决定图像的可视化方式。如果有负值,预计 0 左右的值将被推到某个非零值……通常是灰色的。如果您指定具有负系数的内核,则会发生这种情况。如果您的内核具有严格的正系数,您将看不到任何负值,并且可视化与您预期的一样。

关于r - 如何标准化卷积图像?我是不是该?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32596774/

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