Search code examples
pythonimage-processingtrackbarcolor-paletteopencv3.0

Can't move trackbars in OpenCV. They instantly go back to zero.


The code doesn't give me any errors but I can't move the trackbars to find the values I like. I've fully read through documentation but didn't find anything helpful. I'm trying to find a good upper and lower value to for my color range using trackbars. It should be pretty simple.

rh for example means red high as in red upper boundary.

Here's my code:

import cv2
import numpy as np

def nothing(x):
    return()


cap = cv2.VideoCapture('video.MOV')


while(1):

    #Gets retval and frames from each video 

    ret ,frame = cap.read()

    #Check to see if retval is not None or empty
    if not ret:
        break;

    trackbar = np.zeros((300,512,3), np.uint8)
    trackbar2 = np.zeros((300,512,3), np.uint8)
    cv2.namedWindow("trackbar")
    cv2.namedWindow("trackbar2")


    cv2.createTrackbar('RL','trackbar',0,255,nothing)
    cv2.createTrackbar('GL','trackbar',0,255,nothing)
    cv2.createTrackbar('BL','trackbar',0,255,nothing)

    cv2.createTrackbar('RH','trackbar2',0,255,nothing)
    cv2.createTrackbar('GH','trackbar2',0,255,nothing)
    cv2.createTrackbar('BH','trackbar2',0,255,nothing)


    r = cv2.getTrackbarPos('RL','trackbar')
    g = cv2.getTrackbarPos('GL','trackbar')
    b = cv2.getTrackbarPos('BL','trackbar')

    rh = cv2.getTrackbarPos('RH','trackbar2')
    gh = cv2.getTrackbarPos('GH','trackbar2')
    bh = cv2.getTrackbarPos('BH','trackbar2')

    trackbar[:] = [b,g,r]
    trackbar2[:] = [bh,gh,rh]



    boundaries = [([r,g,b],[rh,gh,bh])]

    for (lower,upper) in boundaries:     
            lower = np.array(lower, dtype = "uint8")   
            upper = np.array(upper, dtype = "uint8")

            mask = cv2.inRange(frame,lower,upper)
            output = cv2.bitwise_and(frame, frame, mask = mask)
            cv2.imshow("video", np.hstack([frame, output]))   




    if (cv2.waitKey(1) & 0xFF) == ord("q"):
        break


cv2.destroyAllWindows()    

Solution

  • As beaker mentioned, I had my initiations inside the loop, so I just moved them outside and it works: Working code below:

    import cv2
    import numpy as np
    
    def nothing(x):
        return()
    
    
    cap = cv2.VideoCapture('movie.MOV')
    
    trackbar = np.zeros((300,512,3), np.uint8)
    trackbar2 = np.zeros((300,512,3), np.uint8)
    cv2.namedWindow("trackbar")
    cv2.namedWindow("trackbar2")
    
    
    cv2.createTrackbar('RL','trackbar',0,255,nothing)
    cv2.createTrackbar('GL','trackbar',0,255,nothing)
    cv2.createTrackbar('BL','trackbar',0,255,nothing)
    
    cv2.createTrackbar('RH','trackbar2',0,255,nothing)
    cv2.createTrackbar('GH','trackbar2',0,255,nothing)
    cv2.createTrackbar('BH','trackbar2',0,255,nothing)
    
    
    
    while(1):
    
        #Gets retval and frames from each video 
    
        ret ,frame = cap.read()
    
        #Check to see if retval is not None or empty
        if not ret:
            break;
    
    
        r = cv2.getTrackbarPos('RL','trackbar')
        g = cv2.getTrackbarPos('GL','trackbar')
        b = cv2.getTrackbarPos('BL','trackbar')
    
        rh = cv2.getTrackbarPos('RH','trackbar2')
        gh = cv2.getTrackbarPos('GH','trackbar2')
        bh = cv2.getTrackbarPos('BH','trackbar2')
    
        trackbar[:] = [b,g,r]
        trackbar2[:] = [bh,gh,rh]
    
    
    
        boundaries = [([r,g,b],[rh,gh,bh])]
    
        for (lower,upper) in boundaries:     
                lower = np.array(lower, dtype = "uint8")   
                upper = np.array(upper, dtype = "uint8")
    
                mask = cv2.inRange(frame,lower,upper)
                output = cv2.bitwise_and(frame, frame, mask = mask)
                cv2.imshow("video", np.hstack([frame, output]))   
    
    
    
    
        if (cv2.waitKey(1) & 0xFF) == ord("q"):
            break
    
    
    cv2.destroyAllWindows()