最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python調(diào)用豆包API實現(xiàn)批量提取圖片信息

 更新時間:2025年11月04日 10:03:08   作者:PythonFun  
這篇文章主要為大家詳細介紹了Python如何通過調(diào)用豆包API實現(xiàn)批量提取圖片信息的功能,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下

一、問題的由來

最近,有網(wǎng)友說,他一天要處理很多100多份訂單截圖,提取其中的發(fā)貨單號、車號、凈重、品種、出廠日期等,并存入到Excel文件當中。普通的人工錄入太慢,電腦OCR識圖又不太準確,還要來回復制粘貼,非常的麻煩,而且耗時耗力。因此,他想編寫一個批量處理工具,實現(xiàn)批量化操作訂單截圖,自動提取指定信息,然后可以轉(zhuǎn)到Excel里。

問題的由來

二、問題的分析

這個問題與提取發(fā)票信息有點兒像,不過發(fā)票一般都是pdf格式,而且很清晰,這是圖片,一般都是手機拍攝的,不僅不規(guī)則,有時還不太清晰,所以要準確提取難度有點兒大。我想了一下,提供了兩套解決的思路。

1. 用智能體的方法

我們進入豆包,在左側(cè)菜單欄中,點擊【更多】,找到【AI智能體】,再點擊右上角的【創(chuàng)建智能體】,

創(chuàng)建智能體

然后,在設(shè)定描述中輸入相關(guān)指令,并為這個智能體設(shè)計一個名稱,可以通過AI一鍵生成。

錄入指令

完成智能體編寫后,提交豆包審核,審核通過后,我們就可以通過提交圖片來實現(xiàn)相關(guān)信息的提交了。不過這種方法,一次只能提交一張圖片,效果如下所示:

智能體識別相關(guān)信息

但這種方法的好處是可以在手機上提交識別,速度還挺快的,準確率也很好,而且操作免費。

2. Python編程法

另一種方法有點兒復雜,但可以實現(xiàn)批量操作,無人職守就可以完成提取圖片信息的任務,但是就得消耗豆包API的額度,不過貌似價格不是很高。在編程前,可以去申請一個豆包api。

申請完之后,在控制臺找到多模態(tài)處理的AI樣例代碼如下:

import os
from openai import OpenAI

# 初始化客戶端
client = OpenAI(
    base_url="https://ark.cn-beijing.volces.com/api/v3",
    api_key="<API_KEY>"  # 這里修改了一下,直接為變量賦值,輸入你的API_KEY即可
)

response = client.chat.completions.create(
    model="doubao-seed-1-6-250615",  #豆包的多模態(tài)處理模型。
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://wx3.sinaimg.cn/orj480/7ffa58d5ly1i44lggggjxj20k00zkjse.jpg"
                    },
                },
                {"type": "text", "text": "提取圖片中的文字信息,其它不要顯示。"},
            ],
        }
    ],
)

# 提取content內(nèi)容
content = response.choices[0].message.content
print("提取的內(nèi)容:")
print(content)

根據(jù)上面的樣例代碼,我們借助Python中的Tkinter框架,編寫了一款圖片信息提取工具,實現(xiàn)包括圖片的導入、預覽、信息提取、復制等功能,基本的樣式如下:

圖片識別工具

軟件編寫過程中處理了底部按鈕放大后變形,圖片預覽框忽大忽小等問題,為信息提取和圖片預覽區(qū)還設(shè)置了LabelFrame,便于操作。

軟件可以自動檢測本地是否加載API Key,如果沒有加載,就會彈窗提醒輸入。如果已經(jīng)加載API,就會提供已經(jīng)加載API。

軟件提取信息,一方面會顯示在界面中部右側(cè),中間用制表位隔開,生成完,點擊復制信息就可以粘貼到Excel當中。通過打開目錄,還可以查看已經(jīng)寫入本地的信息。

3. 代碼展示

import os
import json
from tkinter import Tk, Label, Entry, filedialog, messagebox, StringVar, END, Button, LEFT,LabelFrame,Frame, Toplevel
from tkinter.scrolledtext import ScrolledText
from tkinter import PhotoImage, font
import threading
import base64
import pyperclip
from pathlib import Path
from openai import OpenAI
from PIL import Image, ImageTk

class ImageEssayEvaluator:
    def __init__(self, root):
        self.root = root
        self.root.title("圖片信息提取工具 | By Gordon")
        self.setup_ui()
        self.api = None
        self.output_dir = os.path.join(os.getcwd(), "識別結(jié)果")
        os.makedirs(self.output_dir, exist_ok=True)
        self.current_scale = 1.0  # Track current zoom scale
        self.image_files = []  # List to store multiple image paths
        self.current_image_index = 0  # Track current image index

        json_filename = "config.json"
        if not os.path.exists(json_filename):
            with open(json_filename, "w") as json_file:
                json.dump({"api_key": self.api}, json_file)
            print("JSON 文件已創(chuàng)建。")
        else:
            with open(json_filename, "r") as json_file:
                data = json.load(json_file)
            self.api = data.get("api")
        if self.api is None:
            self.show_settings()
        self.update_api_button_text()

    def update_api_button_text(self):
        """根據(jù)API狀態(tài)更新按鈕文本"""
        if self.api:
            self.api_button.config(text="已加載API")
        else:
            self.api_button.config(text="設(shè)置API")

    def setup_ui(self):
        self.info_var = StringVar()
        self.info_var.set("Tip: 請導入圖片,識別結(jié)果將顯示在下方文本框")
        Label(self.root, textvariable=self.info_var, font=("微軟雅黑", 12)).pack(pady=5)

        frame = Frame(self.root)
        frame.pack(padx=6)

        Label(frame, text="圖片路徑:", font=("微軟雅黑", 12)).pack(side='left')
        self.image_path_entry = Entry(frame, width=60, font=("微軟雅黑", 12))
        self.image_path_entry.pack(side=LEFT, padx=5, pady=5)

        self.api_button = Button(frame, text="設(shè)置API", font=("微軟雅黑", 12), command=self.show_settings)
        self.api_button.pack()

        # Create a frame for the image and text display
        main_frame = Frame(self.root)
        main_frame.pack(padx=5, pady=5)

        # Left Frame for Image Preview (no fixed height)
        #self.preview_frame = Frame(main_frame, width=500)
        self.preview_frame = LabelFrame(main_frame, text="  預覽圖片文件",font=("微軟雅黑", 12), width=400, height=460, padx=1, pady=1)
        self.preview_frame.grid(row=0, column=0, padx=10, pady=10)
        self.preview_frame.pack_propagate(False)

        # Image preview label
        self.image_label = Label(self.preview_frame)
        self.image_label.pack(padx=10, pady=10)

        # Frame for zoom and navigation buttons
        button_frame = Frame(self.preview_frame)
        button_frame.pack(side='bottom',pady=5)

        # Zoom buttons (Up and Down) and Navigation buttons (Previous and Next)
        self.zoom_in_button = Button(button_frame, text="放大", font=("微軟雅黑", 12), command=self.zoom_in)
        self.zoom_in_button.pack(side=LEFT, padx=5)
        self.zoom_out_button = Button(button_frame, text="縮小", font=("微軟雅黑", 12), command=self.zoom_out)
        self.zoom_out_button.pack(side=LEFT, padx=5)
        self.prev_button = Button(button_frame, text="上一張", font=("微軟雅黑", 12), command=self.previous_image)
        self.prev_button.pack(side=LEFT, padx=5)
        self.next_button = Button(button_frame, text="下一張", font=("微軟雅黑", 12), command=self.next_image)
        self.next_button.pack(side=LEFT, padx=5)

        # Right Frame for Text Display
        #self.text_frame = Frame(main_frame, width=400, height=300)
        self.text_frame = LabelFrame(main_frame, text="  提取信息顯示 ", font=("微軟雅黑", 12), width=400, height=300, padx=1, pady=1)
        self.text_frame.grid(row=0, column=1, padx=10, pady=10)
        # Text display area
        self.text_display = ScrolledText(self.text_frame, width=50, height=20, font=("微軟雅黑", 12))
        self.text_display.pack(padx=5, pady=5)
        button_frame = Frame(self.root)
        button_frame.pack(expand=True)
        # Other buttons
        Button(button_frame, text="導入圖片", font=("微軟雅黑", 12), command=self.load_image).pack(side="left", padx=90, pady=10)
        Button(button_frame, text="提取信息", font=("微軟雅黑", 12), command=self.start_evaluation).pack(side="left", padx=60, pady=10)
        Button(button_frame, text="打開目錄", font=("微軟雅黑", 12), command=self.open_output_dir).pack(side="left", padx=60, pady=10)
        Button(button_frame, text="復制信息", font=("微軟雅黑", 12), command=self.copy_info).pack(side="left", padx=60, pady=10)

    def show_settings(self):
        self.settings_window = Toplevel(self.root)
        self.settings_window.attributes('-topmost', True)
        self.settings_window.title("豆包 API設(shè)置")

        Label(self.settings_window, text="請把kimi的API放在這里,使用ctrl+V:").pack(pady=5)
        self.api_var = StringVar()
        self.entry = Entry(self.settings_window, textvariable=self.api_var, width=30, font=("微軟雅黑", 12))
        self.entry.pack()
        confirm_button = Button(self.settings_window, text="確認", command=lambda: self.apply_settings())
        confirm_button.pack(pady=10)

        screen_width = self.settings_window.winfo_screenwidth()
        screen_height = self.settings_window.winfo_screenheight()
        self.settings_window.update_idletasks()
        window_width = self.settings_window.winfo_width()
        window_height = self.settings_window.winfo_height()

        x_position = (screen_width - window_width) // 2
        y_position = (screen_height - window_height) // 2
        self.settings_window.geometry(f"{window_width}x{window_height}+{x_position}+{y_position}")

    def apply_settings(self):
        new_time = self.api_var.get()
        self.api = new_time.strip()
        data = {'api': self.api}
        with open('config.json', 'w+') as f:
            json.dump(data, f, indent=4)
        self.settings_window.destroy()

    def copy_info(self):
        pyperclip.copy(self.text_display.get(1.0, END))
    def load_image(self): 
        if len(str(self.api)) < 10:
            messagebox.showwarning("警告!", "API設(shè)置不正確或者沒有")
            self.show_settings()
            return

        # 選擇導入方式
        choice = messagebox.askquestion("選擇導入方式", "是:加載多個圖片文件\n否:加載整個文件夾中的圖片")

        image_paths = []

        if choice == 'yes':
            # 導入多個圖片文件
            file_paths = filedialog.askopenfilenames(
                title="選擇圖片",
                filetypes=[("圖片文件", "*.jpg;*.png;*.jpeg;*.bmp")]
            )
            if file_paths:
                image_paths = [fp.replace("\\", "/") for fp in file_paths]
                # 顯示第一張圖片路徑到 entry
                self.image_path_entry.delete(0, END)
                self.image_path_entry.insert(0, image_paths[0])

        elif choice == 'no':
            # 導入整個文件夾中的圖片
            folder_path = filedialog.askdirectory(title="選擇文件夾")
            if folder_path:
                folder_path = folder_path.replace("\\", "/")  # 替換為統(tǒng)一的路徑分隔符
                for fname in os.listdir(folder_path):
                    if fname.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp')):
                        image_path = os.path.join(folder_path, fname).replace("\\", "/")
                        image_paths.append(image_path)
                image_paths.sort()

                # 設(shè)置 entry 顯示文件夾路徑
                self.image_path_entry.delete(0, END)
                self.image_path_entry.insert(0, folder_path)

        # 若成功導入圖片路徑
        if image_paths:
            self.image_files = image_paths
            self.current_image_index = 0
            self.current_scale = 1.0  # Reset zoom

            # 顯示狀態(tài)信息
            self.info_var.set(
                f"已加載圖片: {os.path.basename(self.image_files[self.current_image_index])} "
                f"({self.current_image_index + 1}/{len(self.image_files)})"
            )
            self.display_image(self.image_files[self.current_image_index])
            self.update_navigation_buttons()
        else:
            self.info_var.set("未選擇任何圖片")

    def update_navigation_buttons(self):
        """Enable or disable navigation buttons based on image list and current index"""
        if len(self.image_files) > 1:
            self.prev_button.config(state="normal" if self.current_image_index > 0 else "disabled")
            self.next_button.config(state="normal" if self.current_image_index < len(self.image_files) - 1 else "disabled")
        else:
            self.prev_button.config(state="disabled")
            self.next_button.config(state="disabled")

    def previous_image(self):
        if self.current_image_index > 0:
            self.current_image_index -= 1
            self.image_path_entry.delete(0, END)
            self.image_path_entry.insert(0, self.image_files[self.current_image_index])
            self.info_var.set(f"已加載圖片: {os.path.basename(self.image_files[self.current_image_index])} ({self.current_image_index + 1}/{len(self.image_files)})")
            self.current_scale = 1.0  # Reset zoom scale
            self.display_image(self.image_files[self.current_image_index])
            self.update_navigation_buttons()

    def next_image(self):
        if self.current_image_index < len(self.image_files) - 1:
            self.current_image_index += 1
            self.image_path_entry.delete(0, END)
            self.image_path_entry.insert(0, self.image_files[self.current_image_index])
            self.info_var.set(f"已加載圖片: {os.path.basename(self.image_files[self.current_image_index])} ({self.current_image_index + 1}/{len(self.image_files)})")
            self.current_scale = 1.0  # Reset zoom scale
            self.display_image(self.image_files[self.current_image_index])
            self.update_navigation_buttons()

    def display_image(self, image_path):
        # Open the image and display it as preview
        img = Image.open(image_path)
        # Estimate text area height (15 lines of font "微軟雅黑" size 12)
        text_font = font.Font(family="微軟雅黑", size=12)
        line_height = text_font.metrics("linespace")
        target_height = int(line_height * 15 * self.current_scale)
        # Calculate width based on aspect ratio
        original_width, original_height = img.size
        target_width = int(target_height * original_width / original_height)
        img = img.resize((target_width, target_height), Image.Resampling.LANCZOS)
        self.image_preview = ImageTk.PhotoImage(img)
        self.image_label.config(image=self.image_preview)

    def zoom_in(self):
        # Increase image size by 10%
        self.current_scale *= 1.1
        self.update_image()

    def zoom_out(self):
        # Decrease image size by 10%
        self.current_scale *= 0.9
        self.update_image()

    def update_image(self):
        if not self.image_files or self.current_image_index >= len(self.image_files):
            messagebox.showwarning("警告", "請先加載圖片")
            return

        image_path = self.image_files[self.current_image_index]

        try:
            img = Image.open(image_path)

            # Estimate text area height (15 lines of font "微軟雅黑" size 12)
            text_font = font.Font(family="微軟雅黑", size=12)
            line_height = text_font.metrics("linespace")
            target_height = int(line_height * 15 * self.current_scale)

            # Calculate width based on aspect ratio
            original_width, original_height = img.size
            target_width = int(target_height * original_width / original_height)

            img = img.resize((target_width, target_height), Image.Resampling.LANCZOS)
            self.image_preview = ImageTk.PhotoImage(img)
            self.image_label.config(image=self.image_preview)

            # 更新路徑欄顯示當前圖片(可選)
            self.image_path_entry.delete(0, END)
            self.image_path_entry.insert(0, image_path)

        except Exception as e:
            messagebox.showerror("錯誤", f"無法加載圖片:{e}")


    def start_evaluation(self):
        threading.Thread(target=self.evaluate_essay).start()
    def evaluate_essay(self):
        if not self.image_files:
            messagebox.showerror("錯誤", "請先導入圖片文件或文件夾!")
            return

        self.info_var.set("正在提取內(nèi)容,請稍候...")

        try:
            for file in self.image_files:
                result = self.chat_doubao(file)
                base_name = os.path.splitext(os.path.basename(file))[0]
                output_path = os.path.join(self.output_dir, f"{base_name}.txt")
                with open(output_path, "a+", encoding="utf-8") as f:
                    f.write(result)

            self.info_var.set("提取完成!")
        except Exception as e:
            messagebox.showerror("錯誤", f"提取失敗: {e}")
            self.info_var.set("提取失敗,請重試")

    def get_order(self):
        with open("order.txt","r",encoding="utf-8") as f:
            order = f.read().strip()
        return order
    def image_to_base64(self,image_path):
        # 獲取圖片文件的MIME類型
        ext = os.path.splitext(image_path)[1].lower()
        mime_type = f"image/{ext[1:]}" if ext in ['.jpg', '.jpeg', '.png', '.gif'] else "image/jpeg"
        
        with open(image_path, "rb") as image_file:
            # 讀取文件內(nèi)容并進行Base64編碼
            base64_data = base64.b64encode(image_file.read()).decode('utf-8')
            # 返回完整的data URI格式
            return f"data:{mime_type};base64,{base64_data}"
    def chat_doubao(self,local_image_path):
        # 初始化客戶端
        client = OpenAI(
            base_url="https://ark.cn-beijing.volces.com/api/v3",
            api_key="<YOUR API KEY>"  # 這里要輸入自己的API
        )

        try:
            # 轉(zhuǎn)換本地圖片為Base64編碼
            image_data = self.image_to_base64(local_image_path)
            
            # 調(diào)用API處理圖片
            response = client.chat.completions.create(
                model="doubao-seed-1-6-250615",
                messages=[
                    {
                        "role": "user",
                        "content": [
                            {
                                "type": "image_url",
                                "image_url": {
                                    "url": image_data  # 使用Base64編碼的本地圖片數(shù)據(jù)
                                },
                            },
                            {"type": "text", "text": self.get_order()},
                        ],
                    }
                ]
            )

            # 提取并打印內(nèi)容
            content = response.choices[0].message.content
            self.text_display.insert(END, f"{content}\n")
            self.text_display.see(END)
            # 更新預覽圖片顯示
            self.display_image(local_image_path)

            # 更新頂部路徑欄顯示
            self.image_path_entry.delete(0, END)
            self.image_path_entry.insert(0, local_image_path)

        except FileNotFoundError:
            self.text_display.insert('1.0',f"錯誤:找不到圖片文件 '{local_image_path}'")
        except Exception as e:
            print(f"處理過程中發(fā)生錯誤:{str(e)}")
        return content

    def open_output_dir(self):
        os.startfile(self.output_dir)


if __name__ == "__main__":
    root = Tk()
    app = ImageEssayEvaluator(root)
    root.mainloop()

上面程序中,為了實現(xiàn)本地圖片的讀取,我們通過image_to_base64這個函數(shù)進行圖像信息的轉(zhuǎn)化,如果不轉(zhuǎn)化,我們就得從網(wǎng)址里獲取,有可能需要網(wǎng)絡(luò)存儲桶,不僅不方便,也會延遲速度。

三、學后總結(jié)

1. 人工智能性能不斷提升,未來對于多模態(tài)數(shù)據(jù)如:圖片、音頻和視頻的處理就變得非常方便。借用Python批量處理的特點,我們可以很好地實現(xiàn)指定文本的提取和保存。

2. 此工具還可以拓展。把指令文件order.txt修改一下,通過修改指令可以實現(xiàn)發(fā)票信息提取、作文批改等功能。如果未來支持音頻和視頻,也可以這么操作。

到此這篇關(guān)于Python調(diào)用豆包API實現(xiàn)批量提取圖片信息的文章就介紹到這了,更多相關(guān)Python提取圖片信息內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python開發(fā)中避免過度優(yōu)化的7種常見場景

    Python開發(fā)中避免過度優(yōu)化的7種常見場景

    今天我們來聊一個超火但又常常讓人“翻車”的話題:過度優(yōu)化,很多開發(fā)者,特別是剛接觸Python的朋友,往往會被“高級技巧”迷了眼,結(jié)果搞得自己程序既不簡潔,又不易維護,那么,今天就來跟大家一起看看,Python開發(fā)中哪些“高級技巧”其實是過度優(yōu)化,應該盡量避免的
    2025-05-05
  • 簡單了解python 生成器 列表推導式 生成器表達式

    簡單了解python 生成器 列表推導式 生成器表達式

    這篇文章主要介紹了簡單了解python 生成器 列表推導式 生成器表達式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • Python錯誤AttributeError:?'NoneType' object?has?no?attribute問題的徹底解決方法

    Python錯誤AttributeError:?'NoneType' object?h

    在?Python?項目開發(fā)和調(diào)試過程中,經(jīng)常會碰到這樣一個異常信息AttributeError:?'NoneType'?object?has?no?attribute?'foo',本文將從問題產(chǎn)生的根源、常見觸發(fā)場景、深度排查方法,一直到多種修復策略與最佳實踐,需要的朋友可以參考下
    2025-07-07
  • 關(guān)于Python下的Matlab函數(shù)對應關(guān)系(Numpy)

    關(guān)于Python下的Matlab函數(shù)對應關(guān)系(Numpy)

    這篇文章主要介紹了關(guān)于Python下的Matlab函數(shù)對應關(guān)系(Numpy),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • python之PySide2安裝使用及QT Designer UI設(shè)計案例教程

    python之PySide2安裝使用及QT Designer UI設(shè)計案例教程

    這篇文章主要介紹了python之PySide2安裝使用及QT Designer UI設(shè)計案例教程,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 零基礎(chǔ)寫python爬蟲之爬蟲編寫全記錄

    零基礎(chǔ)寫python爬蟲之爬蟲編寫全記錄

    前面九篇文章從基礎(chǔ)到編寫都做了詳細的介紹了,第十篇么講究個十全十美,那么我們就來詳細記錄一下一個爬蟲程序如何一步步編寫出來的,各位看官可要看仔細了
    2014-11-11
  • Python matplotlib 畫圖窗口顯示到gui或者控制臺的實例

    Python matplotlib 畫圖窗口顯示到gui或者控制臺的實例

    今天小編就為大家分享一篇Python matplotlib 畫圖窗口顯示到gui或者控制臺的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • python函數(shù)形參用法實例分析

    python函數(shù)形參用法實例分析

    這篇文章主要介紹了python函數(shù)形參用法,較為詳細的講述了Python函數(shù)形參的功能、定義及使用技巧,需要的朋友可以參考下
    2015-08-08
  • python中找出numpy array數(shù)組的最值及其索引方法

    python中找出numpy array數(shù)組的最值及其索引方法

    下面小編就為大家分享一篇python中找出numpy array數(shù)組的最值及其索引方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Python 5種常見字符串去除空格操作的方法

    Python 5種常見字符串去除空格操作的方法

    這篇文章主要給大家分享的是Python 5種常見字符串去除空格操作的方法,包括有strip()方法、rstrip()方法、replace()方法、join()方法+split()方法,下面文章是詳細內(nèi)容,需要的朋友可以參考一下
    2021-11-11

最新評論

扎鲁特旗| 江陵县| 长海县| 香港 | 伽师县| 县级市| 寻乌县| 万源市| 井陉县| 辽中县| 孝义市| 大港区| 宣武区| 成安县| 额敏县| 黄浦区| 安庆市| 临沂市| 舒兰市| 大埔区| 德钦县| 那曲县| 舞钢市| 郯城县| 体育| 余庆县| 巫溪县| 冷水江市| 宜春市| 锡林郭勒盟| 垦利县| 横峰县| 介休市| 大邑县| 忻州市| 武宣县| 冀州市| 孟村| 峨眉山市| 青阳县| 于田县|