下采样图像时出界限误差

时间:2017-12-06 13:24:57

标签: python image list matrix

有谁知道我的索引matrix[k][m]=sum/9超出范围的原因?我很确定我的解决方案是正确的。我试过调试它,但我仍然无法思考 为什么它不起作用。

def downsample_by_3(image):

    matrix_image = copy.deepcopy(image)
    matrix=[ [], [], [] ]
    k=0
    m=0
    for i in range(0,len(matrix_image),3):

        for j in range(0,len(matrix_image[i]),3):


            sum=0

            for r in range(i,i+3):
                for c in range(j,j+3):
                    sum+=matrix_image[r][c]
            m+=1
            matrix[k][m]=sum/9

        m=0
        k+=1

    return matrix

图像显示为矩阵(列表列表)。

让我说我拿了这个清单,

print(downsample_by_3([[2,2,2],[2,2,2],[2,2,2]]))

它应该返回一个包含18的列表。

另一个更好地理解它的例子:

better example

2 个答案:

答案 0 :(得分:0)

首先将matrix硬编码为一系列空列表matrix=[ [], [], [] ],然后在

matrix[k][m]=sum/9

行,您尝试将值强制插入其中一个插槽,但没有插槽。 k 对于前几个(从0到2)是可以的,但 m 会立即出错。好像你需要动态创建matrix。也许

matrix[k].append(sum/9)

另外,return matrix最后你的功能不会受到伤害。 :)

以上内容可以帮助您前进。至少它提供了运行代码。

答案 1 :(得分:0)

您有一个空列表列表。因此,虽然matrix[0]没问题,但matrix[0][0]超出范围。

如果您希望通过索引访问子列表,则必须事先预先分配子列表的长度,或者如Gary02127的答案所示附加平均值。如果您选择前者,则必须在 m之后增加matrix[k][m]=sum/9

但是,您的代码有另一个等待触发的越界错误。假设您有一个3x4图像,即其中一个尺寸不能被3整除。您可以平均第一个3x3块,然后尝试访问列索引3-5处的像素。

如果你的尺寸不能被缩减采样因子整除,你有3种选择:

  1. 在函数调用开始时引发错误
  2. 添加额外的行/列以使您的矩阵可以被因子整除(您可以使用行/列的最后一个元素的值来进一步扩展它),或者
  3. 只使用剩余的元素。
  4. 这是一个方法#3的实现,并预先分配你的矩阵。

    def downsample(image, factor):
        height = len(image)
        # this assumes that all sublists have the same length!
        width = len(image[0])
        matrix = [[None] * ((width + factor - 1) // factor)
                  for _ in range((height + factor - 1) // factor)]
        k = 0
        m = 0
        for i in range(0, height, factor):
            for j in range(0, width, factor):
                # don't overshadow the `sum` builtin
                total = 0
                count = 0
                for r in range(i, min(i+factor, height)):
                    for c in range(j, min(j+factor, width)):
                        total += image[r][c]
                        count += 1
                matrix[k][m] = total / count
                m += 1
            m = 0
            k += 1
        return matrix