python:将一个负值输入到数组中一直给我 256 减去该值(图像-prewitt 边缘检测)
python: inputting a negative value into array keeps giving me 256 minus that value (image- prewitt edge detection)
我正在尝试对图像进行简单的 prewitt 边缘检测,并输出 2 个具有水平和垂直边缘的图像。出于某种原因,每当输出值应为负数(例如 -3)时,我的输出数组以 256 减去该值 (253) 结束,这给了我大量的背景知识。我尝试添加这些 if/elif/else 语句,但这根本没有帮助。我正在使用下面的代码并且不知道出了什么问题:
for i in range(1,(len(os.listdir(images)))):
image=plt.imread(images+(os.listdir(images)[i]))
if len(image.shape)>2:
img=image[:,:,0]
else:
img=image
imgC=deepcopy(img)
imgD=deepcopy(img)
imgE=deepcopy(img)
for x in range(1,img.shape[1]-2):
for y in range(1,img.shape[0]-2):
avgA=(img[(y-1),x]+img[(y-1),(x+1)]+img[(y-1),(x-1)])
avgC=(img[(y+1),x]+img[(y+1),(x+1)]+img[(y+1),(x-1)])
avgT=(img[(y-1),(x-1)]+img[y,(x-1)]+img[(y+1),(x-1)])
avgB=(img[(y-1),(x+1)]+img[y,(x+1)]+img[(y+1),(x+1)])
if (avgA-avgC)<0:
imgC[y,x]=0
elif (avgA-avgC)>255:
imgC[y,x]=255
else:
imgC[y,x]=(avgA-avgC)
if (avgT-avgB)<0:
imgD[y,x]=0
elif (avgT-avgB)>255:
imgD[y,x]=255
else:
imgD[y,x]=(avgT-avgB)
imgE[y,x]=math.sqrt(((imgC[y,x]**2)+(imgD[y,x]**2)))
该图像中的值存储为 unsigned byte
s(0..255
范围),所以这可能是问题所在,因为减去两个 unsigned byte
s 会导致溢出,您会得到253
而不是 -3
.
您需要将这些值转换为 int
。像这样的东西可以工作:
...
avgA = int(img[(y-1),x]) + int(img[(y-1),(x+1)]) + int(img[(y-1),(x-1)])
avgC = int(img[(y+1),x]) + int(img[(y+1),(x+1)]) + int(img[(y+1),(x-1)])
avgT = int(img[(y-1),(x-1)]) + int(img[y,(x-1)]) + int(img[(y+1),(x-1)])
avgB = int(img[(y-1),(x+1)]) + int(img[y,(x+1)]) + int(img[(y+1),(x+1)])
imgC[y, x] = avgA - avgC
imgD[y, x] = avgT - avgB
...
但我很确定使用通用卷积你会得到更好的(更快、更不容易出错的代码)结果
函数,例如 PIL.Image.filter(''<filter>'')
和使用创建的过滤矩阵
PIL.ImageFilter.Kernel(..)
用于 PIL 库 - http://pillow.readthedocs.org/en/latest/reference/ImageFilter.html
或者 numpy/scipy
个库中的 convolve
个,如下所示:http://juanreyero.com/article/python/python-convolution.html
Edit:正如 Julien Spronck 指出的那样 - imgE
中的结果值完全超出范围,通常应将其除以像素数(即卷积矩阵中所有值的总和)用于计算该结果。
我正在尝试对图像进行简单的 prewitt 边缘检测,并输出 2 个具有水平和垂直边缘的图像。出于某种原因,每当输出值应为负数(例如 -3)时,我的输出数组以 256 减去该值 (253) 结束,这给了我大量的背景知识。我尝试添加这些 if/elif/else 语句,但这根本没有帮助。我正在使用下面的代码并且不知道出了什么问题:
for i in range(1,(len(os.listdir(images)))):
image=plt.imread(images+(os.listdir(images)[i]))
if len(image.shape)>2:
img=image[:,:,0]
else:
img=image
imgC=deepcopy(img)
imgD=deepcopy(img)
imgE=deepcopy(img)
for x in range(1,img.shape[1]-2):
for y in range(1,img.shape[0]-2):
avgA=(img[(y-1),x]+img[(y-1),(x+1)]+img[(y-1),(x-1)])
avgC=(img[(y+1),x]+img[(y+1),(x+1)]+img[(y+1),(x-1)])
avgT=(img[(y-1),(x-1)]+img[y,(x-1)]+img[(y+1),(x-1)])
avgB=(img[(y-1),(x+1)]+img[y,(x+1)]+img[(y+1),(x+1)])
if (avgA-avgC)<0:
imgC[y,x]=0
elif (avgA-avgC)>255:
imgC[y,x]=255
else:
imgC[y,x]=(avgA-avgC)
if (avgT-avgB)<0:
imgD[y,x]=0
elif (avgT-avgB)>255:
imgD[y,x]=255
else:
imgD[y,x]=(avgT-avgB)
imgE[y,x]=math.sqrt(((imgC[y,x]**2)+(imgD[y,x]**2)))
该图像中的值存储为 unsigned byte
s(0..255
范围),所以这可能是问题所在,因为减去两个 unsigned byte
s 会导致溢出,您会得到253
而不是 -3
.
您需要将这些值转换为 int
。像这样的东西可以工作:
...
avgA = int(img[(y-1),x]) + int(img[(y-1),(x+1)]) + int(img[(y-1),(x-1)])
avgC = int(img[(y+1),x]) + int(img[(y+1),(x+1)]) + int(img[(y+1),(x-1)])
avgT = int(img[(y-1),(x-1)]) + int(img[y,(x-1)]) + int(img[(y+1),(x-1)])
avgB = int(img[(y-1),(x+1)]) + int(img[y,(x+1)]) + int(img[(y+1),(x+1)])
imgC[y, x] = avgA - avgC
imgD[y, x] = avgT - avgB
...
但我很确定使用通用卷积你会得到更好的(更快、更不容易出错的代码)结果
函数,例如 PIL.Image.filter(''<filter>'')
和使用创建的过滤矩阵
PIL.ImageFilter.Kernel(..)
用于 PIL 库 - http://pillow.readthedocs.org/en/latest/reference/ImageFilter.html
或者 numpy/scipy
个库中的 convolve
个,如下所示:http://juanreyero.com/article/python/python-convolution.html
Edit:正如 Julien Spronck 指出的那样 - imgE
中的结果值完全超出范围,通常应将其除以像素数(即卷积矩阵中所有值的总和)用于计算该结果。