DEV Community

codemee
codemee

Posted on

1

RGB565 轉 RGB888

在使用 MaixPy 時, 攝影機的格式通常會設為 RGB565, 這個模式會用 5+6+5 共 16 個 bits 表示顏色:

R:5   G:6   B:5
←高位元   低位元→
Enter fullscreen mode Exit fullscreen mode

MaixPy 中的 image 物件可以使用 to_bytes() 取得內部使用的 bytesarray 物件 (和 OpenMV 中的 bytearray() 類似), 即可存取個別像素的 RGB565 顏色值。如果想從 bytearray 中更改像素值, 每一個像素值就是 2 個位元組, 高位元組在前, 所以如果想要取得影像中最開頭的像素的 RGB 值, 可以這樣做:

img = sensor.snapshot()
bi = img.to_bytes()
r5 = (bi[0] & 0xF8) >> 3
g6 = ((bi[0] & 0x07) << 3) | ((bi[1] & 0xE0)>>5)
b5 = bi[1] & 0x1F
Enter fullscreen mode Exit fullscreen mode

即可取得以 5、6、5 個 bits 個別表示的 RGB 值。

如果想將這樣的 RGB565 顏色值轉換成 RGB 各用 8 個 bits 表示的 RGB888 格式, 可以這樣做:

r8 = r5 << 3
g8 = g6 << 2
b8 = b5 << 3
Enter fullscreen mode Exit fullscreen mode

這是單純將 r5、b5 從 0~31 的範圍轉換到 0~255 範圍、g6 從 0~63 的範圍轉換到 0~255 範圍的快速算法。不過如果只是這樣簡單的轉換, 會遇到一個問題, 以白色來舉例, RGB565 的白色是:

0x11111 111111 11111
Enter fullscreen mode Exit fullscreen mode

用上述方式轉換成 RGB888 會變成:

R8: 0b11111000
G8: 0b11111100
B8: 0b11111000
Enter fullscreen mode Exit fullscreen mode

你可以發現這不是真正的白色, 在 ARM 開發者網站 上建議我們在轉換後的數值尾端填上高位處的 bits, 例如:

r8 = (r5 << 3) | (r5 >> 2)
g8 = (g6 << 2) | (g6 >> 4)
b8 = (b5 << 3) | (b5 >> 2)
Enter fullscreen mode Exit fullscreen mode

這樣的作法可以讓接近上限的 RGB565 值在轉換成 RGB888 時用高位元來補償低位元, 避免發生顏色的損失。

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (2)

Collapse
 
greatxiang profile image
大相

我来自中国大陆,也在使用maixpy,你解决了困扰了我很多天的问题,谢谢

Collapse
 
codemee profile image
codemee

很高興能幫上忙

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay