在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

電子發燒友App

硬聲App

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示
電子發燒友網>電子資料下載>電子資料>帶有OV7670相機模塊的TinyML

帶有OV7670相機模塊的TinyML

2023-02-03 | zip | 0.32 MB | 次下載 | 2積分

資料介紹

描述

這是我在 TensorFlow 下與 Google Summer of Code (GSoC) 合作的第二個項目。互聯網上沒有合適的文檔來構建自定義圖像識別 TinyML 模型,因此我的 GSoC 導師 Paul Ruiz 建議我嘗試解決它。您還可以通過以下方式構建圖像識別 TinyML 應用程序。快樂修補!

項目背后的想法:

我想解決一個變量較少的問題,因為有關如何使用相機模塊和處理其數據的文檔不是很好。我選擇構建一個 MNIST TinyML 模型,因為在這種情況下,我不需要擔心訓練數據集,它可以讓我專注于項目的重要部分,以啟動和運行項目。但是,既然我已經了解了構建自定義圖像識別項目的所有部分,我已經記錄了如何使用相機模塊收集訓練數據集。

博客的主題/基調?

我想警告您,這個博客可能有點難以理解。對此有一個正確的解釋:使用基于加速度計的應用程序,只需在串行監視器或繪圖儀上打印出一個軸的加速度計值,就可以很容易地進行健全性檢查。相比之下,對圖像識別應用程序進行健全性檢查至少要煩人 10 倍,因為檢查一段代碼是否正在執行所需的操作無法實時可視化。

一些評論

由于單元測試的復雜性,這篇博客可能有點難以理解。我想通過讀者的反饋來解決解釋中的任何差距。因此,請在下方評論您對嵌入式系統圖像識別相關的任何疑問和問題。

TinyML 有意義嗎?

我建議您通讀 TinyML 書的作者 Pete Warden 的這篇精彩文章,以了解為什么在微控制器上運行機器學習模型是有意義的,并且是機器學習的未來。

即使 TinyML 有意義,圖像識別在 TinyML 上有意義嗎?

我們將在此處使用的 OV7670 相機輸出的完整 VGA(640×480 分辨率)對于當前的 TinyML 應用程序來說太大了。uTensor 通過使用 28×28 圖像的 MNIST 運行手寫檢測TensorFlow Lite for Microcontrollers 示例中的人員檢測示例使用 96×96,這已經足夠了。即使是最先進的“Big ML”應用程序也通常只使用 320×320 的圖像。總之,在微型微控制器上運行圖像識別應用程序非常有意義

tensorflow-lite-logo-social_CrFpufeE9u.png?auto=compress%2Cformat&w=740&h=555&fit=max
?

教程簡而言之:

  • 接線
  • OV7670攝像頭模組介紹
  • RGB888 與 RGB565
  • 結論
1_4QRSeQOnxC.png?auto=compress%2Cformat&w=740&h=555&fit=max
?

1、接線

1.a Arduino Nano 33 BLE Sense 引出線

image_z1m6odFUmC.png?auto=compress%2Cformat&w=740&h=555&fit=max
?

1.b 原理圖

image_yFIrIZY6xl.png?auto=compress%2Cformat&w=740&h=555&fit=max
?

1.c Arduino Nano 33 BLE Sense - OV7670 攝像頭模塊

OV7670 相機模塊上的引腳 - Arduino Nano 33 BLE Sense 上的引腳

3.3 至 3.3V

接地到接地

SIOC 至 A5

SIOD 至 A4

VSYNC 至 8

HREF 到 A1

PCLK 到 A0

XCLK 至 9

D7 至 4

D6至6

D5至5

D4 至 3

D3 至 2

D2 至 0 / RX

D1 到 1 / TX

D0 至 10

1.d Arduino Nano 33 BLE Sense - TFT LCD 模塊

1.44" TFT LCD 顯示屏上的引腳 - Arduino Nano 33 BLE Sense 上的引腳

注意:Arduino 板上只有一個 3.3V。使用面包板與其建立多個連接。

LED 至 3.3V

SCK 至 13

SDA 至 11

A0 至 A6

重置為 7

CS到A7

接地到接地

VCC 至 5V

注意:連接到 Arduino 板的 TFT LCD 模塊使用硬件 SPI 引腳。

SPI代表串行外設接口微控制器使用它與一個或多個外圍設備快速通信SPI 通信比 I2C 通信更快。

所有外圍設備共有三個公共引腳:

SCK - 它代表串行時鐘該引腳產生時鐘脈沖,用于同步數據傳輸。

MISO - 它代表主輸入/從輸出MISO 引腳中的這條數據線用于向主機發送數據。

MOSI - 它代表主輸出/從輸入該線用于向從站/外圍設備發送數據。

開發板上的 SPI 引腳:

  • D13-SCK
  • D12 - 味噌
  • D11 - 莫西

我們將只在此處使用 SCK 和 MOSI 引腳,因為我們將向 TFT 發送數據并且不需要 MISO 引腳。

image_vLScZlJehs.png?auto=compress%2Cformat&w=740&h=555&fit=max
?
2_cvnPRrWkif.png?auto=compress%2Cformat&w=740&h=555&fit=max
?

二、OV7670攝像頭模組介紹

2.a OV7670模塊的一般信息

OV7670 攝像頭模塊是一款低成本的 0.3 兆像素 CMOS 彩色攝像頭模塊。它可以 30fps 的速度輸出 640x480 VGA 分辨率的圖像。

特征:

  • 低光操作的高靈敏度
  • 嵌入式便攜式應用的低工作電壓
  • 鏡頭陰影校正
  • 閃爍 (50/60 Hz) 自動檢測
  • 降噪電平自動調整
  • 支持圖像尺寸:VGA、CIF 以及從 CIF 縮小到 40x30 的任何尺寸
  • 用于子采樣的 VarioPixel 方法
  • 自動圖像控制功能包括:自動曝光控制(AEC)、自動增益控制(AGC)、自動白平衡(AWB)、自動帶狀濾波器(ABF)、自動黑電平校準(ABLC)
  • ISP 包括降噪和缺陷校正
  • 支持LED和閃光燈頻閃模式
  • 支持縮放
  • 輸出支持 Raw RGB、RGB(GRB 4:2:2、RGB565/555/444)、YUV (4:2:2) 和 YCbCr (4:2:2) 格式
  • 圖像質量控制包括色彩飽和度、色調、伽馬、銳度(邊緣增強)和防暈染
  • 飽和度自動調整(UV調整)
  • 邊緣增強級別自動調整

規格

  • 感光陣列:640 x 480。
  • IO 電壓:2.5V 至 3.0V。
  • 工作功率:60mW/15fpsVGAYUV。
  • 休眠模式:<20μA。
  • 工作溫度:-30 至 70 攝氏度。
  • 輸出格式:YUV/YCbCr4:2:2 RGB565/555/444 GRB4:2:2 原始 RGB 數據(8 位)。
  • 鏡頭尺寸:1/6 英寸。
  • 視角:25度。
  • 最大限度。幀速率:30fps VGA。
  • 靈敏度:1.3V / (Lux-sec)。
  • 信噪比:46 分貝。
  • 動態范圍:52 分貝。
  • 瀏覽方式:按行。
  • 電子曝光:1 至 510 行。
  • 像素覆蓋范圍:3.6μm x 3.6μm。
  • 電流:60℃時為 12 mV/s。
  • PCB 尺寸(長 x 寬):約 1.4 x 1.4 英寸/3.5 x 3.5 厘米。
ov7670_EsYNCDP5eh.jpg?auto=compress%2Cformat&w=740&h=555&fit=max
OV7670 攝像頭模塊的圖像
?

2.b 軟件設置:安裝“Arduino_OV767x”庫

首先,您需要安裝 Arduino IDE。接下來,在“工具”部分下,單擊“管理庫”,搜索OV7670 ,選擇Arduino_OV767x庫并單擊“安裝”。

OV767X 庫中支持的圖像配置:

  • VGA – 640 x 480
  • CIF – 352 x 240
  • QVGA – 320 x 240
  • QCIF – 176 x 144
manage_libraries_installation_wNifahRiLP.jpeg?auto=compress%2Cformat&w=740&h=555&fit=max
打開 Arduino 環境并單擊工具 > 管理庫
?
ov7670_installation_WjkLejElqy.png?auto=compress%2Cformat&w=740&h=555&fit=max
搜索 OV7670 > 安裝 Arduino_OV767X 庫
?

2.c 軟件設置:安裝Processing

Processing是一個簡單的編程環境,由麻省理工學院媒體實驗室的研究生創建,旨在更輕松地開發以動畫為重點的面向視覺的應用程序,并通過交互為用戶提供即時反饋。

使用此鏈接下載并安裝 Processing 。

為什么我需要下載這個軟件?我們將使用此應用程序可視化 OV7670 相機模塊通過串行端口發送的相機輸出。
processing_installation_zaO5IOsJV1.png?auto=compress%2Cformat&w=740&h=555&fit=max
為您的操作系統下載正確的配置
?
processing_greeting_page_MJyP0FiO3U.png?auto=compress%2Cformat&w=740&h=555&fit=max
當您第一次打開 Processing 應用程序時,您會看到此頁面
?

2.d 使用處理:測試模式

本小節的 Github 鏈接。

打開一個 Arduino 草圖,將下面的草圖復制并粘貼到草圖中,將其上傳到您的電路板。

Processing_test_pattern.ino:

/*
  Circuit:
    - Arduino Nano 33 BLE board
    - OV7670 camera module:
      - 3.3 connected to 3.3
      - GND connected GND
      - SIOC connected to A5
      - SIOD connected to A4
      - VSYNC connected to 8
      - HREF connected to A1
      - PCLK connected to A0
      - XCLK connected to 9
      - D7 connected to 4
      - D6 connected to 6
      - D5 connected to 5
      - D4 connected to 3
      - D3 connected to 2
      - D2 connected to 0 / RX
      - D1 connected to 1 / TX
      - D0 connected to 10
*/

#include 

int bytesPerFrame;

byte data[320 * 240 * 2]; // QVGA: 320x240 X 2 bytes per pixel (RGB565)

void setup() {
  Serial.begin(115200);
  while (!Serial);

  if (!Camera.begin(QVGA, RGB565, 1)) {
    Serial.println("Failed to initialize camera!");
    while (1);
  }

  bytesPerFrame = Camera.width() * Camera.height() * Camera.bytesPerPixel();

  Camera.testPattern();
}

void loop() {
  Camera.readFrame(data);

  Serial.write(data, bytesPerFrame);
}

將上述草圖上傳到 Arduino 板后,打開 Processing 應用程序并將以下代碼復制粘貼到一個新文件中。

處理草圖:

import processing.serial.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

Serial myPort;

// must match resolution used in the sketch
final int cameraWidth = 320;
final int cameraHeight = 240;

final int cameraBytesPerPixel = 2;

final int bytesPerFrame = cameraWidth * cameraHeight * cameraBytesPerPixel;

PImage myImage;

void setup()
{
  size(320, 240);

  // if you have only ONE serial port active
  //myPort = new Serial(this, Serial.list()[0], 9600); // if you have only ONE serial port active

  // if you know the serial port name
  //myPort = new Serial(this, "COM5", 9600);                    // Windows
  //myPort = new Serial(this, "/dev/ttyACM0", 9600);             // Linux
  myPort = new Serial(this, "/dev/cu.usbmodem14101", 9600);  // Mac

  // wait for full frame of bytes
  myPort.buffer(bytesPerFrame);  

  myImage = createImage(cameraWidth, cameraHeight, RGB);
}

void draw()
{
  image(myImage, 0, 0);
}

void serialEvent(Serial myPort) {
  byte[] frameBuffer = new byte[bytesPerFrame];

  // read the saw bytes in
  myPort.readBytes(frameBuffer);

  // create image to set byte values
  PImage img = createImage(cameraWidth, cameraHeight, RGB);

  // access raw bytes via byte buffer
  ByteBuffer bb = ByteBuffer.wrap(frameBuffer);
  bb.order(ByteOrder.BIG_ENDIAN);

  int i = 0;

  img.loadPixels();
  while (bb.hasRemaining()) {
    // read 16-bit pixel
    short p = bb.getShort();

    // convert RGB565 to RGB 24-bit
    int r = ((p >> 11) & 0x1f) << 3;
    int g = ((p >> 5) & 0x3f) << 2;
    int b = ((p >> 0) & 0x1f) << 3;

    // set pixel color
    img.pixels[i++] = color(r, g, b);
  }
  img.updatePixels();

  // assign image for next draw
  myImage = img;
}

現在,在上面取消注釋特定于您的操作系統的行。然后單擊“運行”按鈕。

// if you know the serial port name
  //myPort = new Serial(this, "COM5", 9600);                    // Windows
  //myPort = new Serial(this, "/dev/ttyACM0", 9600);             // Linux
  //myPort = new Serial(this, "/dev/cu.usbmodem14101", 9600);  // Mac

您應該得到如下所示的輸出:

testpattern-1024x685_8I0BcKrYTc.png?auto=compress%2Cformat&w=740&h=555&fit=max
您應該得到類似于此的輸出。
?

2.e 解釋:測試模式

Processing_test_pattern.ino:

byte data[320 * 240 * 2]; // QVGA: 320x240 X 2 bytes per pixel (RGB565)

這行代碼建立了一個 byte 類型的數組。我們將使用 RGB565 顏色格式,因此每個像素需要 2 個字節,我們將在此處使用的圖像格式是 QVGA,大小為 320x240 像素。因此,數組的大小將是每個像素的顏色所需的高度 * 寬度 * 字節數實際上,它轉換為320 * 240 * 2

Serial.begin(115200);
  while (!Serial);

這行代碼設置了串口,用于在計算機和單片機之間傳輸數據。

if (!Camera.begin(QVGA, RGB565, 1)) {
    Serial.println("Failed to initialize camera!");
    while (1);
  }

上面的代碼行設置了 OV7670 攝像頭模塊。在本例中,我們已將其初始化為使用QVGA圖像格式和RGB565顏色格式。

Camera.testPattern();

這行代碼設置相機通過串行端口發送測試圖像。

Camera.readFrame(data);

這行代碼從攝像頭中讀取一幀圖像并將其存儲在我們之前聲明的數組中。

Serial.write(data, bytesPerFrame);

最后,這行代碼將數組的值寫入串行監視器。

處理草圖:

// must match resolution used in the sketch
final int cameraWidth = 320;
final int cameraHeight = 240;

這些代碼行設置 cameraWidth 和 cameraHeight 以匹配 Arduino 草圖中的大小。

// if you know the serial port name
  //myPort = new Serial(this, "COM5", 9600);                    // Windows
  //myPort = new Serial(this, "/dev/ttyACM0", 9600);             // Linux
  //myPort = new Serial(this, "/dev/cu.usbmodem14101", 9600);  // Mac

這些代碼行指定了微控制器和計算機之間傳輸數據的串行端口。

// convert RGB565 to RGB 24-bit
    int r = ((p >> 11) & 0x1f) << 3;
    int g = ((p >> 5) & 0x3f) << 2;
    int b = ((p >> 0) & 0x1f) << 3;

這些代碼行將 RGB565 顏色格式轉換為 RGB888 格式以顯示在您的計算機屏幕上。這將在后面的章節中詳細解釋。

2.f 使用處理:實時圖像

本小節的 Github 鏈接。

打開一個 Arduino 草圖,將下面的草圖復制并粘貼到草圖中,將其上傳到您的電路板。

Processing_ov7670_live_image.ino

/*
  Circuit:
    - Arduino Nano 33 BLE board
    - OV7670 camera module:
      - 3.3 connected to 3.3
      - GND connected GND
      - SIOC connected to A5
      - SIOD connected to A4
      - VSYNC connected to 8
      - HREF connected to A1
      - PCLK connected to A0
      - XCLK connected to 9
      - D7 connected to 4
      - D6 connected to 6
      - D5 connected to 5
      - D4 connected to 3
      - D3 connected to 2
      - D2 connected to 0 / RX
      - D1 connected to 1 / TX
      - D0 connected to 10
*/

#include 

int bytesPerFrame;

byte data[320 * 240 * 2]; // QVGA: 320x240 X 2 bytes per pixel (RGB565)

void setup() {
  Serial.begin(115200);
  while (!Serial);

  if (!Camera.begin(QVGA, RGB565, 1)) {
    Serial.println("Failed to initialize camera!");
    while (1);
  }

  bytesPerFrame = Camera.width() * Camera.height() * Camera.bytesPerPixel();

  Camera.testPattern();
}

void loop() {
  Camera.readFrame(data);

  Serial.write(data, bytesPerFrame);
}

將上述草圖上傳到 Arduino 板后,打開 Processing 應用程序并將以下代碼復制粘貼到一個新文件中。

處理草圖:

import processing.serial.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

Serial myPort;

// must match resolution used in the sketch
final int cameraWidth = 320;
final int cameraHeight = 240;

final int cameraBytesPerPixel = 2;

final int bytesPerFrame = cameraWidth * cameraHeight * cameraBytesPerPixel;

PImage myImage;

void setup()
{
  size(320, 240);

  // if you have only ONE serial port active
  //myPort = new Serial(this, Serial.list()[0], 9600); // if you have only ONE serial port active

  // if you know the serial port name
  //myPort = new Serial(this, "COM5", 9600);                    // Windows
  //myPort = new Serial(this, "/dev/ttyACM0", 9600);             // Linux
  myPort = new Serial(this, "/dev/cu.usbmodem14101", 9600);  // Mac

  // wait for full frame of bytes
  myPort.buffer(bytesPerFrame);  

  myImage = createImage(cameraWidth, cameraHeight, RGB);
}

void draw()
{
  image(myImage, 0, 0);
}

void serialEvent(Serial myPort) {
  byte[] frameBuffer = new byte[bytesPerFrame];

  // read the saw bytes in
  myPort.readBytes(frameBuffer);

  // create image to set byte values
  PImage img = createImage(cameraWidth, cameraHeight, RGB);

  // access raw bytes via byte buffer
  ByteBuffer bb = ByteBuffer.wrap(frameBuffer);
  bb.order(ByteOrder.BIG_ENDIAN);

  int i = 0;

  img.loadPixels();
  while (bb.hasRemaining()) {
    // read 16-bit pixel
    short p = bb.getShort();

    // convert RGB565 to RGB 24-bit
    int r = ((p >> 11) & 0x1f) << 3;
    int g = ((p >> 5) & 0x3f) << 2;
    int b = ((p >> 0) & 0x1f) << 3;

    // set pixel color
    img.pixels[i++] = color(r, g, b);
  }
  img.updatePixels();

  // assign image for next draw
  myImage = img;
}

現在,在上面取消注釋特定于您的操作系統的行。然后單擊“運行”按鈕。

// if you know the serial port name
  //myPort = new Serial(this, "COM5", 9600);                    // Windows
  //myPort = new Serial(this, "/dev/ttyACM0", 9600);             // Linux
  //myPort = new Serial(this, "/dev/cu.usbmodem14101", 9600);  // Mac

您應該得到如下所示的輸出:

liveqvga-1-1024x688_omNFH6SB0M.png?auto=compress%2Cformat&w=740&h=555&fit=max
你應該在屏幕上看到你的相機正在看的任何東西的圖像。
?

2.g 解釋:實時圖像

Processing_ov7670_live_image.ino:

byte data[320 * 240 * 2]; // QVGA: 320x240 X 2 bytes per pixel (RGB565)

這行代碼建立了一個 byte 類型的數組。我們將使用 RGB565 顏色格式,因此每個像素需要 2 個字節,我們將在此處使用的圖像格式是 QVGA,其大小為 320x240 像素。因此,數組的大小將是每個像素顏色所需的高度 * 寬度 * 字節數。實際上,它轉換為320 * 240 * 2

Serial.begin(115200);
  while (!Serial);

這行代碼設置了串口,用于在計算機和單片機之間傳輸數據。

if (!Camera.begin(QVGA, RGB565, 1)) {
    Serial.println("Failed to initialize camera!");
    while (1);
  }

上面的代碼行設置了 OV7670 攝像頭模塊。在本例中,我們已將其初始化為使用QVGA圖像格式和RGB565顏色格式。

Camera.testPattern();

這行代碼設置相機通過串行端口發送測試圖像。

Camera.readFrame(data);

這行代碼從攝像頭中讀取一幀圖像并將其存儲在我們之前聲明的數組中。

Serial.write(data, bytesPerFrame);

最后,這行代碼將數組寫入串行監視器。

處理草圖:

// must match resolution used in the sketch
final int cameraWidth = 320;
final int cameraHeight = 240;

這些代碼行設置 cameraWidth 和 cameraHeight 以匹配 Arduino 草圖中的大小。

// if you know the serial port name
  //myPort = new Serial(this, "COM5", 9600);                    // Windows
  //myPort = new Serial(this, "/dev/ttyACM0", 9600);             // Linux
  //myPort = new Serial(this, "/dev/cu.usbmodem14101", 9600);  // Mac

這些代碼行指定了微控制器和計算機之間傳輸數據的串行端口。

// convert RGB565 to RGB 24-bit
    int r = ((p >> 11) & 0x1f) << 3;
    int g = ((p >> 5) & 0x3f) << 2;
    int b = ((p >> 0) & 0x1f) << 3;

這些代碼行將 RGB565 顏色格式轉換為 RGB888 格式,以便在您的計算機屏幕上顯示。這將在后面的章節中詳細解釋。

2.h 這種方法的問題,以及可能的解決方案

處理應用程序顯示鋸齒形測試圖案而不是實際測試圖案,并顯示破損/褪色圖像而不是正確的實時圖像。這已在 Github 討論和 Arduino 論壇中進行了討論。我已將鏈接附加到下面的鏈接。

鏈接到 Github 討論
鏈接到 Arduino 論壇

一些建議的解決方案:

1.使用較短的電線

  • 我的看法:我將 20 厘米的電線更改為 10 厘米,但這并沒有什么不同。

2. 試試 Ubuntu Linux

3.改變FPS

  • 我的看法:我將其更改為 1/5/30 FPS,但沒有任何改進。

4.更改串口速率

  • 我的看法:我將串行速率從 9600 bps 更改為 115200 bps。但問題仍然沒有改善

問題的合理原因:

  • 論壇上的大多數人都認為導致問題的是 Windows 處理速度,切換到 Ubuntu 應該可以解決問題。
25d878d8fbecdca5bc1693b8e52bb4cfb63d4b2c_JN0FbZFtDp.png?auto=compress%2Cformat&w=740&h=555&fit=max
真實測試模式輸出
?
94660018-01a9a600-02ba-11eb-8dc1-c9350230eadb_DApm9lW9qp.png?auto=compress%2Cformat&w=740&h=555&fit=max
真實的實時圖像輸出
?
94736283-d3ab7c80-0320-11eb-8b71-8566f959d6bd_AodWZWqcQL.png?auto=compress%2Cformat&w=740&h=555&fit=max
?
section2_dV0wxqvTnX.png?auto=compress%2Cformat&w=740&h=555&fit=max
?

3. RGB888 與 RGB565

3.a 關于RGB888的一般信息

RGB888 顏色模型使用 8 位來表示每種顏色。透明度 (alpha) 值假定為最大值 (255)。

紅色、藍色和綠色可能的最大值為 255。

一些例子:

  • 白色:(R, G, B) = (255, 255, 255)
  • 黑色:(R, G, B) = (0, 0, 0)
rgb888_RSaK5Wjuue.png?auto=compress%2Cformat&w=740&h=555&fit=max
?

3.b 關于RGB565的一般信息

RGB565 用于以 16 位表示顏色,而不是 24 位來指定顏色。為了充分利用這 16 位,紅色和藍色編碼為 5 位,綠色編碼為 6 位。這是因為人眼能夠更好地看到更多的綠色陰影。

RGB565 顏色格式中紅色和藍色值的最大可能值為 31,而綠色的最大值為 63。

有趣的事實:RGB565 只有 RGB888 顏色的 0.39%(65k 對 16m)
rgb565_VBnLoPgnLJ.gif?auto=compress&gifq=35&w=740&h=555&fit=max&fm=mp4
?

3.c 將 RGB888 值轉換為 RGB565

/*
Assumption:
r = 8 bits
g = 8 bits
b = 8 bits
*/
rgb565 = ((r & 0b11111000) << 8) | ((g & 0b11111100) << 3) | (b >> 3);

我們轉移:

  • r左移 11 位,并丟棄最后 3 位
  • g左移 5 位,并丟棄最后 2 位
  • b右移 3 位以丟棄最后 3 位

我們最終按位或將這 3 個連接成一個 16 位表示。

例子:

讓我們將白色從 RGB888 顏色空間轉換為 RGB565 顏色空間。

由于我們已經知道兩個顏色空間可能的最大可能值,我們應該期望

  • RGB888顏色空間中的 (255, 255, 255)
  • RGB565顏色空間中的 (31, 63, 31)

在這個問題中,

  • r = 十進制的 255 或二進制的 0000000011111111
  • g = 十進制的 255 或二進制的 0000000011111111
  • b = 十進制的 255 或二進制的 0000000011111111

對于紅色:

  • r = 0000000011111111
  • (r & 0b11111000) = 0000000011111000
  • (r & 0b11111000) << 8) = 1111100000000000

對于綠色:

  • g = 0000000011111111
  • (g & 0b11111100) = 0000000011111100
  • ((g & 0b11111100) << 3) = 0000011111100000

對于藍色:

  • b = 0000000011111111
  • (b >> 3) = 0000000000011111

結合這三個等式:

  • rgb565 = ((r & 0b11111000) << 8) | ((g & 0b11111100) << 3) | (b >> 3);
  • rgb565 = ( 1111100000000000 | 0000011111100000 | 0000000000011111)
  • rgb565 = 1111111111111111

在RGB565色彩空間中,

  • 前5位對應紅色值
  • 接下來的 6 位對應綠色值
  • 最后 5 位對應藍色值
  • 這轉換為 (31, 63, 31),這是預期的輸出!

3.d 將 RGB565 值轉換為 RGB888

int r = ((p >> 11) & 0b00011111) << 3;
int g = ((p >> 5) & 0b00111111) << 2;
int b = ((p >> 0) & 0b00011111) << 3;
  • 對于紅色,我們左移 11 位,與 0b00011111 按位與,右移 3 位
  • 對于綠色,我們左移 5 位,與 0b00111111 按位與,右移 2 位
  • 對于藍色,我們左移 0 位,與 0b00011111 按位與,右移 3 位

例子:

讓我們將白色從 RGB565 顏色空間轉換為 RGB888 顏色空間。

由于我們已經知道兩個顏色空間可能的最大可能值,我們應該期望

  • RGB565顏色空間中的 (31, 63, 31)
  • RGB888顏色空間中的 (248, 252, 248)

我們不應該期望 RGB888 顏色空間中的 (255, 255, 255) 嗎?

RGB565 只有 RGB888 顏色的 0.39%(65k 對 16m)。因此它無法覆蓋 RGB888 的整個頻譜。

在這個問題中,

RGB 格式中,白色 = 1111111111111111

對于紅色:

  • p(此處:白色)= 1111111111111111
  • (p >> 11) = 00011111
  • ((p >> 11) & 0b00011111) = 00011111
  • (((p >> 11) & 0b00011111) << 3) = 11111000

對于綠色:

  • p(此處:白色)= 1111111111111111
  • (p >> 5) = 0000011111111111
  • ((p >> 5) & 0b00111111) = 00111111
  • (((p >> 5) & 0b00111111) << 2) = 11111100

對于藍色:

  • p(此處:白色)= 1111111111111111
  • (p >> 0) = 1111111111111111
  • ((p >> 0) & 0b00011111) = 00011111
  • ((p >> 0) & 0b00011111) << 3 = 11111000

結合這三個輸出:

  • 最終紅色值 = 0b11111000 = 248
  • 最終綠色值 = 0b11111100 = 252
  • 最終藍色值 = 0b11111000 = 248
  • 這是預期的輸出!
鏈接到 RGB565 顏色選擇器
RGB88轉RGB565轉換器
section2__2__PRa52WoYBS.png?auto=compress%2Cformat&w=740&h=555&fit=max
?

結論

我感謝我的 GSoC 導師 Paul Ruiz,他在整個項目中指導我!

鏈接


下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數據手冊
  2. 1.06 MB  |  532次下載  |  免費
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費
  5. 3TC358743XBG評估板參考手冊
  6. 1.36 MB  |  330次下載  |  免費
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費
  9. 5元宇宙深度解析—未來的未來-風口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費
  11. 6迪文DGUS開發指南
  12. 31.67 MB  |  194次下載  |  免費
  13. 7元宇宙底層硬件系列報告
  14. 13.42 MB  |  182次下載  |  免費
  15. 8FP5207XR-G1中文應用手冊
  16. 1.09 MB  |  178次下載  |  免費

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費
  3. 2555集成電路應用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費
  7. 4開關電源設計實例指南
  8. 未知  |  21549次下載  |  免費
  9. 5電氣工程師手冊免費下載(新編第二版pdf電子書)
  10. 0.00 MB  |  15349次下載  |  免費
  11. 6數字電路基礎pdf(下載)
  12. 未知  |  13750次下載  |  免費
  13. 7電子制作實例集錦 下載
  14. 未知  |  8113次下載  |  免費
  15. 8《LED驅動電路設計》 溫德爾著
  16. 0.00 MB  |  6656次下載  |  免費

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費
  3. 2protel99se軟件下載(可英文版轉中文版)
  4. 78.1 MB  |  537798次下載  |  免費
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費
  11. 6電路仿真軟件multisim 10.0免費下載
  12. 340992  |  191187次下載  |  免費
  13. 7十天學會AVR單片機與C語言視頻教程 下載
  14. 158M  |  183279次下載  |  免費
  15. 8proe5.0野火版下載(中文版免費下載)
  16. 未知  |  138040次下載  |  免費
主站蜘蛛池模板: 1024国产看片在线观看| 国产精品午夜寂寞视频| 天天爽夜夜爽视频| 天天躁狠狠躁| 能直接看黄的网站| 日本在线视频二区| 99久久久久久久| 羞羞爱爱| 在线亚洲精品| 久久免费精品高清麻豆| 亚洲香蕉电影| 清朝荒淫牲艳史在线播放| 中文天堂最新版www| 四虎在线永久| 久久婷婷影院| bt 另类 专区 欧美 制服| 国产三级黄色毛片| 亚洲第一视频在线| 久久手机看片| 中文字幕一区视频| 亚洲精品乱码久久久久久蜜桃图片| 日韩美女拍拍免费视频网站| 黄色片 720p| 午夜视频在线观看免费高清| www夜夜操com| 资源种子在线观看| 户外露出精品视频国产| 天天干天天谢| 国产精品区在线12p| 亚洲美女爱爱| www你懂的| 日本在线不卡一区二区| 美女网站色黄| 一级片免费视频| 2021国产成人午夜精品| 色婷婷基地| 操你啦在线视频| 国内精品第一页| 种子在线搜索| freesexvideo性欧美医生护士| 91视频免费网站|