Script funktioniert nicht mit Tkinter GUI

Fragen zu Tkinter.
Antworten
Jappes
User
Beiträge: 5
Registriert: Montag 5. Juli 2021, 08:46

Hallo zusammen,

Der source code als solches funktioniert.
Wenn ich versuche ein GUI hinzuzufügen bekomme ich folgende Probleme:
Beim drücken auf "Start" finde ich die Funktion "def click_event" nicht. Wenn ich die Zeilen verschiebe finde ich "def click_event" jedoch nicht die Parameter aus der Klammer "event, x, y, flags, params".
Kann mir da einer weiter helfen?

Source code:

Code: Alles auswählen

import cv2
import numpy as np







base_image = cv2.imread('base_img.jpg')
base_image_copy = base_image.copy()
subject_image = cv2.imread('subject.jpg')







def click_event(event, x, y, flags, params):
    if event == cv2.EVENT_LBUTTONDOWN:
        cv2.circle(base_image_copy, (x, y), 4, (0, 0, 255), 5)
        points.append([x, y])
        if len(points) <= 4:
            cv2.imshow('image', base_image_copy)
points = []
base_image = cv2.imread('base_img.jpg')
base_image_copy = base_image.copy()
subject_image = cv2.imread('subject.jpg')

cv2.imshow('image', base_image_copy)
cv2.setMouseCallback('image', click_event)
cv2.waitKey(0)
cv2.destroyAllWindows()
def sort_pts(points):
    sorted_pts = np.zeros((4, 2), dtype="float32")
    s = np.sum(points, axis=1)
    sorted_pts[0] = points[np.argmin(s)]
    sorted_pts[2] = points[np.argmax(s)]

    diff = np.diff(points, axis=1)
    sorted_pts[1] = points[np.argmin(diff)]
    sorted_pts[3] = points[np.argmax(diff)]

    return sorted_pts
sorted_pts = sort_pts(points)
h_base, w_base, c_base = base_image.shape
h_subject, w_subject = subject_image.shape[:2]

pts1 = np.float32([[0, 0], [w_subject, 0], [w_subject, h_subject],                     [0, h_subject]])
pts2 = np.float32(sorted_pts)
transformation_matrix = cv2.getPerspectiveTransform(pts1, pts2)

warped_img = cv2.warpPerspective(subject_image, transformation_matrix, (w_base, h_base))
cv2.imshow('Warped Image', warped_img)
mask = np.zeros(base_image.shape, dtype=np.uint8)
roi_corners = np.int32(sorted_pts)

cv2.fillConvexPoly(mask, roi_corners, (255, 255, 255))
mask = cv2.bitwise_not(mask)
masked_image = cv2.bitwise_and(base_image, mask)
output = cv2.bitwise_or(warped_img, masked_image)
cv2.imshow('Fused Image', output)
cv2.imwrite('Final_Output.png', output)
cv2.waitKey(0)
cv2.destroyAllWindows()


GUI code

Code: Alles auswählen

import cv2
import numpy as np
from tkinter import *
from tkinter import messagebox
from tkinter import filedialog
import sys
import os
import re
class App:
  def __init__(self, master):
      global im
      self.master = master
      master.title("Druckvorschau")
      master.geometry("300x120")
      frame = Frame()
      frame.pack()    
      self.button1 = Button(frame, text="Vorlage",command=self.Vorlage) #Button
      self.button1.pack(side=TOP, pady= 10) #Position Botton
      self.button2 = Button(frame, text="Druckbild",command=self.Druckbild) #Button
      self.button2.pack(side=TOP, pady= 10) #Position Botton
      self.button3 = Button(frame, text="Start",command=self.click_event) #Button
      self.button3.pack(side=TOP, pady= 10) #Position Botton

      def wait():
         ...


  def Vorlage(self):
      global im
      import_base_img = filedialog.askopenfilename()
      base_image = cv2.imread(import_base_img)
      base_image_copy = base_image.copy()
      
  def Druckbild(self):
      global im
      import_subject = filedialog.askopenfilename()
      subject_image = cv2.imread(import_subject)
      
  def click_event(self, event, x, y, flags, params):
      print("test")
      global im
      if event == cv2.EVENT_LBUTTONDOWN:
             cv2.circle(base_image_copy, (x, y), 4, (0, 0, 255), 5)# 5 = Punkt-Größe
             points.append([x, y])
             if len(points) <= 4:
                 cv2.imshow('image', base_image_copy)
      points = []
      base_image = cv2.imread(import_base_img)
      base_image_copy = base_image.copy()
      subject_image = cv2.imread(import_subject)
      cv2.imshow('image', base_image_copy)
      v2.setMouseCallback('image', click_event)
      cv2.waitKey(0)
      cv2.destroyAllWindows()

  def sort_pts(points):
          global im
          sorted_pts = np.zeros((4, 2), dtype="float32")
          s = np.sum(points, axis=1)
          sorted_pts[0] = points[np.argmin(s)]
          sorted_pts[2] = points[np.argmax(s)]

          diff = np.diff(points, axis=1)
          sorted_pts[1] = points[np.argmin(diff)]
          sorted_pts[3] = points[np.argmax(diff)]

          return sorted_pts
          sorted_pts = sort_pts(points)
          h_base, w_base, c_base = base_image.shape
          h_subject, w_subject = subject_image.shape[:2]
  
          pts1 = np.float32([[0, 0], [w_subject, 0], [w_subject, h_subject],                     [0, h_subject]])
          pts2 = np.float32(sorted_pts)
          transformation_matrix = cv2.getPerspectiveTransform(pts1, pts2)
  
          warped_img = cv2.warpPerspective(subject_image, transformation_matrix, (w_base, h_base))
          cv2.imshow('Warped Image', warped_img)
          mask = np.zeros(base_image.shape, dtype=np.uint8)
          roi_corners = np.int32(sorted_pts)
 
          cv2.fillConvexPoly(mask, roi_corners, (255, 255, 255))
          mask = cv2.bitwise_not(mask)
          masked_image = cv2.bitwise_and(base_image, mask)

          output = cv2.bitwise_or(warped_img, masked_image)
          cv2.imshow('Fused Image', output)
          cv2.imwrite('Final_Output.png', output)
          cv2.waitKey(0)
          cv2.destroyAllWindows()
  
root = Tk()
my_gui = App(root)
root.mainloop()






Vielen Dank,

Jappes
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Vergiss, dass es global gibt.
Schreib saubere Programme ohne globale Variablen.

Also:
1: werde global los.
2: Es steht kein Code auf Modulebene (also ohne Einrückung) außer Importe und die Definition von Konstanten, Funktionen und Klassen. (Konstanten zeichnen sich übrigens dadurch aus, dass sie ihren Wert nicht ändern). Und der Aufruf deines Programms, das üblicherweise in einer Funktion namens main beginnt und wie folgt aufgerufen wird:

Code: Alles auswählen

if __name__ == "__main__":
    main()
3. Funktionen und Methoden bekommen alles, was sie brauchen als Parameter und geben das Ergebnis mit return zurück.
4. Eingerückt wird mit 4 Leerzeichen. Nicht mal 4 und mal 8.

Warum gibt es da mitten in einer Funktion ein return und die Funktion geht danach weiter?!?

Danach ist dein Code dann etwas lesbarer und man kann an die Fehlersuche gehen.
Antworten