pythonopencvtrackbar

OpenCV Python: Blur image using trackbar


I'd like to control the blur of an image by using a trackbar. The given MWE imports a picture with a trackbar that sets the aperture linear size (ksize) which has to be one or a positive odd number. Strangely getTrackbarPos returns a negative number which makes it necesarry to multiply ksize by -2 and subtract 1. Inside an infinite loop the image gets blurred and displayed.

import cv2

# Callback function for trackbar
def on_change(self):
    pass

# Reads image with 0 as GRAY and 1 as BGR
img = cv2.imread('example.JPG', 0)

# Creates window
cv2.namedWindow('Image')

# Creates Trackbar with slider position and callback function
low_k = 1  # slider start position
high_k = 21  # maximal slider position
cv2.createTrackbar('Blur', 'Image', low_k, high_k, on_change)

# Infinite loop
while(True):
    ksize = cv2.getTrackbarPos('ksize', 'Image')  # returns trackbar position
    ksize = -2*ksize-1  # medianBlur allows only odd ksize values

    # Blures input image
    median = cv2.medianBlur(img, ksize)  # source, kernel size

    cv2.imshow('Image', median)  # displays image 'median' in window
    k = cv2.waitKey(1) & 0xFF
    if k == 27:
        break

cv2.destroyAllWindows()

By running this code a window opens with the desired trackbar on top of the input image. The slider start position is one as desired but by changing the silder's position there is no blur or any significant change to the displayed image.

The main question is why the returned trackbar position does not have any influence on medianBlur(). My first thought suggests a mistake either inside the while loop or the callback function. Besides that I'd like to know why getTrackbarPos returns negativ numbers.

I am using Python 3.6 with Anaconda 1.9.2. Thank you for any help!


Solution

  • getTrackbarPos arguments expects the name of the trackbar and the name of the window. You are creating the trackbar with the name Blur and reading as ksize, change

    ksize = cv2.getTrackbarPos('Blur', 'Image')
    

    to

    ksize = cv2.getTrackbarPos('ksize', 'Image')
    

    or change the other way around (the createTrackbar method).

    Also, as mentioned in the comments, you can also update ksize on the on_change callback.

    As a side note, you also need to adjust the way you treat odd values, if the track bar position is 1, the ksize ends up as -3