2

Trying to create 3 trackbars for 1 window.

Im taking an image. Coverting it to gray. Using non local means aka blurring it. Passing it thru a threshold called bino. Doing an edge detection on it. Using the edge detection to find contours. Sorting thise contours by area. Taking only the largest contour. And displaying it preferably over the canny or thresholded image.

I need a track bar for the nlm blur, the threshold, and the canny lines all on the same image but I dont know how to do it and cant figure it out. Please your my only hope!

import numpy as np
import cv2 as cv

def thresh_callback(val):
    nlm_thresh = val
    bino_thresh = val
    canny_thresh = val

    img = cv.imread('test.jpg')
    imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    nlm = cv.fastNlMeansDenoising(imgray,nlm_thresh,nlm_thresh,11,21)
    bino = cv.adaptiveThreshold(nlm,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,\
                             cv.THRESH_BINARY,bino_thresh,8)
    canny_output = cv.Canny(bino, canny_thresh, canny_thresh * 2)
    _, contours, hierarchy = cv.findContours(canny_output,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    cnt = sorted(contours, key=cv.contourArea, reverse=True)
    cnts = cnt[0]
    area = cv.contourArea(cnts)
    print (area)

    drawing = cv.drawContours(img, cnt, 0, (0,255,0), 3)

    cv.imshow('Contours2', canny_output)
    cv.imshow(source_window, drawing)


source_window = 'Source'
cv.namedWindow(source_window)
max_thresh = 255
thresh = 100 # initial threshold
cv.createTrackbar('nlm_thresh:', source_window, thresh, max_thresh, thresh_callback)
cv.createTrackbar('bino_thresh:', source_window, thresh, max_thresh, thresh_callback)
cv.createTrackbar('canny_thresh:', source_window, thresh, max_thresh, thresh_callback)

thresh_callback(thresh)

cv.waitKey(0) & 0xFF  
cv.destroyAllWindows()
Mogarbobac
  • 97
  • 2
  • 10

2 Answers2

6

Another simpler way to do this would be to ignore the parameter passed to your thresh_callback and just get the trackbar value for each trackbar separately with getTrackbarPos()

def thresh_callback(val):
    nlm_thresh = cv.getTrackbarPos('nlm_thresh:', source_window)
    bino_thresh = cv.getTrackbarPos('bino_thresh:', source_window)
    canny_thresh = cv.getTrackbarPos('canny_thresh:', source_window)
abhigdeal
  • 162
  • 3
  • 9
3

Have the trackbars call separate functions that update the relevant (global) variable and then call the function that processes the image.

import numpy as np
import cv2 as cv

#initialise variables with a default
nlm_thresh = 5
bino_thresh = 5
canny_thresh = 5

# functions that update a variable, 
# then call image processing function
def change_nlm(val):
    global nlm_thresh
    nlm_thresh = val
    thresh_callback()

def change_bino(val):
    global bino_thresh
    bino_thresh = val
    thresh_callback()

def change_canny(val):
    global canny_thresh
    canny_thresh = val
    thresh_callback()

# your function that processes the image
def thresh_callback():
    img = cv.imread('test.jpg')
    imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    nlm = cv.fastNlMeansDenoising(imgray,nlm_thresh,nlm_thresh,11,21)
    bino = cv.adaptiveThreshold(nlm,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,          cv.THRESH_BINARY,bino_thresh,8)
    canny_output = cv.Canny(bino, canny_thresh, canny_thresh * 2)
    _, contours, hierarchy = cv.findContours(canny_output,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    cnt = sorted(contours, key=cv.contourArea, reverse=True)
    cnts = cnt[0]
    area = cv.contourArea(cnts)
    print (area)

    drawing = cv.drawContours(img, cnt, 0, (0,255,0), 3)

    cv.imshow('Contours2', canny_output)
    cv.imshow(source_window, drawing)


source_window = 'Source'
cv.namedWindow(source_window)
max_thresh = 255
thresh = 100
# create trackbars
cv.createTrackbar('nlm_thresh:', source_window, thresh, max_thresh, change_nlm)
cv.createTrackbar('bino_thresh:', source_window, thresh, max_thresh, change_bino)
cv.createTrackbar('canny_thresh:', source_window, thresh, max_thresh, change_canny)

thresh_callback()

cv.waitKey(0) & 0xFF  
cv.destroyAllWindows()
J.D.
  • 4,511
  • 2
  • 7
  • 20