Convolution without any padding-opencv Python -


is there function in opencv-python can convolve image kernel without padding ? basically, want image in convolution takes place in regions kernel , portion of image overlaps.

opencv supports convolving image output returned same size input image. such, can still use opencv's filter functions, ignore pixels along edges kernel didn't encapsulate inside image. assuming image kernel odd, can divide each of dimensions half, take floor (or round down) , use these cut away information isn't valid , return left. divakar mentioned, same method using scipy's 2d convolution method 'valid' option.

as such, assuming image stored in a , kernel stored in b, following filtered image kernel encapsulated inside image. take note we're going assume kernel odd , output stored in c.

import cv2 import numpy np  = cv2.imread('...') # load in image here b = (1.0/25.0)*np.ones((5,5)) # specify kernel here c = cv2.filter2d(a, -1, b) # convolve  h = np.floor(np.array(b.shape)/2).astype(np.int) # find half dims of kernel c = c[h[0]:-h[0],h[1]:-h[1]] # cut away unwanted information 

take note cv2.filter2d performs correlation, not convolution. if kernel symmetric (that if take transpose , equals itself), correlation , convolution equivalent. if not case, need perform 180 degree rotation of kernel before using cv2.filter2d. can doing:

b = b[::-1,::-1] 

in order compare, can show above code equivalent use scipy's convolve2d function. here's reproducible ipython session shows this:

in [41]: import cv2  in [42]: import numpy np  in [43]: scipy.signal import convolve2d  in [44]: = np.reshape(np.arange(49), (7,7)).astype(np.float32)  in [45]: out[45]: array([[  0.,   1.,   2.,   3.,   4.,   5.,   6.],        [  7.,   8.,   9.,  10.,  11.,  12.,  13.],        [ 14.,  15.,  16.,  17.,  18.,  19.,  20.],        [ 21.,  22.,  23.,  24.,  25.,  26.,  27.],        [ 28.,  29.,  30.,  31.,  32.,  33.,  34.],        [ 35.,  36.,  37.,  38.,  39.,  40.,  41.],        [ 42.,  43.,  44.,  45.,  46.,  47.,  48.]], dtype=float32)  in [46]: b = (1.0/25.0)*np.ones((5,5), dtype=np.float32)  in [47]: b out[47]: array([[ 0.04,  0.04,  0.04,  0.04,  0.04],        [ 0.04,  0.04,  0.04,  0.04,  0.04],        [ 0.04,  0.04,  0.04,  0.04,  0.04],        [ 0.04,  0.04,  0.04,  0.04,  0.04],        [ 0.04,  0.04,  0.04,  0.04,  0.04]], dtype=float32)  in [48]: c = cv2.filter2d(a, -1, b)  in [49]: h = np.floor(np.array(b.shape)/2).astype(np.int)  in [50]: c = c[h[0]:-h[0],h[1]:-h[1]]  in [51]: c out[51]: array([[ 15.99999809,  16.99999809,  18.        ],        [ 22.99999809,  24.        ,  24.99999809],        [ 29.99999809,  30.99999809,  31.99999809]], dtype=float32)  in [52]: c2 = convolve2d(a, b, mode='valid')  in [53]: c2 out[53]: array([[ 15.99999905,  17.00000191,  18.00000191],        [ 22.99999809,  23.99999809,  24.99999809],        [ 29.99999809,  30.99999809,  31.99999809]], dtype=float32) 

the example quite simple understand. declare dummy matrix of 7 x 7 values increase 0 48 row-wise. declare 5 x 5 kernel of (1/25) each element implement 5 x 5 average filter. use cv2.filter2d , scipy.signal.convolve2d extract out valid portions of convolution result. far precision goes, c output of cv2.filter2d , c2 output of convolve2d both equivalent. take special note of not actual contents shape of both output arrays.

however, if wish keep size of original image , replace affected pixels filtered results, make copy of original image , use same indexing logic used cut away information invalid replacing pixels in copy convolved result:

c_copy = a.copy() c_copy[h[0]:-h[0],h[1]:-h[1]] = c  

Comments

Popular posts from this blog

javascript - Thinglink image not visible until browser resize -

firebird - Error "invalid transaction handle (expecting explicit transaction start)" executing script from Delphi -

mongodb - How to keep track of users making Stripe Payments -