pretty code

2023年11月13日 星期一

才下眉頭,卻上心頭

昨天在回父母家前終於把上上星期打好的管委會舊資料電子檔再核對一次,只有兩年半的資料也花了我了六日不少時間,雖說在打舊資料時就會核對一次,也趁使用 Python tool 填上分析總表時自動重新計算一下每月活存餘額作檢查,但沒有再核對一次,心裡總覺得不踏實,畢竟資料正確性才是第一重要, 目前總算是搞定了一件事。

因為一直把這件事放在心上,導致其他想到的事情都只能先用頭腦當暫存區,再加上本週已經開獎,因為沒時間原本已經想放棄了,後來還是覺得有點可惜,記錄一下自己的思路避免以後再次回想。

01. 退出 KOReader 後,bluetooth 無法使用問題。

我能理解開發團隊為什麼要 kill bluetoothd,一來可以省電,二來希望回去 Kobo Nickel 時可以讓 bluetooth 正常,無奈這招行不通。

我想以那團隊的能力 review chip spec 功力一定是不在話下,連他們都沒想到的事代表真的不可行嗎,還是只是純粹對藍牙翻頁器沒有興趣?畢竟會看電子書的人分為兩派,一派很喜歡用翻頁器,另一派卻對翻頁器嗤之以鼻XD

首先,需先釐清問題所在,假設是硬體問題,想辦法 reset chip 再 init 一次應該就可以了?

如果只是 bluetooth status 不同,導致 Nickel 認為有問題而不使用藍牙,是否可以去 /etc/rule.d 看開機時對藍牙做了什麼事,只要再呼叫一次該 script 即可?

02. 點雲點數的差異是如何而來。

雖然還未購買 3D scanner,但我內心總隱隱覺得我的土砲結構光系統跟幾萬塊的消費型機種應該沒有到 100 倍的差距?

回想一下,點雲起手式是什麼,不就是從 pixel cord decode projector cord,故 1 個 pixel 只要是 valid,就會作三角測量產生 1 點才對

換句話說,1920 x 1080 的 camera resolution,假設 valid mask 是 60%,則一次的總點數就是 1920 x 1080 x 0.6 = 1,244,160。

KEYENCE 這樣厲害的廠商一定是重覆拍照拼接或是做額外插值才能得到那麼豐富的點雲資訊?(印象中 33 mm size chip 似乎就拍了 10 幾張?用有 1000 多顆錫球那面來看,點雲點數約為 551 萬

以後如果請廠商 demo 還是得先有基礎知識才不會霧裡看花,什麼重點都沒看到

2023年11月10日 星期五

將來的事將來再說

鄭伊健和張柏芝主演的《蜀山傳》中,徒弟問了師父一個問題,師父只是淡淡的回了一句:將來的事將來再說…

話雖如此,但這將來也是有點久,即使我上星期五就知道答案,但拖到昨天才有非正式通知,也害我多看了沒用的數學 4 天?

這 1Q 的數學深不得我心,可能跟我本來的屬性不合,前 3Q 的至少是偏應用,還可以用學到的知識來土砲結構光系統,但這 1Q 的是純演算法跟數學,又不是要發頂會論文,坦白說我也還未入流,只是在浪費生命罷了。

站在管理的角度來說,這樣很不可取,浪費公司跟我的時間在一個沒有未來的學習,拿去多學一些對公司有用的不是很好,雖說也跟主管稍微提到這樣不行,無奈主管對我很好,我也只能欣然接受。

在這家公司 9 年多了,我對公司只有滿滿的感激,沒賺錢還有幾個月的年中加年終可拿,補班也不用我們上班,年底還有聖誕節可放!

衷心希望公司可以再起一波,只可惜以後沒有益生菌可購買了XD

------------------

上星期五就已經想好接下來要做什麼了!先簡短記錄,晚點再補細節。

01. 開發社區簡易財報查詢系統。

這一個多月假日除了土砲結構光系統外,有空都在補歷年財報電子檔資料,補到現在也才補了 9 年,算是一件吃力不討好的事,重點是也沒有人要求!責任心還是不要那麼重比較好。

超過 7 年的紙本資料都發霉了,就回朔到 103 年 6 月就好,勢不可去盡…

犧牲了自己假日時間,總算也是有點收穫,追回了一筆兩萬多塊的重覆付款,只能說這個永大很爛!

坦白說開發這個系統對我也沒什麼幫助,過去有建檔的資料都已經在我腦袋中,就當替 10 年後的我買個保險,以免 10 年後還住這個社區XD

這個簡易系統有 3 個方向可實作,分別是 UI 三大框架選一個,Excel VBA,Google Sheet Action Script。

UI 三大框架就是要配 Github Page,資料也不知會不會有隱私問題,但我認為漏水或修繕本就是應揭露事項,我是不覺得有任何問題,本人也不會笨到去揭露社區名稱,好吧,我承認我住新竹XD

VBA 或是 Action Sheet 好處是跟著檔案走,比較不用顧慮 UI 設計,但以目前已經有 120 多個 sheet 的 Excel 檔案來說,存檔都需要好幾秒,長久下去不是辦法,我猜跟 Excel 檔案本質就是一堆 XML 的組成有關,故效能會隨資料越多而越差,應該是線性成長?去去去,油漆工演算法不要來搗亂XD

目前在補舊資料時,是透過 Python 將新增資料填上分析總表以及各別科目 sheet,坦白說已經很好用了,比第一次從頭到尾建電子檔節省了不少人力,當然每月新增的資料還是免不了人力介入。

我們社區就是沒錢,難怪沒人主動要當管理委員?目前活存來到接近歷史新低。編號 13 的那筆資料剛好也是某次的調漲管理費用起始點,希望能像那次一樣,可以逐漸往上成長還能夠有餘額轉定存!


02. 購買消費性 3D 掃瞄儀來確定土砲結構光系統差距。

原本想購買 REVOPOINT POP3,但在 Reddit 看到前一代的評論,只能說慘不忍睹。

另外在同討論串看到推薦 EinScan-SE 這台,但價差多了 3 萬,總共要 5 萬塊,確實是有點買不下手。在 YouTube 看到一個影片,這台搭配轉盤,一個面速力達母寬度的小物件,看起來會轉 8 次,轉一次約會有 17,000 左右的點,感覺我的土砲結構光系統跟他並沒有到 100 倍以上的差距?


還是多看一些 YouTube 的影片再做決定?

03. Review 世界未來趨勢。

進入賺錢的產業或公司才是最重要的!你會什麼程式語言根本不是重點,結論還是鞏固基礎能力就好,正所謂萬變不離其宗。

退一步則是找自己有興趣的,有興趣才能持久。

千萬別為了工作而工作!

04. 多陪爸爸媽媽。

把買的那幾本相關書看一看。

05. Kobo(找到之前找我面試的 email)、Readmoo、HyRead 選一家投履歷。

一直有印象 Kobo 之前有找我面試?但遍尋 Gmail 卻一無所獲?目前只看到蝦皮的 email?

2023年11月3日 星期五

Magic symbol - _ZN6google15ErrnoLogMessageC1EPKciimMNS_10LogMessageEFvvE

同事最近在搞 Vitis-AI 的板子,過程中遇到一些問題,花了一天多的時間幫忙釐清並解決編譯問題,還是稍微記錄一下好了XD

這個 magic string 就是所謂的 name mangling,請看這裡

環境介紹:同事沒有使用 PetaLinux 而是使用 Ubuntu 22.04。

同事在執行下面這支 script 時發生問題,一開始就跑不起來,看了 code 後發現,並沒有人去呼叫 main function,故需要改成先帶 main 再帶 target board 型號的方式來執行此 script。(後來才發現 Xilinx 文件是錯的,4.3.2 有錯,但 4.3 有稍微提到 run_all_target.sh 這支 script,裡面就可以看到正確呼叫 run_all_cifar10_target.sh 的參數傳法)

Vitis-AI-Tutorials/Tutorials/RESNET18/files/target/run_all_cifar10_target.sh

再來還是跟執行 run_all_cifar10_target.sh 有關的錯誤。

01.  missing symbol - _ZN6google15ErrnoLogMessageC1EPKciimMNS_10LogMessageEFvvE

這個名稱是 gcc 在編譯函數等 object 時所定義的 symbol name,gcc 是 follow 這個文件,我們也可以把這串名字丟到此網站,我們就可以看到此 symbol 的原型宣告如下:

google::ErrnoLogMessage::ErrnoLogMessage(char const*, int, int, unsigned long, void (google::LogMessage::*)())

同事的問題就是在安裝的 glog 中找不到同樣名稱的函數,嚴格說起來是差在第 4 個參數,我們跟這串文字差了一個 m,而這個 m 就表示參數是 unsigned long。

同事還蠻幸運的,在降版本到第二個版本後,就順利編譯出有一樣 symbol 的 so 檔。

02. missing symbol - xclIPSetReadRange

這個問題跟上面類似,也是版本相關的 issue,後來在 review XRT 版本後,確定某些版本以前的 code 確實缺少了這個函數(XRT/src/runtime_src/core/pcie/linux/shim.cpp),後來便決定使用 202220.2.14.354。

底下是自己編譯此版本會遇到的問題。

首先在 sudo <XRT>/src/runtime_src/tools/scripts/xrtdeps.sh 時,會看到類似沒有安裝 gcc 8 的訊息,因為環境已經有 gcc 11 了。

接著執行 build.sh 發現很快就結束了,原因是 script 中,gcc 版本是 hard code 寫死,直接改成對應的版本即可,接下來就是一連串的 sudo apt-get install 地獄XD

此 script 會先執行 configure 相關工作,反正遇到什麼錯誤就 google 一下,安裝對應的 xxx-dev 版本即可,印象中有 4 ~ 5 個要裝。

最麻煩的是在 runtime_src/xdp/CMakeLists.txt:427 會報找不到 xdp_hw_emu_device_offload_plugin 錯誤,但這個東西如果我沒搞錯應該是編譯時才會編譯,懷疑是 CMakeLists.txt 沒寫好,可能跟相容 cross-compile 有關?

想了一下,直接註解 427 及 428 行即可。

接下來是一連串的 build error,最糟糕的都是直到編譯某支檔案時才會報找不到 header file 的錯誤,此時也只能一個一個 apt-get 安裝,印象編譯到 40 幾趴還會有錯誤,大概也是有 4 ~ 5 個要安裝,之後便可以順利編譯出 Debug 和 Release 版本了。

接著使用 objdump -T xxx_core.so | grep xclIPSetReadRange 確認一下,這次就可以順利看到 symbol。

由於 Release 版本還在編譯,簡單使用 export LD_LIBRARY_PATH=/XXX/Debug 來讓執行時可以找到 xxx_core.so 的 xclIPSetReadRange symbol 來驗證是否有順利解決問題。

花了一天多幫同事搞定這個問題,最後還是沒能在 target board 跑出想要的結果,但這又是另一個故事了XD

2023/11/24 更新

為了寫技術文件,從零亂的計算紙中找到蛛絲馬跡,凡走過必留下痕跡。

fix configure error

sudo apt-get install libdrm-dev
sudo apt-get install ocl-icd-opencl-dev
sudo apt-get install libncurses5-dev
sudo apt-get install libssl-dev
sudo apt-get install rapidjson-dev

-------------
CMake Error at runtime_src/xdp/CMakeLists.txt:427 (add_dependencies):
  The dependency target "xrt_hwemu" of target
  "xdp_hw_emu_device_offload_plugin" does not exist.

https://github.com/Xilinx/XRT/issues/6942

fix it
comment runtime_src/xdp/CMakeLists.txt line427, line428

-------------------------------------------------------------------
fix build error

sudo apt-get install uuid-dev
sudo apt-get install ocl-icd-dev
sudo apt-get install libcurl-dev
sudo apt-get install libudev-dev

2023年10月23日 星期一

Use pure bluetooth in KOReader v2021.10.1

KOReader is an awesome application on Kobo device. The architecture of application is very flexible.

I follow the guides of NiLuJe to modify source code a little to let my Kobo Elipsa to use bluetooth.

The only file you modify is koreader/frontend/device/kobo/device.lua

01. Add "hasKeys = yes," in KoboEuropa object.

-- Kobo Elipsa
local KoboEuropa = Kobo:new{
    model = "Kobo_europa",
    isSunxi = yes,
    canToggleChargingLED = yes,
    hasFrontlight = yes,
    hasKeys = yes,
    hasGSensor = yes,
    canToggleGSensor = yes,
    pressure_event = C.ABS_MT_PRESSURE,
    misc_ntx_gsensor_protocol = true,
    display_dpi = 227,
    boot_rota = C.FB_ROTATE_CCW,
    battery_sysfs = "/sys/class/power_supply/battery",
    ntx_dev = "/dev/input/by-path/platform-ntx_event0-event",
    touch_dev = "/dev/input/by-path/platform-0-0010-event",
    isSMP = yes,
}

02. Modify key code for your pageturner, I use Logitech R500.

-- NOTE: For the Forma, with the buttons on the right, 193 is Top, 194 Bottom.
    self.input = require("device/input"):new{
        device = self,
        event_map = {
            [35] = "SleepCover",  -- KEY_H, Elipsa
            [59] = "SleepCover",
            [90] = "LightButton",
            [102] = "Home",
            [105] = "RPgBack",
            [106] = "RPgFwd",
            [116] = "Power",
            [331] = "Eraser",
            [332] = "Highlighter",
        },
        
03. Open your pageturner manually. My pageturner is event4.

-- NOTE: usb hotplug event is also available in /tmp/nickel-hardware-status (... but only when Nickel is running ;p)
    self.input.open("fake_events")
    self.input.open("/dev/input/event4")
    
Enjoy it.

------------------------------------------------------------------------

The issue of entering Kobo again is that we can't use bluetooth anymore. The below messages are from logread command. Maybe we can google these keywords to get the solution ?

Oct 23 20:49:02 nickel: (   144.927 @ 0x374c538) QObject::disconnect: Unexpected null parameter
Oct 23 20:49:02 nickel: (   144.927 @ 0x374c538 / ui.warning) cancelled before full sync has started
Oct 23 20:49:02 nickel: (   144.977 @ 0x374c538 / libraryLayout.warning) void AbstractLibraryController<C>::layout(bool) [with C = BluetoothDevice] view is null
Oct 23 20:49:02 nickel: (   144.999 @ 0x374c538 / libraryLayout.warning) void AbstractLibraryController<C>::layout(bool) [with C = BluetoothDevice] source has no rows
Oct 23 20:49:02 nickel: (   145.000 @ 0x374c538 / libraryLayout.warning) void AbstractLibraryController<C>::layout(bool) [with C = BluetoothDevice] source has no rows
Oct 23 20:49:53 bluetoothd[3342]: Endpoint unregistered: sender=:1.2 path=/org/bluez/hci0/A2DP/SBC/Source/1
Oct 23 20:49:53 bluetoothd[3342]: Endpoint unregistered: sender=:1.2 path=/org/bluez/hci0/A2DP/SBC/Source/2
Oct 23 20:49:57 bluetoothd[3342]: Terminating
Oct 23 20:49:57 nickel: (   200.505 @ 0x374c538 / bt.warning) void BluetoothManager::objectManagerInterfacesRemoved(const QDBusObjectPath&, const QStringList&) adapter already destroyed
Oct 23 20:49:57 bluetoothd[3342]: Stopping SDP server
Oct 23 20:49:57 bluetoothd[3342]: Exit
Oct 23 20:50:13 bluetoothd[3352]: Bluetooth daemon 5.63
Oct 23 20:50:13 bluetoothd[3352]: src/main.c:check_options() Unknown key InitVolume for group General in /etc/bluetooth/main.conf
Oct 23 20:50:13 bluetoothd[3352]: Starting SDP server
Oct 23 20:50:13 bluetoothd[3352]: Bluetooth management interface 1.14 initialized
Oct 23 20:50:13 bluetoothd[3352]: src/adapter.c:reset_adv_monitors_complete() Failed to reset Adv Monitors: Unknown Command (0x01)
Oct 23 20:50:23 bluetoothd[3352]: Failed to set mode: Failed (0x03)
Oct 23 20:50:23 bluetoothd[3352]: Player registered: sender=:1.4 path=/com/kobo/bluetooth/MediaPlayer
Oct 23 20:50:24 bluealsa: Couldn't get HCI version: Network is down
Oct 23 20:50:24 bluetoothd[3352]: Endpoint registered: sender=:1.8 path=/org/bluez/hci0/A2DP/SBC/Source/1
Oct 23 20:50:24 bluetoothd[3352]: Endpoint registered: sender=:1.8 path=/org/bluez/hci0/A2DP/SBC/Source/2
Oct 23 20:50:31 bluetoothd[3352]: Endpoint unregistered: sender=:1.8 path=/org/bluez/hci0/A2DP/SBC/Source/1
Oct 23 20:50:31 bluetoothd[3352]: Endpoint unregistered: sender=:1.8 path=/org/bluez/hci0/A2DP/SBC/Source/2

2023年10月22日 星期日

管委會相關事項備忘

下層鐵櫃從左至右分別如下,報表新的在上:

10306 ~ 10412
10501 ~ 10612
10701 ~ 10812
10901 ~ 11012
11101 ~ 11209

滅火器更換,區公所可補助一半(不確定是否常態?)
節能燈具更換,政府補助一半(不確定是否常態?)

B1 or B2 汙水管疏通,工法會切管,一次好幾支約兩萬多。
車道坑洞切換會分批做,避免影響車輛進出。
電梯按鍵一顆以前約 578。
化糞池清洗有分下不下池,下池約再多一半錢。

報表電子資料如何保存,是否要走會計辦法(複式簿記)?
01. 使用 GNU Cash。
02. 使用 Daily Money。
03. 自行寫程式配合 chart.js 放在 github page。
04. 原本的 Excel 檔案(確認 Python module 是否可以加公式或是使用 VBA)。

Note:若要加上公式,Use openpyxl 即可,但將 Excel 檔上傳到 Google Drive 後,如果儲存格是 refer to other cell,Excel 程式會顯示 0,但 Google Drive 不會,故折線圖會不連續,最好將月報表未發生費用值填上 0。

自行寫程式 JSON 格式暫訂:
{
    "init": [
        {
            "bank1": 10000
        },
        {
            "bank2": 20000
        }
    ],
    "accounts": [
        {
            "item": 40100,
            "desc":"管理費收入"        
        }    
    ],
    "reports": [
        {   
            "10601": [
                {
                    "item": 50100,
                    "dollar": 3454,
                    "detail":"B2車道修補"
                }
            ]
        }
    ]
}

防水工程科目名稱改防水及土木工程(車道坑洞修補)
安全缺失改消防安全缺失改進。
活存轉定存目前先放置在其他不屬於每月雜支科目。

費用分析時需將裝潢保證金扣除避免失真。

確認國盛回饋金是否是舊衣回收? -> Yes
資源回收每月約在 90 ~ 400 內。

2023年10月15日 星期日

放空的六日

連續兩個假期都在搞結構光系統,剛好把這三季學到的東西做個總結,雖然最後為了孩子的學習還是多買了一台 webcam,個人還是覺得收穫良多!

這次六日便打定主意完全不煮飯好好來放鬆一下,開開心心來打我的暗黑 2 重製版,也順利的讓我的亞馬升到 93 級。

時間來到星期日的晚上,離睡前還有點時間,來試試 KOReader issue #9059 提到的修改 lua code 使用藍牙翻頁器的討論串好了。

果不期然,事情沒那麼簡單,過程中需要一些指令來做驗證,奈何相關指令散落在我 blog 中的好幾篇文章中。

還是整理一下好了,下次就不會那麼累了。

01. logread

logread 可以來看訊息,一些 third-party app 也會吐訊息在這裡,配合 grep 檢查訊息。

02 藍牙相關

bluetoothctl  (show, info, devices, connect) 配合括弧裡的參數可以來確認藍牙狀態。
不清楚有哪些參數可以打 bluetoothctl help。

/libexec/bluetooth/bluetoothd is a bluettooth daemon
可以砍掉此 process,重新執行 /libexec/bluetooth/bluetoothd -d -n 開啟 debug message。

03. Linux input subsystem

cat /proc/bus/input/devices 可以看到系統長出哪些 /dev/input/eventX 裝置。

04. third-party .so path

像 libbtpt.so 就位在 /usr/local/Kobo/imageformat 裡面,直接砍掉就是 uninstall 了。

05. KOReader debug message

logger.info("xxxxxxx") 便可以在 koreader/crash.log 中看到相關訊息。


2023/10/19 更新

在 KOReader 加入一些 debug message,目前看來在我 Elipsa 上的 v2021.10.1 版本,啟動時並不會砍掉 bluetoothd,故我的藍牙連接是正常的,在 Input:handleKeyBoardEv 確實也有看到我的 R500 按鍵的訊息,感覺是在更上層的地方,沒有人去處理 ?


2023/10/23 更新

果然是沒有人處理,幸好 KOReader 是一個很有彈性的軟體,加個參數騙過它即可XD

2023年9月30日 星期六

第一次結構光初嘗試

中秋節逛寶雅時,剛好看到兩個砧板架,思索了一下,配合束帶應該可以當我的土砲結構光系統架,於是便開始了第一次嘗試。

整個系統如下:


棋盤板也是很克難的用托盤來代替。


拿我最喜歡的美國隊長來當模特兒。


點雲成像品質,只有簡單用 z 當 filter,把雜點去掉。


當然少不了可愛的郭靜。


可惜 gray code + phase shift 不如我的預期,懷疑是照相機在左邊,故 3D 公式應該要改?


只能克難的在飯桌上架設環境,煮飯時又要清空,回復時還要小心不要讓校正好的投影機和相機跑掉,對於第一次的嘗試,我個人覺得至少有 70 分了吧?

繼續思考數學公式中…

2023/10/03 更新

土砲歸土砲,精度看起來還是有的,我的棋盤格橫格約為 17.5mm。


當初使用單目結構光架構是因為我只有一台 webcam,但投影機畢竟是投影機,兩個不同裝置的 model 不一定能完美 match,如果是雙目架構,投影機只是輔助,理論上精度會比現在好,故問題只剩下雙目相機拍照時要保持同步以避免看到的環境光不一致,看來我皮包的小朋友又要出走了?畢竟孩子的學習不能等呀XD

2023/10/04 更新

還是覺得相機擺哪一邊不應該影響數學公式,也就是投影機 y 座標的那個公式,畢竟是從 P1 和 P2 投影矩陣聯立後解 Ax = 0 來的。

再仔細看了一下《Calibration of fringe projection profilometry: A comparative review》 這篇論文,在公式 29 與公式 30 有這麼一段話:「Assume that the projector and camera are arranged horizontally and only vertical fringe images are projected, we can obtain the horizontal coordinate 𝑥 𝑝 by using the phase 𝜙𝑣 ( 𝑥, 𝑦 ) according to Eq. (23) .」


所以表示我的投影機和相機應該水平擺置?但對我這個土砲結構光系統來說,我很難做精細的微調!

在不讓小朋友出走的情況下,我能不能用純軟的方式來解決這個問題呢?

2023/10/05 更新

昨天晚上很克難的用書架把投影機架高,目測照相機和投影機鏡頭中心應該有接近水平?其實不應該用這樣不科學的方式,應該用投影圖案計算來確認兩者是否有水平,但以我這個土砲系統來說,我連找墊高投影機的東西都很難找到,故我就不花時間去計算了,畢竟下班還要搞這個對老人來說也是很累XD

(謎之音:我只是想拍拍可愛的郭靜, 老天爺不要搞我了,拜託XD)

除了墊高投影機外,這次想說把距離拉遠一點,看是否能讓反光影響變小,順便測試投影機 delay 是否可以縮短,之前因為黑條紋會變藍色橘色等不同顏色,故我使用 dealy 1s 的方式來解決這個問題,但拍照的張數越多,時間就會拉長,查了一下我的投影機延遲時間為 35ms,故先用 delay 100ms 的方式來測試,即使已經放大約 3 倍,但藍橘光的情況依舊,為了保險起見還是維持原本的 delay 1s。

這次一共拍了 29 組角度圖片作 calibration,但反光比之前還嚴重,這次可能連 17 組角度都不到,我也懶得算了,面朝下的所有角度都作廢了,導致我的 RMSE 從原本的 0.53 升高到 1.60。

不只如此,我連正常的 gray code 點雲都有問題,完全看不到我的待測物,但 gray code + shift method 反而有東西,雖然雜點是比之前多,但至少是有東東的?

理論上我可以拿之前校正好的參數來套用這次拍的圖片,除了 R, t 失真以外,測了一下,果然使用之前的參數加我這次拍的圖片是可以看到待測物的,當然雜點更多尚屬合理。

帶著一顆失望的心上床去了…

今天中午吃飯回來把絕對相位值畫出來參考,v 選擇解析度的一半 240,看起來果然有錯位,算有符合點雲看到的現象。


一不做二不休,k1、k2、wrapped phase 都一起來吧。


好像看出些什麼來了?

2023/10/07 更新

星期四下班後,做了幾個調整:

01. 架高照相機而不是投影機,之前眼殘,一直以為投影機比較矮。
02. 懷疑是投影機解析度 848 跟 T 無法 matched,改解析度為 1024。
03. 計算 T 時,使用 freq 16 而不是 stripe numbers 32。

我個人覺得 2, 3 才是之前錯位的原因,但我的土砲系統一動就要重新校正,校正時又容易因為反光而得不到好的校正參數,故我也懶得驗證了。

雖然互補格雷碼法與相移法已經搞定,但坦白說沒有比單純 gray code 好多少。

底下是連假前一天下班後的測試及隔天放假第一天的一些實驗。

克難的用書架墊高照相機

做實驗時隨手寫的筆記

上面左邊是 gray code,右邊是 gray code + phase shift。

使用 gray code + phase shift,開燈關燈也會影響點雲品質。

材質不同也會影響點雲品質。

2023/10/09 更新

前天趁著連假的第一天,想辦法搞定 two cameras + one projector 的環境,還好有寶雅,找到便宜的手機三腳架來架設相機,右相機都已經跨到投影機 HDMI 線上才勉強維持一個還過得去的雙目相機視角,整個結構光系統終於克難的架設完畢。


上面不管是 gray code 還是 phase shift,都比原來只有一個相機時差。

中間還遇到傳說中的 OpenCV detect corners bug。

大概想試的都試了,在不繼續看其他 papers 的情況下,我這隻老狗也變不出什麼新把戲了?

額外補充


想要加快開啟相機速度或是設定相機參數速度,可以調整 flags for VideoCapture class。
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
但是 cap.read() 可能就要配合相機的 fps 做 delay,不然會讀到舊的資料。

已經手動拿掉無法匹配的雜點,還是做不出我心目中可愛的點雲,殘念。


精度約差了 4 mm,當然我並沒有很認真 pick points,不過誤差還是 mm 級的,too bad。


2023/10/22 更新

這個假日都在搞管委會資料,趁著煮飯前,再來玩一下結構光,之前看了一篇論文,才恍然大悟為什麼我的點雲周遭雜點很多,我們既然要用結構光來輔助雙目視覺找對應點的難題,我們本來就應該只對投影機有投射的區域做點雲才對,之前都沒認真想過,哈。

即使只是純格雷碼,只關心投影範圍還是能做出不錯的結果,只剩上面哪一小塊匹配不好,以我之前經驗,有些奇怪的地方不一定就是出現在相片 2D 對應的區域,遇到這種問題要查找,只能邊解 3D 邊把點填上點雲,才能看出是在哪裡出錯。