2026/08/17

erlang 的 == 與 =:=

erlang 的相等比較有兩種 == 與 =:= 。同樣都是相等,但比較的嚴格等級不同。

==

這是等值比較,如果比較的是整數跟浮點數,兩種不同的資料型別,在比較之前,會自動做型別轉換,然後再根據數值進行比較。

> 1 == 1.0.
true
> 1 == 1.
true

=:=

全等比較,除了數值要一樣,資料型別也必須要一樣。

> 1 =:= 1.0.
false
> 1 =:= 1.
true

pattern matching

erlang 的 pattern matching 行為比較接近 =:=

假設有這樣的一個 function

check_num(1) -> integer;
check_num(1.0) -> float.

在呼叫 chech_num(1.0) 的時候,會進入第二個 clause,不會進入第一個。因為 1 跟 1.0 是不同的資料型別

/= 與 =/=

不相等,也一樣有兩種寫法

  • /=:對應於 ==。若值在算術上不相等,則為 true

  • =/=:對應於 =:=。若值或型別任一不同,則為 true

>  1 /= 1.0.
false
> 1 =/= 1.0.
true

Term Ordering

在 erlang 的所有資料型別,都能夠直接比較大小,這是因為在處理集合的排序時,能夠得到一個固定的結果。資料型別的比較順序如下

number < atom < reference < fun < port < pid < tuple < map < list < bitstring

sample

> 999999 < apple.
true
> Mixed = [apple, 10, {test, 1}, [1,2,3], 5.5, "hello"].
[apple,10,{test,1},[1,2,3],5.5,"hello"]
> lists:sort(Mixed).
[5.5,10,apple,{test,1},[1,2,3],"hello"]
% 順序:數字(5.5, 10) < atom(apple) < tuple({test,1}) < list([1,2,3], "hello")

Summary

要確保資料比對正確,大部分的狀況都是要寫成 =:=,僅有少部分,遇到了整數跟浮點數必須混合比較時,才需要用到 ==。

2026/08/10

RPi 設定使用 camera

camera

更新套件

sudo apt update
sudo apt install ffmpeg v4l-utils libcamera-apps -y

使用一般的 web camera

用這個指令列出所有 devices,通常外接的 camera 會在 /dev/video0

v4l2-ctl --list-devices

用這個指令查詢 video0 支援的 video 格式

v4l2-ctl --device=/dev/video0 --list-formats-ext

如果有 RPi 官方提供的 camera 模組。

安裝時

  1. 找到 CSI 相機接口,將拉起連接埠的黑色或白色塑膠卡榫

  2. 有藍色膠帶的一面要朝向 HDMI/USB 埠,金屬接點面朝向 CSI 接口內部

  3. 插入排線後,將卡榫壓回固定

測試拍照

如果是用 web camera,可直接用 ffmpeg 拍照。

ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -frames:v 1 test.jpg

如果是 RPI camera 模組,用 ffmpeg 會產生 error,要改用 rpi-cam-* 指令

rpicam-jpeg -o test.jpg

# video
rpicam-vid -t 5000 -o test.h264

將 RPi 改為 HotSpot AP

# 將 wifi 改為 hotspot AP
sudo nmcli device wifi hotspot ssid crpi4 password wifipassword ifname wlan0

# 設定可自動連線
sudo nmcli connection modify Hotspot connection.autoconnect yes

# 修改為 2.4G
sudo nmcli connection modify Hotspot 802-11-wireless.band bg

# 設定可從 wifi 轉發到 ethernet
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

音效卡

使用 UPTech 161 USB 音效卡測試

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 004: ID 0d8c:0014 C-Media Electronics, Inc. Audio Adapter (Unitek Y-247A)
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

要出現 C-Media 的那一行

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 1: vc4hdmi0 [vc4-hdmi-0], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: vc4hdmi1 [vc4-hdmi-1], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 3: Device [USB Audio Device], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

有出現 card 3: USB Audio

設定 USB 音效卡為預設輸出

sudo raspi-config
  • 進入 System Options -> Audio

  • 選擇你的 USB Audio Device,然後按下 Finish

調整音量

alsamixer

按下 F6 鍵,選擇你的 USB Sound Device

使用方向鍵將 SpeakerMic 的音量推高

 $ arecord -l
**** List of CAPTURE Hardware Devices ****
card 3: Device [USB Audio Device], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

card 3device 0 組合起來就是硬體代號 hw:3,0

讓系統預設就抓這張卡,我們建立一個 ALSA 設定檔

sudo nano /etc/asound.conf

defaults.ctl.card 3
defaults.pcm.card 3
defaults.timer.card 3

測試

$ aplay -D hw:3,0 /usr/share/sounds/alsa/Front_Center.wav
Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
aplay: set_params:1398: Channels count non available

因為這張 USB 音效卡(或是 ALSA 驅動)在處理 Mono(單聲道) 檔案時,無法直接對應到硬體的 Stereo(雙聲道) 輸出。

改為以下指令

$ aplay -D plughw:3,0 /usr/share/sounds/alsa/Front_Center.wav
Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono

測試錄音 10秒

arecord -D plughw:3,0 -d 10 -f cd -vv test_mic.wav

設定為 0dB

amixer -c 3 sset Mic 0dB

錄影+錄音

透過 rpicam-vid 錄影後,轉發給 ffmpeg 增加錄音

  • -f segment: 自動分割

  • -segment_time 600: 每 600 秒 (10分鐘) 分割一次

  • -reset_timestamps 1: 每個片段的時間戳從 0 開始,避免播放器錯誤

  • -strftime 1: 允許檔名使用時間格式

rpicam-vid -t 0 --inline --width 1920 --height 1080 --framerate 30 \
    --bitrate 8000000 --profile high \
    --saturation 1.4 --contrast 1.2 --sharpness 1.5 --awb auto \
    -o - 2>/dev/null | \
ffmpeg -y -r 30 -i pipe:0 \
    -f alsa -i plughw:3,0 \
    -c:v copy -c:a aac -ac 1 \
    -af "volume=2.0" \
    -f segment -segment_time 300 -segment_format mp4 \
    /home/charley/Videos/test_%04d.mp4 > /dev/null 2>&1

錄影 mp4 格式,有可能會因為中途中斷而打不開檔案。改使用 ts 格式。iMovie 可讀取 mp4 及 ts 格式

rpicam-vid -t 0 --inline --width 1920 --height 1080 --framerate 30 \
    --bitrate 8000000 --profile high \
    --saturation 1.4 --contrast 1.2 --sharpness 1.5 --awb auto \
    -o - 2>/dev/null | \
ffmpeg -y -r 30 -i pipe:0 \
    -f alsa -i plughw:3,0 \
    -c:v copy -c:a aac -ac 1 \
    -af "volume=2.0" \
    -f segment -segment_time 300 -segment_format mpegts \
    /home/charley/Videos/test_%04d.ts > /dev/null 2>&1

調整畫質

AWB 模式

如果你覺得自動模式不準,可以嘗試適合的模式:

  • --awb auto: 預設自動。

  • --awb indoor: 適合一般室內燈光。

  • --awb tungsten: 適合黃光燈泡環境(這會強力補償藍色,消除黃感)。

  • --awb fluorescent: 適合辦公室日光燈環境。

或是使用 manual mode

  • --awbgains R,B: 第一個數字是紅增益,第二個是藍增益。

  • 調低第一個數 (紅)調高第二個數 (藍) 可以讓畫面變冷色調。

rpicam-jpeg --width 1920 --height 1080 --awbgains 1.2,1.8 -o test_cool.jpg

2026/08/03

pdf OCR

當遇到 pdf 複製文字是無法辨識的內容時,這是 pdf 保護文字資料的方法,可透過轉成圖片,再做 OCR 解決。

安裝軟體

# ghostscript. pdf -> 圖片
dnf install ghostscript

# 圖片
dnf install ImageMagick

# Tesseract OCR(圖片 → 文字)
sudo dnf install tesseract
tesseract --list-langs
# 預設已安裝英文
#sudo dnf install tesseract-langpack-chi-sim  # 簡體中文,視需求
#sudo dnf install tesseract-langpack-chi-tra  # 繁體中文

# 合併 pdf
dnf install poppler-utils

轉成圖片

gs -dNOPAUSE -dBATCH -sDEVICE=png16m -r300 -sOutputFile=page_%03d.png input.pdf

ocr 中文

tesseract page_001.png output_001 -l chi-tra pdf

ocr 英文

tesseract page_001.png output_001 -l eng pdf

--psdm 參數,目前測試調整後, table 換行還是有問題

--psm 常用模式:

  • 3 → 全頁自動檢測文本

  • 6 → 單塊文本

  • 11 → 密集文字或多欄

tesseract page_001.png output_001 -l eng --psm 3 pdf

多頁

for f in page_*.png; do
  base=$(basename $f .png)
  tesseract "$f" "${base}_ocr" -l eng pdf
done

合併

pdfunite page_*_ocr.pdf final_output.pdf

壓縮

gs -sDEVICE=pdfwrite -dPDFSETTINGS=/ebook -o compressed.pdf final_output.pdf