我的Side Project每拍呷 | 研究Azure篇

更新 發佈閱讀 14 分鐘

今日進度3/14:
設定Azure AI Services(或 Azure Cognitive Services for Vision) 的OCR服務。
撰寫一個簡單的Python程式碼,使用一個營養標示圖片進行OCR服務呼叫,並印出返回的JSON結構,確認服務能正常運作。

一開始先在Vision Studio試用OCR服務,但不管是用筆電前鏡頭上傳、或是直接上傳電腦裡的圖片,都會有辨識不出來或是數據錯誤的問題,或是繁中辨識錯誤(我的蜜棗乾怎麼變成蛋蛋乾😫)

raw-image

看了JSON檔感覺很混亂,因為我沒用過OCR服務,我把一樣的照片丟去ChatGPT卻能解析正確,所以我問它這是正常的嗎?以下是它的回覆:


我這邊跟Azure OCR那種「電腦視覺」完全不一樣。
🔹我用到的技術其實是:圖像理解(Image Understanding):我能看懂圖片裡的文字和排版,像人類一樣「讀」出來,而不是逐像素辨識。
自然語言處理(NLP):我把圖裡的表格資訊轉換成結構化數據(例如「每份 218 大卡」),然後再進行計算。
邏輯運算:當你問「6份是多少」時,我就用簡單的乘法幫你算出答案。
換句話說,我沒有跑OCR,而是直接「看懂」圖片中的營養標示內容。這就是為什麼我不會遇到Azure OCR那種「數字亂跳、空值」的情況。
👉 所以可以理解成:Azure OCR → 先看圖 → 轉成文字 → 你自己再整理數據。
我這邊 → 直接理解圖 → 自動幫你抓重點並算數字。

然後我請它推薦比OCR更適合我的專案的服務,它推薦了Azure Document Intelligence(前身叫 Form Recognizer),這是專門處理文件的服務,特別適合表格、發票、報表之類結構化文檔。它的優勢在於能識別文字之外,還能提取「欄位名稱 + 對應值」的 key-value 結構,非常方便輸出 JSON 格式,用於自動化流程。

於是我就改用Document Intelligence,這樣也能避免萬一用戶拍照模糊導致OCR辨識錯誤的問題。

然後我發現Gemini的Gem原來已經免費開放使用了,立刻開一個Gem來專門處理這個專案!
目前為止跟Gemini的協作都還算滿意,以下的流程都是在Gem裡面討論出來的:

👽=我
🫡=Gemini

👽我決定要改用Document Intelligence文件智慧服務,而非OCR!
🫡這個改動方向非常正確!既然舊的OCR辨識效果不佳,果斷換成更強大的Azure AI文件智慧服務是提升準確度的關鍵一步。它不只是單純的文字辨識,更擅長處理結構化的文件,這對我們擷取營養標示的表格數據來說是個大優勢。舊的OCR服務可能更偏向於通用的文字辨識,對於不規則的字體、複雜的背景或表格格式表現不佳。但文件智慧服務專為處理文件而設計,它能:

  • 精確辨識表格與欄位: 營養標示的格式通常是表格,文件智慧服務能自動偵測表格結構,並辨識出「每份」、「每100克」、「熱量」、「蛋白質」等欄位,並將其與對應的數值配對。
  • 提取關鍵-數值配對:不僅是表格,即使是非表格的文字,它也能將「鈉含量:xxx 毫克」這類資訊準確地配對擷取。
  • 優化後的讀取模型:它的「讀取」模型針對文件處理進行了優化,能更精準地辨識印刷體、手寫字,以及高密度的文字。這對那些字體小、排版密集的營養標示特別有用。

👽接下來的開發計畫(第3天)
🫡好的,既然決定轉換技術,我們的開發計畫也需要調整。接下來的重點將是專注於整合文件智慧服務,並設計一個更穩固的數據處理流程。

  1. 調整數據擷取流程
  • 使用文件智慧服務API: 我們會用Python呼叫Azure AI文件智慧服務的Layout API(版面配置)或Read API (讀取),將用戶上傳的營養標示圖片傳送過去。
  • 處理回傳的JSON數據:文件智慧服務會回傳一個包含文字、表格、欄位位置等資訊的JSON檔案。我們需要編寫程式碼,從這個結構化數據中精準地提取出我們需要的營養素(例如:熱量、蛋白質、脂肪、碳水化合物、鈉、糖)及其對應的數值。

    2. 建立資料正規化與驗證機制
  • 處理單位差異:營養標示上的單位可能多樣化,例如:「g」、「mg」、「每份」、「每100公克」。我們的程式必須能聰明地辨識這些單位,並將所有數據正規化為統一的標準(例如:每份的克數或毫克數),才能進行後續的計算。
  • 處理數據缺失:如果圖片模糊導致特定營養素無法辨識,我們需要設計一個錯誤處理機制,提示用戶重新拍攝或手動輸入。

👽那要去哪裡可以試用這個服務?
🫡Azure AI 文件智慧服務 (Document Intelligence) 有它專屬的視覺化工具,叫做 Document Intelligence Studio。它不像 Vision Studio 那樣是通用型的,而是專門為了處理文件、表格、表單等結構化資料而設計的。在網站裡,你會看到幾個不同的模型可以試用,我們需要的是 「Read」 或 「Layout」 這兩個模型。Read (閱讀):專門用來擷取高品質的列印和手寫文字。Layout (版面配置):這個更強大,它不僅能擷取文字,還能同時辨識表格、標籤、選取標記等結構化資訊。將營養標示的圖片上傳到「Layout」模型,你就能看到它回傳的結構化 JSON 數據,裡面會清楚標示出每個表格、行、列的資訊,這會比通用型 OCR 的純文字辨識結果更有用。

👽太好了!那我要用Layout功能,感覺超級聰明!


決定使用Latout後,就開啟VS Code來測試囉!

步驟:

1. 終端機安裝 pip install azure-ai-documentintelligence
2. 初始化客戶端
3. 讀取圖片
4. 呼叫分析功能
5. 處理結果:API會回傳一個操作物件。需要等待分析完成,然後從結果中提取出我們 需要的表格 (tables) 和內容 (content)。
6. 解析數據:從回傳的JSON結構化數據中,找到表格裡的「蛋白質」、「碳水化合物」等欄位,並取出它們對應的數值。

*但因為串接LINE BOT不是今天的進度,所以我先把程式碼設計成用tkinter可以呈現的(直接開啟視窗讓我上傳檔案)

最後再加入一個def函式extract_nutrition_data,以利從tables中提取這些數據:

def extract_nutrition_data(tables):
if not tables:
return None

# 假設營養標示總是在第一個表格
nutrition_table = tables[0]

data = {}

# 建立一個從營養素名稱到其在表格中行索引的對應表
nutrient_row_mapping = {
'熱量': 4,
'蛋白質': 5,
'脂肪': 6,
'碳水化合物': 9,
'糖': 10,
'鈉': 11
}

# 遍歷表格中的所有單元格
for cell in nutrition_table.cells:
# 尋找關鍵營養素的名稱
if cell.row_index in nutrient_row_mapping.values() and cell.column_index == 0:
nutrient_name = cell.content.replace(' ', '')

# 找到對應行的「每份」和「每100公克」數值
for other_cell in nutrition_table.cells:
if other_cell.row_index == cell.row_index and other_cell.column_index == 1:
data[f'{nutrient_name}_per_serving'] = other_cell.content
elif other_cell.row_index == cell.row_index and other_cell.column_index == 2:
data[f'{nutrient_name}_per_100g'] = other_cell.content

# 這裡可以加上數據清洗的邏輯,將字串轉成數字
cleaned_data = {}
for key, value in data.items():
# 移除單位,例如 '大卡', '公克', '毫克'
numeric_value = value.replace(' 大卡', '').replace(' 公克', '').replace(' 毫克', '').replace(' ', '')
try:
cleaned_data[key] = float(numeric_value)
except ValueError:
cleaned_data[key] = numeric_value # 如果無法轉換,保留原始字串

return cleaned_data

# 範例使用
# from the OCR result, get tables object
# extracted_data = extract_nutrition_data(result.tables)
# print(extracted_data)

終於抓到營養數據了✨

{
"熱量_per_serving": 180.0,
"熱量_per_100g": 564.0,
"蛋白質_per_serving": 2.3,
"蛋白質_per_100g": 7.2,
"脂肪_per_serving": 11.2,
"脂肪_per_100g": 35.0,
"碳水化合物_per_serving": 17.6,
"碳水化合物_per_100g": 55.0,
"糖_per_serving": 1.2,
"糖_per_100g": 3.6,
"鈉_per_serving": 187.0,
"鈉_per_100g": 585.0
}

資訊很正確!試了用筆電前鏡頭也可以。請讓我讚嘆它的聰明

以上再融合昨天寫好的GRADIO版本程式碼,讓用戶輸入身高、體重、性別、吃了一包/半包/四分之一包:

raw-image
raw-image
raw-image

👽我換了一個測試資料,結果遇到了「脂肪」辨識錯誤,正確是22.4克,但顯示0克,我猜是因為脂肪的下方還分為飽和脂肪跟反式脂肪,所以辨識錯誤?
🫡你說的沒錯,要解決這個問題,我們需要讓程式碼能更智慧地處理「脂肪」這個特殊情況。最簡單也最有效的方法是:
優先尋找「脂肪」這個關鍵字:這是我們的首選,如果找到了,就提取它的數值。
如果沒有找到「脂肪」:那麼退而求其次,將「飽和脂肪」和「反式脂肪」的數值相加,作為「總脂肪」。

# --- 針對脂肪的特殊處理 ---
total_fat_per_serving = cleaned_data.get('脂肪_per_serving_str', 0)

if total_fat_per_serving == 0:
# 如果總脂肪為0,嘗試將飽和脂肪和反式脂肪相加
saturated_fat = cleaned_data.get('飽和脂肪_per_serving_str', 0)
trans_fat = cleaned_data.get('反式脂肪_per_serving_str', 0)
total_fat_per_serving = saturated_fat + trans_fat

cleaned_data['脂肪_per_serving_str'] = total_fat_per_serving

return cleaned_data, None
這一版終於成功了!今天也修正了很多東西,超有趣的🤣

這一版終於成功了!今天也修正了很多東西,超有趣的🤣

明日進度:

由於明天原訂進度於今天提前做完,故進度改為:
在LINE Developers後台設定BOT的基本資訊、撰寫基於 Python Flask 或 FastAPI 的簡單後端程式,使其能接收 LINE 傳來的文字訊息,並回覆「哈囉!」等基本文字。

加油!!

留言
avatar-img
留言分享你的想法!
avatar-img
Galing的腦內劇場
1會員
15內容數
學習AI的新手,在這邊分享學習筆記跟知識,希望文組轉戰AI也可以闖出一片天💪 大學學的是戲劇,擁有服務業12年經驗,擔任銷售顧問;2025.07開始學習python與AI商業應用,目標是讓職涯變得更自由有彈性,做出好玩有趣的東西! 💬喜歡打電動、看動畫、K-pop佛系追星,偶爾可能會出現這些主題的文章。
Galing的腦內劇場的其他內容
2025/08/21
今日進度 2/14 : 今天主要針對成分表裡的「食品添加物」做分類,初步分成:香料、防腐劑、乳化劑、色素、其他。 使用者輸入文字內容後,系統就能輸出圓餅圖或其他視覺化的分析結果。 但是!實作之後改動了超多東西的,不停發現盲點... ...
Thumbnail
2025/08/21
今日進度 2/14 : 今天主要針對成分表裡的「食品添加物」做分類,初步分成:香料、防腐劑、乳化劑、色素、其他。 使用者輸入文字內容後,系統就能輸出圓餅圖或其他視覺化的分析結果。 但是!實作之後改動了超多東西的,不停發現盲點... ...
Thumbnail
2025/08/20
繼續做我的AI Side Project:「每拍呷-營養標示一拍就懂」🫡 ✔️今日進度1/14:確認營養標示算法、蒐集資料、統整國民健康署DIRS、把熱量&鈉&糖&脂肪換算成白飯&醬油&方糖&沙拉油、暫時先用GRADIO介面做初步的測試。
Thumbnail
2025/08/20
繼續做我的AI Side Project:「每拍呷-營養標示一拍就懂」🫡 ✔️今日進度1/14:確認營養標示算法、蒐集資料、統整國民健康署DIRS、把熱量&鈉&糖&脂肪換算成白飯&醬油&方糖&沙拉油、暫時先用GRADIO介面做初步的測試。
Thumbnail
2025/08/19
在初步學習了Python、Gradio、Azure、SQL&NoSQL、LINE BOT之後,終於要開始做我的第一個AI Side Project--每拍呷-營養標示一拍就懂! 目標:兩周內完成(瑟瑟發抖)
Thumbnail
2025/08/19
在初步學習了Python、Gradio、Azure、SQL&NoSQL、LINE BOT之後,終於要開始做我的第一個AI Side Project--每拍呷-營養標示一拍就懂! 目標:兩周內完成(瑟瑟發抖)
Thumbnail
看更多
你可能也想看
Thumbnail
目前使用ideogram,免費的額度一天 10 slow prompts,然後需要等待幾十秒到一分多鐘的時間產圖。產出來的圖片還不錯,免費方案的也有幾款風格可以選擇,但產出的圖片只能下載非最高畫質的JPEG檔。
Thumbnail
目前使用ideogram,免費的額度一天 10 slow prompts,然後需要等待幾十秒到一分多鐘的時間產圖。產出來的圖片還不錯,免費方案的也有幾款風格可以選擇,但產出的圖片只能下載非最高畫質的JPEG檔。
Thumbnail
本週報告涵蓋電商網站評論分析工具VOC.AI的應用和在Shopify團隊埋設活動頁的追蹤事件等議題。詳細介紹了VOC.AI的功能和分析結果,以及在Shopify上使用Microsoft的分析工具Clarity。
Thumbnail
本週報告涵蓋電商網站評論分析工具VOC.AI的應用和在Shopify團隊埋設活動頁的追蹤事件等議題。詳細介紹了VOC.AI的功能和分析結果,以及在Shopify上使用Microsoft的分析工具Clarity。
Thumbnail
最近要來考證照,把準備過程跟大家分享 選出正確完成句子的答案。 您有一個資料庫,其中包含員工及其照片的清單。您正在標記員工的新照片。對於以下每個陳述,如果該陳述為真,則選擇“是”。否則,選擇「否」 您需要開發一個行動應用程序,供員工在旅行時掃描和儲存他們的費用。您應該使用哪種類型的
Thumbnail
最近要來考證照,把準備過程跟大家分享 選出正確完成句子的答案。 您有一個資料庫,其中包含員工及其照片的清單。您正在標記員工的新照片。對於以下每個陳述,如果該陳述為真,則選擇“是”。否則,選擇「否」 您需要開發一個行動應用程序,供員工在旅行時掃描和儲存他們的費用。您應該使用哪種類型的
Thumbnail
在數字化時代,PDF文件廣泛使用,但傳統處理方式顯得力不從心。本文推薦pdftopdf.ai等工具,通過OCR識別,將圖片中的文字轉化為可編輯、可搜索的文本。探討PDF文檔分析的AI工具,功能和價格。描述其用途以解決掃描件中文字無法直接搜索的困擾,提高工作效率。
Thumbnail
在數字化時代,PDF文件廣泛使用,但傳統處理方式顯得力不從心。本文推薦pdftopdf.ai等工具,通過OCR識別,將圖片中的文字轉化為可編輯、可搜索的文本。探討PDF文檔分析的AI工具,功能和價格。描述其用途以解決掃描件中文字無法直接搜索的困擾,提高工作效率。
Thumbnail
學習如何將掃描的PDF轉換為可搜索文本,並高效管理和查找文件。探索先進的OCR技術如何提升文檔處理效率。
Thumbnail
學習如何將掃描的PDF轉換為可搜索文本,並高效管理和查找文件。探索先進的OCR技術如何提升文檔處理效率。
Thumbnail
這篇要搭建一個同時生成寫實照片跟動漫風格圖片的工作流,還可以幫線稿上色。
Thumbnail
這篇要搭建一個同時生成寫實照片跟動漫風格圖片的工作流,還可以幫線稿上色。
Thumbnail
先前幾篇筆記介紹了網路請求,瀏覽器儲存資料的方式,那麼實務上,前端最常需要發送網路請求的時候,就是透過呼叫 API,去向後端工程師發送/請求資料,所以今天來記錄什麼是 API吧!
Thumbnail
先前幾篇筆記介紹了網路請求,瀏覽器儲存資料的方式,那麼實務上,前端最常需要發送網路請求的時候,就是透過呼叫 API,去向後端工程師發送/請求資料,所以今天來記錄什麼是 API吧!
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News