0

I have a code that thresholds the frame. I want to add trackbars for adjusting the detection parameters, but because I'm new in OpenCV I can't figure out how to do this. The premise is that I have and orange golf ball, that I want to detect, but I can't do it, so I need trackbars to adjust the detection parameters, so I can detect the golf ball. After that I can add blob detection and x & y keypoints detection. But the main problem is the trackbars.

I added a trackbar, but it changed the frame blue and didn't change anything else, so I deleted it.

import cv2

cap = cv2.VideoCapture(0)

while True:
  ret, frame = cap.read()

  # colour detection limits
  lB = 125
  lG = 125
  lR = 125
  hB = 255
  hG = 255
  hR = 255
  lowerLimits = np.array([lB, lG, lR])
  upperLimits = np.array([hB, hG, hR])

  thresholded = cv2.inRange(frame, lowerLimits, upperLimits)
  outimage = cv2.bitwise_and(frame, frame, mask = thresholded)

  cv2.imshow('Original', frame)

  cv2.imshow('Processed', outimage)

1 Answers1

0

I wanted to give you an example, but ended up create a complete script - see below.

The idea is to create a trackbar for each value (I put the in a separate window for ease of use). When a trackbar is moved, a function is called the modifies the global color range variable. Then the thresholding is performed.

Note: for separating out a specific color RGB is not very good. It is far easier in the HSV colorspace. The process is the same as below, but the image is converted to HSV first.
Try out this script, it is basically the script below, but with HSV.

Result:

enter image description here

Code:

import numpy as np
import cv2
# Load image
frame = cv2.imread('img.jpg')

# create variables
lowerLimits = np.array([0, 0, 0])
upperLimits = np.array([255, 255, 255])

# functions to modify the color ranges
def setLowVal(val, col):
    global lowerLimits
    lowerLimits[col] = val
    processImage()

def setHighVal(val, col):
    global upperLimits
    upperLimits[col] = val
    processImage()

def processImage():
    # treshold and mask image
    thresholded = cv2.inRange(frame, lowerLimits, upperLimits)
    outimage = cv2.bitwise_and(frame, frame, mask = thresholded)
    #show img
    cv2.imshow("Frame", outimage)

# create trackbars
cv2.namedWindow("Control")
cv2.createTrackbar("lowRed", "Control", 0,255, lambda x: setLowVal(x,2))
cv2.createTrackbar("highRed", "Control", 255,255, lambda x: setHighVal(x,2))
cv2.createTrackbar("lowGreen", "Control", 0,255, lambda x: setLowVal(x,1))
cv2.createTrackbar("highGreen", "Control", 255,255, lambda x: setHighVal(x,1))
cv2.createTrackbar("lowBlue", "Control", 0,255, lambda x: setLowVal(x,0))
cv2.createTrackbar("highBlue", "Control", 255,255, lambda x: setHighVal(x,0))

#show initial image
cv2.imshow("Frame", frame)
cv2.waitKey(0)
cv2.destroyAllWindows()

Note that I used a lambda function so I could write less code, but lambda's are not really a beginner topic. If you don't fully understand, know that you can also do the following:

def setLowRed(val):
    global lowRed
    lowRed = val
    processImage()

cv2.createTrackbar("lowRed", "Control", 0,255, setLowRed)

Do that for each color, and build the color range array in processImage()

J.D.
  • 4,511
  • 2
  • 7
  • 20
  • OMG, thank you soooooo much. I've been at this code for several days and couldn't figure out how to do this. Thank you, soooo, sooooo much!!! – HollowRaccoon Nov 08 '19 at 23:40