跳到主要內容

發表文章

用 NotebookLM AI 打造 Pikmin 蘑菇重生計算機

有玩《Pikmin Bloom》的玩家都知道,遊戲中的大蘑菇(例如「一般 神秘蘑菇」或「一般 紅色蘑菇」)被推毀後需要一段時間才會重生 。為了精準掌握下一次搶菇的時機,我決定透過 NotebookLM 的協助, 動手寫一個小工具:只要上傳包含挑戰剩餘時間(如「剩下20 分 47 秒」或「剩下1 小時 1 分 58 秒」)的遊戲截圖 ,系統就能自動推算出精確到秒的重生時間。 一開始我只上傳了一張 Pikmin 打菇的截圖, AI 就根據我的要求自動根據左上角的系統時間與圖中剩餘時間等資訊, 告訴我要安裝相關 OCR 套件, 並開發出第一個版本的程式, 這個程式已經大致完成了我的需求, 但離實用還有一小段距離, 所以在持續改進的開發過程中,我遇到了幾個有趣且經典的技術挑戰(對於這些影線處理, OCR, 圖片 EXIF info 等知識, 我是沒有太多的經驗, 但在 AI 一步一步的引導下完成了我的需求),在此與大家分享:  一、 影像預處理:拯救低迷的 OCR 辨識率 一開始,我直接將遊戲截圖丟給 Tesseract OCR 引擎,但辨識結果慘不忍睹。原因是遊戲畫面背景太過複雜(充滿草地、花朵與蘑菇發光特效) ,且文字是白色的。 為了解決這個問題,AI 引入了 OpenCV 進行影像預處理。先將圖片精準裁切,只保留左下角的血條與時間區域,接著轉為灰階並放大兩倍,最後使用二值化(經過測試閾值 200 得到不錯的效果)並反轉顏色。這個步驟成功將複雜的畫面轉換成 Tesseract 最容易辨識的「白底黑字」,大幅提升了準確率, 但在做更多的不同截圖的測試, 閾值 200 並不能成功轉換成 OCR 能辨識的黑白圖, 因此我請 AI 調整成以 200 為基礎, 如果辨識失敗, 在調整成 210, 190, 220, 180 如果都失敗才判定無法辨識(下圖是調整後的圖形)。  二、 對抗 OCR 的奇妙誤判與高容錯 Regex 解決了影像問題,接著是文字解析。遊戲字體中的無襯線數字「1」非常容易被誤判為英文字母 l、I、直線 |,甚至在辨識「1 小時」時被讀成 ]小時 。 為此,我設計了一套高容錯率的正規表達式 (Regex):(?:([0-9lIi|\]\[]+)\s*小?\s*時\s*)?(?:([0-9lIi|\]\[]+)\s*分\s*)?([0-9lIi...
最近的文章

[PHP PEAR]mail 功能

如果要使用PHP 來發送信件, PEAR 中的 Mail 模組是一個不錯的選擇 首先要 Include PEAR mail require_once(" /usr/share/pear/Mail.php "); //看你安裝 PEAR 的實際位置 $smtp = Mail::factory('smtp', array('host' => ' mailserver.domain.com ', 'port' => '25', 'auth' => true, 'username' => ' yourname ', 'password' =>' yourpassword ')); // 產生 mail instance $mail = $smtp->send($receivers, $headers, $content); // 送出信件 其中, create mail instance 時, 有三個主要參數可以選擇送信的方法 1. mail: 將寄信的工作交給 PHP 內建的 mail function 來送信 2. sendmail: 將寄信的工作交給本機的 sendmail 程式, 有兩個可設定的參數 $params["sendmail_path"]: 設定本機 sendmail 的實際路徑 $params["sendmail_args"]: 要傳給 sendmail 的參數 3. smtp: 將寄信的工作交給實際能送信的郵件伺服器, 此參數有很多子參數可設定, 介紹幾個常用的 $params["host"]: 設定實際能幫你送信的主機 $params["port"]: 設定傳送信件的通訊埠, 通常是 25 $params["auth"]: 現在非常多郵件伺服...

[PHP] 用 curl 來抓網路上的資料(四)

前面三篇我大概把一般會用到的基本 curl 介紹完了, 接下來我們會 介紹一些比較特殊的功能, 首先我要示範如果你的 瀏覽器是透過 proxy 來存取Internet 網頁的話, 如何用 curl 來達到同樣的效果呢? PHP 4.x 版和 5.x 版的用法不太一樣, 由於我使用的環境是 4.3.9 因此 我只介紹 4.x 版的用法, 其實 5.x 版也可以用等下我介紹的方法, 只是 5.x 提供了更方便的方法讓使用者容易使用 以下假設我們透過 proxy.hinet.net port:3128 來連上我們的目的地 http://www.test.com.tw/testpage.html 1. 如果 proxy 不需密碼: $ch = curl_init("http://www.test.com.tw/testpage.html"); curl_setopt($ch, CURLOPT_PROXY, "http://proxy.hinet.net:3128"); curl_exec($ch); 即可, 其中 curl_setopt 即是設定我們的程式要透過 proxy 去存取 我們的目的地網站 2. 如果 proxy 需要密碼: $ch = curl_init("http://www.test.com.tw/testpage.html"); curl_setopt($ch, CURLOPT_PROXY, "http://proxy.hinet.net:3128"); curl_setopt($ch, CURLOPT_PROXYUSERPWD, "user:password"); curl_exec($ch); 即可, 其中 第二個 curl_setopt 即是設定我們的程式要透過 proxy 去存取 我們的目的地網站所需的帳號(user)及密碼(password), 如果帳號密碼 沒錯應該就可以透過 proxy 存取了

[PHP] 用 curl 來抓網路上的資料(三)

post 的方法跟 get 的方法也很相近, 但因為他的參數部份(即 get方法中 問號後面"變數名稱=值" 的部份),在傳遞的時候我們無法看到, 因此我們 無法知道它傳的參數為何 , 幸好, 有些工具可以使用。 在此我介紹 httpwatch, httpwatch 是一套商業軟體, 不是 freeware 所 以請購買合法軟體, 如果網友有人知道有功能相近的 freeware 可以介 紹給我, 我會把 httpwatch 換掉,此外 httpwatch 必須跟 IE 搭配使用 (Firefox 目前無法使用)。 安裝完 httpwatch 後, 在 IE 的瀏覽器列就會出現如下圖所示的按鈕 如果按下 httpwatch 的按鈕, 瀏覽器下方就會出現 httpwatch 的相關 工具, 如下圖 先在瀏覽器的網址列輸入你想要觀察的網址, 這裡我用 http://www.digitimes.com.tw 為例 接下來在下方 httpwatch 工具中, 按下 Record(見上圖紅色按鈕) 然後才在網頁中輸入要查詢的關鍵字 接下來就可以看到相關執行程式名稱及相關 POST 的變數 名稱及值, 如下圖所示 此例中, 他新聞搜尋的功能是執行了 http://www.digitimes.com.tw/search/display.asp 並且傳了四個參數 keyword, submit1, sFormDate, sToDate 及 他們的值 SATA, Go!, 2006/8/1,2006/10/31 得到這些參數接下來我們就可以開始使用 curl 用 POST 的方法來抓網頁的資料了 啟始 curl: $ch = curl_init("http://www.digitimes.com.tw/search/display.asp"); 設 curl_setopt($ch, CURLOPT_POST, 1); 如此才能使用 post 的 方法來 傳 curl_setopt($ch, CURLOPT_POSTFIELDS, "keyword=SATA & submit1=Go ! & sFormDate=2006/8/1 & sToDate=2006/10/31"); 用 CURLOPT_PO...

[PHP] 用 curl 來抓網路上的資料(二)

有時候我們抓的網頁需要傳參數, 而用 curl 該怎麼使用呢? 基本上在 html 傳參數是用 form 來傳送, 而傳送的方法有 get 和 post 兩種方式 get 的方式就是我們常看到的在網址後面, 參數=值的格式, 例如: http://www.blogger.com/post-edit.g? blogID=95939 & postID=1159981918019 就是將 blogID 這個變數其值是 95939 和 postID 值是 1159981918019 傳給伺服器 http://www.blogger.com/ 中的 post-edit.g 這個程式 所以, get 的方法就很簡單, 只要在 curl_init 中將整個網址當參數就可以了, 例如: $ch = curl_init("http://www.blogger.com/post-edit.g?blogID=95939&postID=1159981918019"); 如果參數的值是會變動的也可以用變數代替, 例如: $ch = curl_init("http://www.blogger.com/post-edit.g?blogID= $bid &postID= $pid "); get 的方法一般比較常用, 方法也較簡單, 而且你可以用瀏覽器先看看你要抓的網站他的程式需要甚麼參數, 你就可以直接拿來使用 另一種方法 post 就沒那麼方便了, 雖然用 curl 的方法沒多複雜, 但是我們沒辦法直接看到網站的程式, 他所需要的參數是甚麼, 所以需要其他輔助的工具來幫忙, 這個部份比較多我就留在下一次再跟大家介紹

[PHP] 用 curl 來抓網路上的資料(一)

CURL 是 Client URL Library 的縮寫, 他是 php 當作 client 的好用工具, 如果你需要用程式來抓人網站的資料來處理, 他是一個很方便的函式庫, PHP 4.0.2 之後的版本有支援, 如果你的 PHP 不能用可以去以下的網址 curl 下載套件安裝 要使用 curl, 首先要先啟始 curl: $ch = curl_init("http://tw.yahoo.com"); 或 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://tw.yahoo.com"); 接著要設定相關選項, 選項的部份相當的多, 詳細的資料可參考 www.php.net curl_setop t 我僅就我常用的說明一下: 如果你連的網站回傳是 xml 格式, 你將傳回的 xml 格式以 SAX 或 DOM 的方式, 將 CURLOPT_HEADER 設成 0, header 就不會回傳以方便後續處理 curl_setopt ( $ch , CURLOPT_HEADER , 0 ); 如果網站回傳的資料, 你需要做後續處理, 一般我們會將他存在一個字串, 這時你就需要用 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 最後真的開始連接網站時就可以用: $result = curl_exec($ch); 將結果存在 $result 中了 如果你希望將連接網站的資料存在檔案中, 你需要先開一個檔案 $fp = fopen("test.html", "w"); 再用: curl_setopt($ch, CURLOPT_FILE, $fp); 指定將等下執行 curl_exec($ch); 的結果存進 $fp (即 test.html 裡) 最後當然一定要執行 curl_exec($ch); 或 $result = curl_exec($ch); 當然最後使...