下面是我编写的python代码,目的是使图像正常化并使其具有照度不变性。
对于图像的每个像素,新像素值应为(R/sum,G/sum,B/sum)
,其中sum=R+G+B
import numpy as np
import cv2
img=cv2.imread(r'C:/Users/kjbaili/.spyder-py3/color_supression_RV/rub00.jpg')
print(img[200,200])
print(img[200,200,0])
def normalized(down):
norm_img = np.zeros(down.shape, down.dtype)
width,height,channels=down.shape
for y in range(0,height):
for x in range(0,width):
sum=down[x,y,0]+down[x,y,1]+down[x,y,2]
b=(down[x,y,0]/ sum)*255
g=(down[x,y,1]/ sum)*255
r=(down[x,y,2]/ sum)*255
norm_img[x,y,0]= b
norm_img[x,y,1]= g
norm_img[x,y,2]= r
return norm_img
image=normalized(img)
cv2.imshow('normalized',image)
cv2.waitKey(0)
cv2.destroyAllWindows()
但是,我得到了以下错误:
OverflowError: cannot convert float infinity to integer
虽然,我在这里发现了类似的问题,但我无法将其投射到我的问题中,因为我不知道哪个值是无穷大的
我很高兴能得到一些帮助
提前谢谢
您的访问索引已切换。你应该做
down[y,x,0]
等,而不是down[x,y,0]
。但是,我怀疑您在访问这里时没有遇到任何错误,因为图像是方形的。此外,当您将三个精度有限的数字与完全浮点精度相加时,您的值将溢出。例如,在无符号8位整数中添加200 + 100 + 50
将导致350 % 256 = 94
。在无穷大结果中可能发生的情况是,要么你有完全黑色的像素,因此归一化会导致除以0的错误,要么三个值的总和溢出,给你一个值0,再次给你这个结果您可以做的是执行健全性检查,以确保如果三个通道的总和不等于0,则执行归一化。此外,您还需要更改精度,以便在求和后可以处理更高的值
换言之:
这当然是非常低效的,因为您在单个像素上循环,而没有利用体现NumPy阵列的矢量化。简单地说,使用^{} 沿第三维求和,然后将每个通道除以相应的量:
第一行计算二维阵列,其中每个位置沿通道标注求和,以获得每个空间位置的RGB值之和。我还将类型提升为浮点,以在归一化时保持精度。接下来,第二行代码上的中间检查确保没有被零除的错误,因此任何为0的像素,我们将sentinel值设置为1,以便除法结果为0。之后,我们获取输入图像并将每个对应的RGB像素除以相应空间位置处的和。请注意,我使用了广播,因此我将2D和数组制作成了3D数组,其中包含一个单例第三通道,以允许广播正常工作。最后,我乘以255,就像你在上一个版本中所做的那样。我还确保将最终结果强制转换为函数中的传入类型
为了更简洁一点,您可以在第三维求和后使用
numpy.sum
的keepdims
参数来维护单体维度,从而进一步简化此过程。这样可以避免手动插入单个标注:相关问题 更多 >
编程相关推荐