Python находит ядро ​​свертки, если входное изображение и выходное изображение известны - PullRequest
0 голосов
/ 07 апреля 2019

У меня проблема с ядром свертки в python.Речь идет о простом операторе свертки.У меня есть входная матрица и выходная матрица.Я хочу найти возможное ядро ​​свертки с размером (5x5).Как решить эту проблему с Python, NumPy или TenorFlow?

import scipy.signal as ss

input_img = np.array([[94, 166, 76, 106, 152, 232],
                      [48, 242, 30, 98, 46, 210],
                      [52, 60, 86, 60, 216, 248],
                      [52, 236, 116, 240, 224, 184],
                      [138, 160, 146, 254, 236, 252],
                      [94, 100, 224, 246, 152, 74]], dtype=float)

output_img = np.array([[15, 49, 23, 105, 0, 0],
                       [43,30, 108, 124, 0, 0],
                       [58, 120, 112, 92, 0, 0],
                       [73, 127, 118, 126, 0, 0],
                       [112, 123, 76, 37, 0, 0],
                       [0, 0, 0, 0, 0, 0]], dtype=float)

# I want to find this kernel
conv = np.zeros((5,5), dtype=int)

# So if I do convolution operator, output_img will resulting a value same as I defined above
output_img = ss.convolve2d(input_img, conv, padding='same')

1 Ответ

0 голосов
/ 08 апреля 2019

Насколько я понял, вам нужно восстановить вес окна по заданным входным, выходным массивам и размеру окна. Это возможно, я думаю, особенно, если входной массив (изображение) достаточно большой.

Посмотрите на код ниже:

import scipy.signal as ss
import numpy as np

source_dataset = np.random.rand(20, 10)
sample_convolution = np.diag([1, 1, 1])
output_dataset = ss.convolve2d(data, sample_convolution, mode='same')
conv_size = c.shape[0]

# Given output_dataset, source_datset, and conv_size we need to reconstruct
# window weights.

def reconstruct(data, output, csize):
    half_size = int(csize / 2)
    min_row_ind = half_size
    max_row_ind = int(data.shape[0]) - half_size
    min_col_ind = half_size
    max_col_ind = int(data.shape[1]) - half_size
    A = list()
    b = list()
    for i in np.arange(min_row_ind, max_row_ind, dtype=int):
        for j in np.arange(min_col_ind, max_col_ind, dtype=int):
            A.append(data[(i - half_size):(i + half_size + 1), (j - half_size):(j + half_size + 1)].ravel().tolist())
            b.append(output[i, j])
            if len(A) == csize * csize and np.linalg.matrix_rank(A) == csize * csize:
                return (np.linalg.pinv(A)@np.array(b)[:, np.newaxis]).reshape(csize, csize)
    if len(A) < csize*csize:
        raise Exception("Insufficient data")

result = reconstruct(source_dataset, output_dataset, 3)

Я получил следующий результат

array([[ 1.00000000e+00, -1.77635684e-15, -1.11022302e-16],
       [ 0.00000000e+00,  1.00000000e+00, -8.88178420e-16],
       [ 0.00000000e+00, -1.22124533e-15,  1.00000000e+00]])

Итак, все работает как положено; но, безусловно, необходимо улучшить, чтобы учесть краевые эффекты, случай, когда размер окна даже и т. д.

...