2D Iterable to get every convolution window per loop iteration.

    For more information, refer to:
    - https://github.com/guillaume-chevalier/python-conv-lib/blob/master/conv/conv.py
    - https://github.com/guillaume-chevalier/python-conv-lib
    - MIT License, Copyright (c) 2018 Guillaume Chevalier

def convolved_2d(iterable, kernel_size=1, stride=1, padding=0, default_value=None):
    """2D Iterable to get every convolution window per loop iteration.

    For more information, refer to:
    - https://github.com/guillaume-chevalier/python-conv-lib/blob/master/conv/conv.py
    - https://github.com/guillaume-chevalier/python-conv-lib
    - MIT License, Copyright (c) 2018 Guillaume Chevalier
    """
    kernel_size = dimensionize(kernel_size, nd=2)
    stride = dimensionize(stride, nd=2)
    padding = dimensionize(padding, nd=2)

    for row_packet in convolved(iterable, kernel_size[0], stride[0], padding[0], default_value):
        transposed_inner = []
        for col in tuple(row_packet):
            transposed_inner.append(list(
                convolved(col, kernel_size[1], stride[1], padding[1], default_value)
            ))

        if len(transposed_inner) > 0:
            for col_i in range(len(transposed_inner[0])):
                yield tuple(row_j[col_i] for row_j in transposed_inner)