为了账号安全,请及时绑定邮箱和手机立即绑定

标准化图像返回---> OverflowError:无法将浮点无穷大转换为整数

标准化图像返回---> OverflowError:无法将浮点无穷大转换为整数

Cats萌萌 2023-02-22 10:51:11
下面是我为了标准化图像并使其照度不变而编写的 python 代码。对于图像的每个像素,新像素值应为(R/sum,G/sum,B/sum),其中sum=R+G+B。import numpy as npimport 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_imgimage=normalized(img)cv2.imshow('normalized',image)cv2.waitKey(0)cv2.destroyAllWindows()但是,我收到以下错误:OverflowError: cannot convert float infinity to integer虽然,我在这里找到了与此相关的类似已回答问题,但我无法将其投射到我的问题中,因为我不知道哪个值会导致无穷大。
查看完整描述

1 回答

?
12345678_0001

TA贡献1802条经验 获得超5个赞

您的访问索引已切换。你应该做down[y,x,0]etc. not down[x,y,0]。但是,我怀疑您在此处访问时不会遇到任何错误,因为图像是方形的。此外,与完整的浮点精度相比,当您以有限的精度将三个数字加在一起时,您的值将会溢出。例如,添加200 + 100 + 50无符号 8 位整数将导致350 % 256 = 94. 在你的无限结果中可能发生的是,要么你有完全黑色的像素,因此归一化导致除以 0 错误,或者三个值的总和溢出给你一个 0 值再次给你这个结果。


您可以做的是执行完整性检查,以确保如果三个通道的总和不等于 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=float(down[y,x,0])+float(down[y,x,1])+float(down[y,x,2])  # Change

              

              if sum > 0:  # Change

                  b=(down[y,x,0]/ sum)*255.0   # Change

                  g=(down[y,x,1]/ sum)*255.0

                  r=(down[y,x,2]/ sum)*255.0

            

                  norm_img[y,x,0]= b  # Should cast downwards automatically

                  norm_img[y,x,1]= g

                  norm_img[y,x,2]= r

              

    return norm_img

这当然是非常低效的,因为您在单个像素上循环并且没有利用体现 NumPy 数组的矢量化。简单的说,numpy.sum沿第三个维度求和,然后将每个通道除以相应的量:


def normalized(down):

    sum_img = np.sum(down.astype(np.float), axis=2)

    sum_img[sum_img == 0] = 1

    return (255 * (down.astype(np.float) / sum_img[...,None])).astype(down.dtype)

第一行计算一个二维数组,其中每个位置沿通道维度求和,为您提供每个空间位置的 RGB 值之和。我还将类型提升为浮点数以在规范化时保持精度。接下来,第二行代码的中间检查确保没有被零除的错误,所以任何为 0 的像素,我们将标记值设置为 1,以便除法结果为 0 值。之后,我们获取输入图像并将每个相应的 RGB 像素除以相应空间位置的总和。请注意,我使用了广播,以便将 2D 总和数组制作成具有单例第三通道的 3D 数组,以使广播正常工作。最后,我乘以 255,就像您在之前的版本中所做的那样。


为了更简洁一点,您可以通过使用keepdims参数来进一步简化此操作numpy.sum,以便在对第三维求和后维护单例维。这样就避免了手动单例维度插入:


def normalized(down):

    sum_img = np.sum(down.astype(np.float), axis=2, keepdims=True)

    sum_img[sum_img == 0] = 1

    return (255 * (down.astype(np.float) / sum_img)).astype(down.dtype)


查看完整回答
反对 回复 2023-02-22
  • 1 回答
  • 0 关注
  • 144 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号