How to make a circular kernel?


For the Code below, I am wondering how to make a circular kernel instead of a rectangular one. I am currently looking at something circular, and I want to find the BGR average values for it. By adjusting my kernel, my data will be more accurate.

for center in c_1:
    b = img2[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 0]
    g = img2[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 1]
    r = img2[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 2]
Asked By: Danny.Tran2018



Get the circle region when given the center, you could try the following function:

def circleAverage(center, r = 4):
    for i in range(center[0]-r, center[0]+r):
        for j in range(center[1]-r, center[1] + r):
            if (center[0] - i) ** 2 + (center[1] - j) ** 2 <= r**2:
                // do your computation here.

Hope this helps you.

Answered By: chenxingwei


We manually created a structuring elements in the previous examples with help of Numpy. It is rectangular shape. But in some cases, you may need elliptical/circular shaped kernels. So for this purpose, OpenCV has a function, cv2.getStructuringElement(). You just pass the shape and size of the kernel, you get the desired kernel.

# Elliptical Kernel
>>> cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
array([[0, 0, 1, 0, 0],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [0, 0, 1, 0, 0]], dtype=uint8)
Answered By: Kohanz

Came here to find how to make a circular (symmetric) kernel. Ended up with my own implementation.

import numpy as np

def get_circular_kernel(diameter):

    mid = (diameter - 1) / 2
    distances = np.indices((diameter, diameter)) - np.array([mid, mid])[:, None, None]
    kernel = ((np.linalg.norm(distances, axis=0) - mid) <= 0).astype(int)

    return kernel

Note that for low diameters, behavior is perhaps unexpected. Variable mid when used for the second time can for example be replaced by diameter / 2.

Answered By: F.Wessels

I’ve implemented it in a following way:

r = 16
kernel = np.fromfunction(lambda x, y: ((x-r)**2 + (y-r)**2 <= r**2)*1, (2*r+1, 2*r+1), dtype=int).astype(np.uint8)

Extra type conversion is needed to avoid overflow

Answered By: Paul
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.