python 动态计算图像处理卷积核

1l5u6lss  于 2023-02-02  发布在  Python
关注(0)|答案(1)|浏览(136)

使用标准的numpycv2.filter2D解决方案,我可以对图像应用静态卷积:

import numpy as np

convolution_kernel = np.array([[-2, -1, 0], 
                               [-1, 1, 1], 
                               [0, 1, 2]])

import cv2

image = cv2.imread('1.png') result = cv2.filter2D(image, -1, convolution_kernel)

输出图像中[i, j]处的每个像素都有一个值,该值是通过将一个3x3 "窗口"居中到输入图像中的[i, j]上,然后将窗口中的每个值乘以卷积核中的对应值(Hadamard乘积),最后将9个乘积相加以获得输出图像中[i, j]的值(对于每个颜色通道)来计算的。
[四]

  • (图片来源:https://github.com/ashushekar/image-convolution-from-scratch#convolution)*

在我的例子中,计算每个输出像素的函数并不像阿达玛乘积之和那么简单,而是通过对已知大小的窗口执行运算,将每个像素转换为以该像素为中心的两个输入矩阵。
我有两个输入矩阵("图像"),如

A = [[179,  97,  77, 118, 144, 105],
     [ 68,  56, 184, 210, 141, 230],
     [178, 166, 218,  47, 106, 172],
     [ 38, 183,  50, 185,  48,  87],
     [ 60, 200, 228, 232,   6, 190],
     [253,  75, 231, 166, 117, 134]]

B = [[116,  95,  94, 220,  80, 223],
     [135,   9, 166,  78,   5, 129],
     [102, 167, 120,  81, 141,  29],
     [ 83, 117,  81, 129, 255,  48],
     [130, 231, 165,   7, 187, 169],
     [ 44, 137,  16,  50, 229, 202]]

在输出矩阵中,每个[i, j]像素应计算为两个(大小相同)输入矩阵上3x3 "窗口"内[u, v]坐标的所有A[u,v] ** 2 - B[u,v] ** 2值之和。
如何在Python中快速计算这个输出矩阵?
使用numpy,看起来像是A * A - B * B的3x3求和,但是如何做这些求和呢?或者我可以使用另一个"2d map"过程吗?
我编写了一个基于循环的解决方案来计算以下两个示例的预期输出:
一个二个一个一个

ffscu2ro

ffscu2ro1#

您可以使用scipy.signal.convolve2d

from scipy.signal import convolve2d

# Same shape as original (6x6)
>>> convolve2d(A**2-B**2, np.ones((3, 3)), mode='same')
array([[ 18585.,  18969.,  -2523., -37383., -20140., -24368.],
       [ 20073.,  23512.,   6832.,   6933.,  37732.,  31747.],
       [ 22768.,  25490.,  42146.,  73088.,  44875.,  76213.],
       [ 15835.,  35302.,  48530.,  42295., -58134., -37358.],
       [-18745., -12306.,  27137.,  92057., -26295., -84850.],
       [ 48773.,  22268.,  51359., 156695.,   5146., -88994.]])

# Shape reduce by 1 (5x5)
>>> convolve2d(A**2-B**2, kernel, mode='valid')
array([[ 23512.,   6832.,   6933.,  37732.,  31747.],
       [ 25490.,  42146.,  73088.,  44875.,  76213.],
       [ 35302.,  48530.,  42295., -58134., -37358.],
       [-12306.,  27137.,  92057., -26295., -84850.],
       [ 22268.,  51359., 156695.,   5146., -88994.]])
    • 注意**:您必须反复使用"mode"和"limit"参数,直到得到您想要的结果。
    • 更新**

如果此时边界不是问题,则可以使用sliding_window_view

from numpy.lib.stride_tricks import sliding_window_view

>>> np.sum(sliding_window_view(A**2-B**2, (3, 3)), axis=(2, 3))
array([[ 65887,  38811,  61252,  51033],
       [ 60119, 109133,  35101,  70005],
       [ 62463, 126935,  14530,   2255],
       [110426, 163513,  33812, -50035]])

相关问题