Seite 1 von 1
Bild öffnen und Name in Variable speichern
Verfasst: Montag 8. Juni 2020, 14:32
von lucas97de
Hallo zusammen,
ich bin gerade dabei eine kleine Testanlage zu bauen. Das Ziel dieser ist die Bestimmung eines Farbanteils in einem Bild.
Der Code hierfür funktioniert ohne Probleme.
Das Problem das ich jetzt habe, ist folgendes:
Am Ende soll die Anlage von Leuten benutzt werden, die keine Ahnung haben von Python (ich eigentlich auch nicht).
Derzeit muss man in meinem Code noch jedes mal das Bild manuell eintippen. Da können natürlich schnell Fehler passieren...
Ich habe mir erhofft, dass es eine Möglichkeit gibt, eine Oberfläche zu schaffen, die quasi den Explorer öffnet und man dann ein Bild
anklicken kann, welches dann auch automatisch in meinen Code übernommen wird.
Hat dafür jemand Tipps? Ich habe bisher nicht viel Erfahrung mit Python und noch weniger mit Oberflächen..
Vielen Dank!
Mein bisheriger Code:
Code: Alles auswählen
import cv2
import numpy as np
img = cv2.imread("Testbild 5%.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_range = np.array([100, 50, 50])
upper_range = np.array([130, 255, 255])
mask = cv2.inRange(hsv, lower_range, upper_range)
img_size =img.size/3
# cv2.imshow("Image", img)
# cv2.imshow("Mask", mask)
pixels = cv2.countNonZero(mask)
Ratio = ((100/img_size)*pixels)
print("Das gesamte Bild besteht aus",round(img_size), "Pixeln")
print("Das Bild beinhaltet", pixels, "blaue Pixel")
print("Der Blauanteil beträgt damit: ",round(Ratio,2), "Prozent")
cv2.waitKey(0)
cv2.destroyAllWindows()
Re: Bild öffnen und Name in Variable speichern
Verfasst: Montag 8. Juni 2020, 15:32
von __blackjack__
@lucas97de: Anmerkungen zum Quelltext: Namen sollten nicht kryptisch abgekürzt werden. Wenn man `image` meint, sollte man nicht `img` schreiben.
`mask` könnte man besser benennen, so das der Leser auch weiss was die Maske bedeutet.
`image_size` ist irreführend weil es nicht `image.size` entspricht, sondern die Anzahl der Pixel beschreiben soll. Den Wert sollte man auch nicht runden müssen, zumal man `round()` nicht verwendet um eine Anzeige auf eine bestimmte Anzahl von Nachkommastellen zu begrenzen. Dafür gibt es die Formatanweiungen bei den Platzhaltern bei der Zeichenkettenformatierung.
`pixels` enthält eine Anzahl und keine Pixel, und welche Pixel das sind könnte man auch in den Namen schreiben.
Prozent und Verhältnis sind unterschiedliche Werte. Also ist entweder `ratio` falsch benannt, oder es wird dort der falsche Wert zugewiesen. Ich würde es bei Verhältnis lassen und dann später bei der Ausgabe die Formatierung für Prozent verwenden. Namen schreibt man zudem klein_mit_unterstrichen. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).
Zwischenstand:
Code: Alles auswählen
#!/usr/bin/env python3
import cv2
import numpy as np
def main():
show_image = False
image = cv2.imread("Testbild 5%.jpg")
blue_pixels_mask = cv2.inRange(
cv2.cvtColor(image, cv2.COLOR_BGR2HSV),
np.array([100, 50, 50]),
np.array([130, 255, 255]),
)
total_pixel_count = image.size // 3
if show_image:
cv2.imshow("Image", image)
cv2.imshow("Mask", blue_pixels_mask)
blue_pixel_count = cv2.countNonZero(blue_pixels_mask)
blue_ratio = blue_pixel_count / total_pixel_count
print(f"Das gesamte Bild besteht aus{total_pixel_count} Pixeln.")
print(f"Das Bild beinhaltet {blue_pixel_count} blaue Pixel.")
print(f"Der Blauanteil beträgt damit: {blue_ratio:0.2%}.")
if show_image:
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
Eine Datei wird man wohl am einfachsten mit dem `tkinter.filedialog`-Modul vom Benutzer erfragen können.
Re: Bild öffnen und Name in Variable speichern
Verfasst: Dienstag 9. Juni 2020, 09:05
von lucas97de
Danke schonmal fürs aufräumen von dem Code
Mit:
Code: Alles auswählen
a = Tk()
def mfileopen():
file1 = filedialog.askopenfile()
label=Label(text=file1).pack()
button = Button(text="open file", command=mfileopen).pack()
a.mainloop()
kann ich ein den Pfad von dem Bild in file1 speichern. Aber wie kann ich von außerhalb der Funktion darauf zugreifen?

Re: Bild öffnen und Name in Variable speichern
Verfasst: Dienstag 9. Juni 2020, 09:20
von peterpy
Hallo Lucas97de,
gib deiner Funktion ein
mit
und greife dann auf die Funktion zu.
Gruss
Peter
Re: Bild öffnen und Name in Variable speichern
Verfasst: Dienstag 9. Juni 2020, 09:36
von lucas97de
So? Dann schmeißt er mir diesen Fehler:
File "C:/Python/Code/venv/Blautest.py", line 45, in <module>
main()
File "C:/Python/Code/venv/Blautest.py", line 20, in main
image = cv2.imread(mfileopen())
SystemError: <built-in function imread> returned NULL without setting an error
Code: Alles auswählen
import cv2
import numpy as np
from tkinter import *
from PIL import ImageTk, Image
from tkinter import filedialog
a = Tk()
def mfileopen():
file1 = filedialog.askopenfile()
label=Label(text=file1).pack()
return file1
button = Button(text="open file", command=mfileopen).pack()
def main():
show_image = False
image = cv2.imread(mfileopen())
blue_pixels_mask = cv2.inRange(
cv2.cvtColor(image, cv2.COLOR_BGR2HSV),
np.array([100, 50, 50]),
np.array([130, 255, 255]),
)
total_pixel_count = image.size // 3
if show_image:
cv2.imshow("Image", image)
cv2.imshow("Mask", blue_pixels_mask)
blue_pixel_count = cv2.countNonZero(blue_pixels_mask)
blue_ratio = blue_pixel_count / total_pixel_count
print(f"Das gesamte Bild besteht aus{total_pixel_count} Pixeln.")
print(f"Das Bild beinhaltet {blue_pixel_count} blaue Pixel.")
print(f"Der Blauanteil beträgt damit: {blue_ratio:0.2%}.")
if show_image:
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
a.mainloop()
Re: Bild öffnen und Name in Variable speichern
Verfasst: Dienstag 9. Juni 2020, 11:00
von peterpy
Hallo lucas97de,
Bitte vergiss die Sternimporte!
ein Beispiel:
Code: Alles auswählen
from tkinter import Tk, Button, filedialog
def ausgebe_speicherort():
pfad_datei = oeffne_file()
print("Ausgebe", pfad_datei)
def oeffne_file():
oeffne= filedialog.askopenfilename()
pfad_datei = oeffne
print("Datei geoeffnet", pfad_datei)
return pfad_datei
def main():
root = Tk()
taste_oeffne = Button(root, command=ausgebe_speicherort, text="Öffne")
taste_oeffne.pack()
root.mainloop()
if __name__ == "__main__":
main()
Gruss
Peter
Re: Bild öffnen und Name in Variable speichern
Verfasst: Dienstag 9. Juni 2020, 11:06
von Sirius3
Keine *-Importe. tkinter wird üblicherweise als `import tkinter as tk` importiert. `a` ist ein besonders schlechter Name für eine Tk-Instanz. Außerdem steht der Code außerhalb der main-Funktion, was nicht sein sollte. `pack` liefert None als Rückgabewert, also sowohl `button` als auch `label` sind unsinnig, werden aber auch gar nicht benutzt. Man erstellt nicht nachträglich irgendwelche Labels. Diese werden am Anfang beim Aufbau des Fensters schon angelegt.
Was soll denn die `1` bei `file1`? Die Funktion askopenfile liefert tatsächlich ein File-Objekt (zu einer Textdatei), Du willst aber einen DateiNAMEN. Dafür gibt es eine andere passendere Funktion.