алгоритм свертки для сглаживания данных - PullRequest
0 голосов
/ 29 января 2020

Поэтому я решил написать свою собственную свертку, чтобы сгладить мои данные, что делает то же самое, что и np.convolve. единственная проблема в том, что я получил амплитуды немного выше, чем я ожидал. Я не знаю, на какую часть я должен разделить мои данные, чтобы получить правильный результат.

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

def dotProduct(a,b):
    dot = 0
    if (len(a) == len(b)):
        for i in range(len(a)):
            dot += a[i] * b[i]
    elif (len(a) > len(b)):
        for i in range(len(b)):
            dot += a[i] * b[i]
    elif (len(b) > len(a)):
        for i in range(len(a)):
            dot += a[i] * b[i]

    return dot


def convolution(signal,magnitude=3):
    kernel = np.linspace(0,1,4) * magnitude
    convolution = np.zeros(len(signal))
    sameSizeKernel = np.zeros(len(signal))
    for i in range(len(convolution)):
        if ((len(kernel)+i) <= len(convolution)):
            sameSizeKernel[i:len(kernel)+i] = kernel
            convolution[i+int(len(kernel)/2)] = dotProduct(signal,sameSizeKernel)/4
        else:
            kernel = kernel[:len(kernel)-1]
            sameSizeKernel[i:len(kernel)+i] = kernel
            convolution[i+int(len(kernel)/2)] = dotProduct(signal,sameSizeKernel)/4
    return convolution


t = np.linspace(0, 1, 500)
triangle = signal.sawtooth(2 * np.pi * 5 * t, 0.5)
conv_ = convolution(triangle,10)

plt.figure(figsize=(15,8))
plt.plot(triangle, label='signal')
plt.plot(conv_, label='convolution')
plt.legend(loc=1)

enter image description here

1 Ответ

0 голосов
/ 29 января 2020

Так что я нашел ответ сам :) Дело в том, что массив ядра может суммировать до 1 не больше, чем если вы хотите увидеть правильный результат. Поэтому для нормализации мы должны разделить каждую точку на сумму индексов ядра.

convolution[i+int(len(kernel)/2)] = dotProduct(signal,sameSizeKernel)/np.sum(kernel)

Полный код приведен здесь:

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

def dotProduct(a,b):
    dot = 0
    if (len(a) == len(b)):
        for i in range(len(a)):
            dot += a[i] * b[i]
    elif (len(a) > len(b)):
        for i in range(len(b)):
            dot += a[i] * b[i]
    elif (len(b) > len(a)):
        for i in range(len(a)):
            dot += a[i] * b[i]

    return dot

dotProduct(a,b)

def convolution(signal,magnitude=3):
    kernel = np.linspace(0,magnitude,10)
    convolution = np.zeros(len(signal))
    sameSizeKernel = np.zeros(len(signal))
    for i in range(len(convolution)):
        if ((len(kernel)+i) <= len(convolution)):
            sameSizeKernel[i:len(kernel)+i] = kernel
            convolution[i+int(len(kernel)/2)] = dotProduct(signal,sameSizeKernel)/np.sum(kernel)
        else:
            kernel = kernel[:len(kernel)-1]
            sameSizeKernel[i:len(kernel)+i] = kernel
            convolution[i+int(len(kernel)/2)] = dotProduct(signal,sameSizeKernel)/np.sum(kernel)
    return convolution


t = np.linspace(0, 1, 50)
triangle = np.zeros(len(t))
triangle[10:20] = 10
conv_ = convolution(triangle,10)

plt.figure(figsize=(15,8))
plt.plot(triangle, label='signal')
plt.plot(conv_, label='convolution')
plt.legend(loc=1)

...