簡體   English   中英

系統錯誤:<built-in function imread> 返回 NULL 沒有設置錯誤(tkinter)</built-in>

[英]SystemError: <built-in function imread> returned NULL without setting an error (tkinter)

我正在使用我的 keras model 使用改進的 tkinter 程序來檢測 2 個類別,以對蝴蝶物種進行分類。

import tkinter as tk
from tkinter import filedialog
from tkinter import *
from PIL import ImageTk, Image
import numpy
import cv2

import tensorflow as tf
model = tf.keras.models.load_model("64x300-CNN.model")

classes = ["real", "fake"]

top=tk.Tk()
top.geometry('800x600')
top.title('Butterfly Classification')
top.configure(background='#CDCDCD')
label=Label(top,background='#CDCDCD', font=('arial',15,'bold'))
sign_image = Label(top)

def prepare(filepath):
    IMG_SIZE = 50  # 50 in txt-based
    img_array = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)  # read in the image, convert to grayscale
    new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))  # resize image to match model's expected sizing
    return new_array.reshape(-1, IMG_SIZE, IMG_SIZE, 1)  # return the image with shaping that TF wants.

def classify(file_path):
    global label_packed
    new_array = cv2.imread(file_path, 1)
    pred = model.predict([prepare(new_array)])
    sign = classes[pred]
    print(sign)
    label.configure(foreground='#011638', text=sign)

def show_classify_button(file_path):
    classify_b=Button(top,text="Classify Image",
    command=lambda: classify(file_path),padx=10,pady=5)
    classify_b.configure(background='#364156', foreground='white',
    font=('arial',10,'bold'))
    classify_b.place(relx=0.79,rely=0.46)

def upload_image():
    try:
        file_path=filedialog.askopenfilename()
        uploaded=Image.open(file_path)
        uploaded.thumbnail(((top.winfo_width()/2.25),
        (top.winfo_height()/2.25)))
        im=ImageTk.PhotoImage(uploaded)
        sign_image.configure(image=im)
        sign_image.image=im
        label.configure(text='')
        show_classify_button(file_path)
    except:
        pass

upload=Button(top,text="Upload an image",command=upload_image,
  padx=10,pady=5)

upload.configure(background='#364156', foreground='white',
    font=('arial',10,'bold'))

upload.pack(side=BOTTOM,pady=50)
sign_image.pack(side=BOTTOM,expand=True)
label.pack(side=BOTTOM,expand=True)
heading = Label(top, text="Butterfly Classification",pady=20, font=('arial',20,'bold'))

heading.configure(background='#CDCDCD',foreground='#364156')
heading.pack()
top.mainloop()

並得到了這個錯誤

SystemError:返回 NULL 未設置錯誤

我已嘗試從此處提出的類似問題中進行修復,但沒有運氣,我認為通過 tkinter 而不是通過文件路徑導入圖像時出現問題?

使用cv2.imread: "<built-in function imread> returned NULL without setting an error",好像打不開圖片或獲取數據

完整的錯誤信息

Tkinter 回調 Traceback 中的異常(最近一次調用最后一次):
文件“C:\Users\1rock\anaconda3\envs\machL\lib\ tkinter_init _.py”,第 1883 行,調用return self.func(*args) 文件“C:/Users/1rock/anaconda3/envs/ machL/fly.py”,第 36 行,在命令 = lambda 中:classify(file_path),padx=10,pady=5) 文件“C:/Users/1rock/anaconda3/envs/machL/fly.py”,第 29 行,在分類 pred = model.predict([prepare(new_array)]) 文件“C:/Users/1rock/anaconda3/envs/machL/fly.py”,第 22 行,准備 img_array = cv2.imread(filepath, cv2 .IMREAD_GRAYSCALE) # 讀入圖像,轉灰度 SystemError: returned NULL without setting an error

進程以退出代碼 0 結束

您實現的准備 function 執行加載、調整大小、重塑圖像的過程。 function cv2.imread的目的是從給定的文件路徑打開圖像。 但是您輸入了 function prepare(new_array)其中new_array已經是圖像本身,而不是文件路徑。 我建議進行兩個修復,盡管兩者最終是相等的。

此外, model.predict以實數輸出最后一層,而不是整數類型的 class 數字。 因此,在這種情況下,您必須使用model.predict_classes 此外,由於這些函數默認為批處理模式,盡管您只提供單個圖像,但您必須假設預測是一個數組,並對其進行索引。

第一個修復是提供文件路徑並在prepare function 中加載圖像。

def prepare(filepath):
    IMG_SIZE = 50  # 50 in txt-based
    img_array = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)  # read in the image, convert to grayscale
    new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))  # resize image to match model's expected sizing
    return new_array.reshape(-1, IMG_SIZE, IMG_SIZE, 1)  # return the image with shaping that TF wants.

def classify(file_path):
    global label_packed
    pred = model.predict_classes([prepare(file_path)])
    sign = classes[pred[0,0]]
    print(sign)
    label.configure(foreground='#011638', text=sign)

接下來是僅在prepare function 中執行整形。

def prepare(img_array):
    IMG_SIZE = 50  # 50 in txt-based
    new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))  # resize image to match model's expected sizing
    return new_array.reshape(-1, IMG_SIZE, IMG_SIZE, 1)  # return the image with shaping that TF wants.

def classify(file_path):
    global label_packed
    new_array = cv2.imread(file_path, 1)
    pred = model.predict_classes([prepare(new_array)])
    sign = classes[pred[0,0]]
    print(sign)
    label.configure(foreground='#011638', text=sign)

我還想說,這種調整大小的過程非常低效。 輸入管道的解決方案是在 Tensorflow 內部開發的預處理層。 您可以創建一個 model 作為輸入管道。

input_pipeline=tf.keras.models.Sequential([
  tf.keras.layers.experimental.preprocessing.Resizing(h,w,..),
  tf.keras.layers.experimental.preprocessing...
])
...
new_array=input_pipeline.predict(img_array)

或使用tf.image.resize ,因為它們可以在沒有顯式循環的情況下處理批量圖像,並提供更多可以簡單應用的功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM