-1

I am trying to implement Scales to adjust threshold values for the canny image detection in python however I am unable to change the values using Scales. the value remains 0 no matter what. please help me out. Here is my code.

from tkinter import *
import cv2

v1 =0
v2 =0

def print_value1(val1):
    v1 = val1    
    print (v1)

def print_value2(val2):
    v2 = val2
    print (v2)

def edge_detection():
    img = cv2.imread("C:/Users/Shah Lamaan 
    Rana/Pictures/modernvsoldforehand.jpg")
    edges = cv2.Canny(img, v1, v2)
    cv2.imshow('test image', edges)


root =Tk()

scale1 =  Scale(orient = 'horizontal', from_=0, to=200, command=print_value1)
scale1.pack()
scale2 =  Scale(orient = 'horizontal', from_=0, to=400, command=print_value2)
scale2.pack()
button = Button(root,text = "find edges", command = edge_detection,bg = 'red' 
,height = 1, width = 24, borderwidth=6)
button.pack()

root.mainloop()
Easton Bornemeier
  • 1,918
  • 8
  • 22
shah lamaan
  • 35
  • 2
  • 6
  • 2
    Possible duplicate of [Using global variables in a function](https://stackoverflow.com/questions/423379/using-global-variables-in-a-function) – Easton Bornemeier Aug 07 '18 at 18:31

4 Answers4

2

If you're trying to modify a global variable within a function you must tell the function that you're going to be working with a global variable, because functions assume you want them to use a local variable. Try this:

v1 =0
v2 =0

def print_value1(val1):
    global v1 
    v1 = val1    
    print (v1)

def print_value2(val2):
    global v2
    v2 = val2
    print (v2)

and carry on from there!

Sarah Strand
  • 119
  • 8
1

You need the global keyword -- your v1 inside the function is separate from the v1 defined before it:

v1 = 0
print(v1, id(v1))
def p_v1():
    v1 = 1
    print(v1, id(v1))

p_v1()  # 1 4516448896
print(v1, id(v1))  # 0 4516448864

with global:

global v1 = 0
print(v1, id(v1))
def p_v1():
    global v1
    v1 = 1
    print(v1, id(v1))

p_v1()  # 1 4383513216
print(v1, id(v1))  # 1 4383513216
MoxieBall
  • 1,907
  • 7
  • 23
  • This will only maintain the two values at 1 – Onyambu Aug 07 '18 at 18:32
  • sure, but this is just an example of how to make global variables work, not how to make the code in the question work – MoxieBall Aug 07 '18 at 18:35
  • well then that really doesn't answer the question at hand, and should therefore be part of the comment since it is an example and not an answer to the question – Onyambu Aug 07 '18 at 18:36
  • The question is not an MCVE, this answer answers the missing MCVE. It details everything that OP has done wrong, and gives them enough information to fix it, without me caring about what they're trying to do, which should be enough by any measure of an answer – MoxieBall Aug 07 '18 at 18:38
0
v1 =0
v2 =0

def print_value1(val1):
    nonlocal v1 
    v1 = val1    
    print (v1)

def print_value2(val2):
    nonlocal v2
    v2 = val2
    print (v2)

declare your variables as nonlocal or global. Python's scope resolution dictates that re-assigning variables with the same name inside a function creates a new local variable. In order to reflect those changes in variables in lower scope, one must specify.

modesitt
  • 7,052
  • 2
  • 34
  • 64
0

Use a class, to store the values of the scale:

import tkinter as tk
import cv2

class MainWindow(tk.Tk):
    def __init__(self):
        tk.Tk.__init__()
        self.v1 = 0
        self.v2 = 0
        scale1 =  tk.Scale(self, orient='horizontal', from_=0, to=200, command=self.print_value1)
        scale1.pack()
        scale2 =  tk.Scale(self, orient='horizontal', from_=0, to=400, command=self.print_value2)
        scale2.pack()
        button = tk.Button(self, text="find edges", command=self.edge_detection, bg='red', height=1, width=24, borderwidth=6)
        button.pack()

    def print_value1(self, val1):
        self.v1 = val1    
        print(self.v1)

    def print_value1(self, val2):
        self.v2 = val2
        print(self.v2)

    def edge_detection(self):
        img = cv2.imread("C:/Users/Shah Lamaan Rana/Pictures/modernvsoldforehand.jpg")
        edges = cv2.Canny(img, self.v1, self.v2)
        cv2.imshow('test image', edges)

def main():
    root = MainWindow()
    root.mainloop()

if __name__ == '__main__':
    main()
Daniel
  • 42,087
  • 4
  • 55
  • 81