pythonopencvtkinter

Handling of lists in python while using OpenCV


I have tried to formulate my previous question a bit more. (I have erased my last question because it was closed). I am currently writing a program that acquires the position of a point generated by clicking on a window, assigns an id to the acquired point, creates a dictionary-type list, and then accesses the list with the id to get the value of the point. (The reason I am doing it this way is to create a user interface in the future.)The following is the code I wrote.

#Import modules to be used
import tkinter as tk
import numpy as np
import cv2

points_dict = [] 

img = cv2.imread('images.jpg')
cv2.imshow('sample', img)

def onMouse(event, x, y, flags, params):

    if event == cv2.EVENT_LBUTTONDOWN:
        id = input("Please enter your id:") 
        points_dict.append({'id':id, 'vector':(x,y)})
        #print(f"id: {id}, x: {x}, y: {y}")

cv2.setMouseCallback('sample', onMouse)
cv2.waitKey(0)

def button_click():
    #first_point = first_point_list[1]
    print(points_dict)
    first_point_list = [d["vector"] for d in points_dict if d["id"]==input("Starting id:")]
    print(first_point_list)
    second_point_list = [d["vector"] for d in points_dict if d["id"]==input("Endpoint id:")]
    print(second_point_list)
    #second_point = second_point_list[1]
#     print(second_point_list[1])
#     diff= first_point - second_point 
#     norm = np.linalg.norm(diff)

#     with open('map.txt', 'a') as f:
#         f.write("{} {} {}\n".format(first_point, second_point, norm))

root = tk.Tk()
button = tk.Button(root, text="button", command=button_click)
button.pack()
root.mainloop()

And after one run, the following results were obtained.

Please enter your id:1
Please enter your id:2
[{'id': 1, 'vector': (112, 34)}, {'id': 2, 'vector': (102, 67)}]
Starting id:1
Starting id:2
[(112, 34), (102, 67)]
Endpoint id:2
Endpoint id:1
[]
Please enter your id:1
Please enter your id:2
[{'id': 1, 'vector': (112, 34)}, {'id': 2, 'vector': (102, 67)}]
Starting id:1
[(112, 34)]
Endpoint id:2
[(102, 67)]

I would expect the above to be the case, but apparently, it doesn't work that way. Something must be wrong with the code, so I ran the simplified code separately, and this one worked fine.

my_list = \[{"id":3,"vector" : (1, 2)} , {"id":4,"vector" : (2, 3)}\]

result = \[d\["vector"\] for d in my_list if d\["id"\] == 4\]

print(result)

\[(2, 3)\]

Solution

  • def button_click():
        #first_point = first_point_list[1]
        print(points_dict)
        first_point_list = [d["vector"] for d in points_dict if d["id"]==input("Starting id:")]
        print(first_point_list)
        second_point_list = [d["vector"] for d in points_dict if d["id"]==input("Endpoint id:")]
        print(second_point_list)
    

    In the above, it seems that I made a mistake in putting the input in the list comprehension notation.

    second_point_list = [d["vector"] for d in points_dict if d["id"]==input("Endpoint id:")]

    a = input("Endpoint id:")
    second_point_list = [d["vector"] for d in points_dict if d["id"]== a]
    

    Thanks for the advice, picobit! I will switch to GUI in the future. Thanks for your help, acw1668!