“This is the first day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021”

The way this series of columns are written

This series of columns will use the first question-and-answer writing format to quickly introduce you to the beginner, intermediate, and advanced levels of OpenCV.

5. Python OpenCV slider details and FAQ solutions

The slider is very rich in the use of OpenCV cases, many times need to use the slider to obtain the relevant parameters.

To master the slider, you only need to master cv2.createTrackbar and cv2.getTrackbarPos.

The prototypes for the above two functions can be viewed directly through the help function, and this series of columns will only briefly explain the function prototypes

createTrackbar(trackbarName, windowName, value, count, onChange) -> None
getTrackbarPos(trackbarname, winname) -> retval
Copy the code

The cv2.createTrackbar function has more parameters, and the cv2.getTrackbarPos function is its child.

Next through a simple case, the basic application of the slider, drag to change the color of a rectangle in the window.

import cv2
import numpy as np

cv2.namedWindow("Trackbar_Demo", cv2.WINDOW_NORMAL)

# to make space for parameter positions in the slider


def nothing() :
    pass


ret = np.zeros([512.512.3], np.uint8)
Create a slider
cv2.createTrackbar("color_green"."Trackbar_Demo".0.255, nothing)

while 1:
    Get the value of the slider
    color_green = cv2.getTrackbarPos("color_green"."Trackbar_Demo")
    cv2.rectangle(ret, (100.100), (200.200), (0, color_green, 0), -1)
    cv2.imshow("Trackbar_Demo", ret)
    if cv2.waitKey(1) & 0xFF= =ord('q') :break

cv2.destroyAllWindows()
Copy the code

If the following BUG occurs during code writing, missing parameters:

TypeError: function takes exactly 5 arguments (4 given)
Copy the code

This BUG indicates that the last onChange parameter is missing from the cv2.createTrackbar function.

After the code is run, the GIF looks like this:

cv2.createTrackbarFunction onChange parameter related problem solution

Cv2. createTrackbar (onChange) = onChange (onChange);

Pointer to the function to be called every time the slider changes position. This function should be prototyped as void Foo(int,void*); , where the first parameter is the trackbar position and the second parameter is the user data (see the next parameter). If the callback is the NULL pointer, no callbacks are called, but only value is updated.

In OpenCV C++, this function has an extra parameter called userdata, which means that the prototype of this function is as follows:

int createTrackbar(const String& trackbarname, const String& winname, int* value, int count, TrackbarCallback onChange=0.void* userdata=0)
Copy the code

But Python has integrated it so that it can operate on two data values with a single parameter, so that we can actually operate on it every time we drag the slider.

Modify the code as follows. In relation to space, only modify the part of nothing function. When running the code, the following content will appear:

# slider callback function for each step
def nothing(x) :
    print("Slider to operate")
    print(x)
Copy the code

I can even adjust the code logic directly to place the rectangle drawing operation in the scrollbar callback as follows:

import cv2
import numpy as np

cv2.namedWindow("Trackbar_Demo", cv2.WINDOW_NORMAL)

# slider callback function for each step
def nothing(x) :
    print("Slider to operate")
    cv2.rectangle(ret, (100.100), (200.200), (0, x, 0), -1)


ret = np.zeros([512.512.3], np.uint8)
Create a slider
cv2.createTrackbar("color_green"."Trackbar_Demo".0.255, nothing)


# color_green = cv2.getTrackbarPos("color_green", "Trackbar_Demo")
while True:
    cv2.imshow("Trackbar_Demo", ret)
    if cv2.waitKey(1) & 0xFF= =ord('q') :break

cv2.destroyAllWindows()
Copy the code

With this logic in place, we can design the slider as a switch that can be dragged to different values to show different effects.

For more details, you can continue to read the manual, visit the address

Split slider and image window in OpenCV

In the actual coding process, it is recommended to split the slider window and the picture window to facilitate the adjustment of parameters.

For example, the following is a manual callback to implement binarization (covered in a future article).

import cv2
import numpy as np


def nothing(a) :
    pass


cv2.namedWindow("HSV",cv2.WINDOW_AUTOSIZE)

cv2.createTrackbar("HUE Min"."HSV".0.255, nothing)
cv2.createTrackbar("HUE Max"."HSV".180.255, nothing)
cv2.createTrackbar("SAT Min"."HSV".255.255, nothing)
cv2.createTrackbar("SAT Max"."HSV".43.255, nothing)
cv2.createTrackbar("VALUE Min"."HSV".255.255, nothing)
cv2.createTrackbar("VALUE Max"."HSV".46.255, nothing)

while True:

    img = cv2.imread("./t1.jpg")
    imgHsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    h_min = cv2.getTrackbarPos("HUE Min"."HSV")
    h_max = cv2.getTrackbarPos("HUE Max"."HSV")
    s_min = cv2.getTrackbarPos("SAT Min"."HSV")
    s_max = cv2.getTrackbarPos("SAT Max"."HSV")
    v_min = cv2.getTrackbarPos("VALUE Min"."HSV")
    v_max = cv2.getTrackbarPos("VALUE Max"."HSV")

    lower = np.array([h_min, s_min, v_min])
    upper = np.array([h_max, s_max, v_max])
    mask = cv2.inRange(imgHsv, lower, upper)
    result = cv2.bitwise_and(img, img, mask=mask)

    mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
    hStack = np.hstack([img, mask, result])
    cv2.imshow('Horizontal Stacking', hStack)
    if cv2.waitKey(1) & 0xFF= =27:
        break


cv2.destroyAllWindows()
Copy the code

After the above code runs, there will be a very convenient operation, drag a window, in another window can dynamically display the corresponding change.

Cv2.namedwindow (“HSV”, cv2.window_autosize), please use the value cv2.window_autosize. If you do not use this value, it is easy to cause a mess of the slider window. Or uneven distribution of window parameters.

Finally, another function of the slider is to reemphasize the switch button. After all, there are no button functions in OpenCV, and using a slider with a fixed value can effectively solve this problem.

Use the code as follows:

cv2.createTrackbar(switch,'image'.0.1If this value is not used, it is easy to cause the disorderly version of the slider window or the uneven distribution of window parameters. Finally, another function of the slider is to reemphasize the switch button. After all, there are no button functions in OpenCV, and using a slider with a fixed value can effectively solve this problem. Python cv2.createTrackbar(switch,'image'.0.1,nothing)
Copy the code