電子發(fā)燒友App

硬聲App

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示
創(chuàng)作
電子發(fā)燒友網(wǎng)>電子資料下載>電子資料>帶有OV7670相機(jī)模塊的TinyML

帶有OV7670相機(jī)模塊的TinyML

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

資料介紹

描述

這是我在 TensorFlow 下與 Google Summer of Code (GSoC) 合作的第二個(gè)項(xiàng)目。互聯(lián)網(wǎng)上沒(méi)有合適的文檔來(lái)構(gòu)建自定義圖像識(shí)別 TinyML 模型,因此我的 GSoC 導(dǎo)師 Paul Ruiz 建議我嘗試解決它。您還可以通過(guò)以下方式構(gòu)建圖像識(shí)別 TinyML 應(yīng)用程序。快樂(lè)修補(bǔ)!

項(xiàng)目背后的想法:

我想解決一個(gè)變量較少的問(wèn)題,因?yàn)橛嘘P(guān)如何使用相機(jī)模塊和處理其數(shù)據(jù)的文檔不是很好。我選擇構(gòu)建一個(gè) MNIST TinyML 模型,因?yàn)樵谶@種情況下,我不需要擔(dān)心訓(xùn)練數(shù)據(jù)集,它可以讓我專(zhuān)注于項(xiàng)目的重要部分,以啟動(dòng)和運(yùn)行項(xiàng)目。但是,既然我已經(jīng)了解了構(gòu)建自定義圖像識(shí)別項(xiàng)目的所有部分,我已經(jīng)記錄了如何使用相機(jī)模塊收集訓(xùn)練數(shù)據(jù)集。

博客的主題/基調(diào)?

我想警告您,這個(gè)博客可能有點(diǎn)難以理解。對(duì)此有一個(gè)正確的解釋?zhuān)菏褂没诩铀俣扔?jì)的應(yīng)用程序,只需在串行監(jiān)視器或繪圖儀上打印出一個(gè)軸的加速度計(jì)值,就可以很容易地進(jìn)行健全性檢查。相比之下,對(duì)圖像識(shí)別應(yīng)用程序進(jìn)行健全性檢查至少要煩人 10 倍,因?yàn)闄z查一段代碼是否正在執(zhí)行所需的操作無(wú)法實(shí)時(shí)可視化。

一些評(píng)論

由于單元測(cè)試的復(fù)雜性,這篇博客可能有點(diǎn)難以理解。我想通過(guò)讀者的反饋來(lái)解決解釋中的任何差距。因此,請(qǐng)?jiān)谙路皆u(píng)論您對(duì)嵌入式系統(tǒng)圖像識(shí)別相關(guān)的任何疑問(wèn)和問(wèn)題。

TinyML 有意義嗎?

我建議您通讀 TinyML 書(shū)的作者 Pete Warden 的這篇精彩文章,以了解為什么在微控制器上運(yùn)行機(jī)器學(xué)習(xí)模型是有意義的,并且是機(jī)器學(xué)習(xí)的未來(lái)。

即使 TinyML 有意義,圖像識(shí)別在 TinyML 上有意義嗎?

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

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

教程簡(jiǎn)而言之:

  • 接線
  • OV7670攝像頭模組介紹
  • RGB888 與 RGB565
  • 結(jié)論
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 相機(jī)模塊上的引腳 - 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 板上只有一個(gè) 3.3V。使用面包板與其建立多個(gè)連接。

LED 至 3.3V

SCK 至 13

SDA 至 11

A0 至 A6

重置為 7

CS到A7

接地到接地

VCC 至 5V

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

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

所有外圍設(shè)備共有三個(gè)公共引腳:

SCK - 它代表串行時(shí)鐘。該引腳產(chǎn)生時(shí)鐘脈沖,用于同步數(shù)據(jù)傳輸。

MISO - 它代表主輸入/從輸出。MISO 引腳中的這條數(shù)據(jù)線用于向主機(jī)發(fā)送數(shù)據(jù)。

MOSI - 它代表主輸出/從輸入。該線用于向從站/外圍設(shè)備發(fā)送數(shù)據(jù)。

開(kāi)發(fā)板上的 SPI 引腳:

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

我們將只在此處使用 SCK 和 MOSI 引腳,因?yàn)槲覀儗⑾?TFT 發(fā)送數(shù)據(jù)并且不需要 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 分辨率的圖像。

特征:

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

規(guī)格

  • 感光陣列: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 數(shù)據(jù)(8 位)。
  • 鏡頭尺寸:1/6 英寸。
  • 視角:25度。
  • 最大限度。幀速率:30fps VGA。
  • 靈敏度:1.3V / (Lux-sec)。
  • 信噪比:46 分貝。
  • 動(dòng)態(tài)范圍:52 分貝。
  • 瀏覽方式:按行。
  • 電子曝光:1 至 510 行。
  • 像素覆蓋范圍:3.6μm x 3.6μm。
  • 電流:60℃時(shí)為 12 mV/s。
  • PCB 尺寸(長(zhǎng) 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 軟件設(shè)置:安裝“Arduino_OV767x”庫(kù)

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

OV767X 庫(kù)中支持的圖像配置:

  • 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
打開(kāi) Arduino 環(huán)境并單擊工具 > 管理庫(kù)
?
ov7670_installation_WjkLejElqy.png?auto=compress%2Cformat&w=740&h=555&fit=max
搜索 OV7670 > 安裝 Arduino_OV767X 庫(kù)
?

2.c 軟件設(shè)置:安裝Processing

Processing是一個(gè)簡(jiǎn)單的編程環(huán)境,由麻省理工學(xué)院媒體實(shí)驗(yàn)室的研究生創(chuàng)建,旨在更輕松地開(kāi)發(fā)以動(dòng)畫(huà)為重點(diǎn)的面向視覺(jué)的應(yīng)用程序,并通過(guò)交互為用戶(hù)提供即時(shí)反饋。

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

為什么我需要下載這個(gè)軟件?我們將使用此應(yīng)用程序可視化 OV7670 相機(jī)模塊通過(guò)串行端口發(fā)送的相機(jī)輸出。
processing_installation_zaO5IOsJV1.png?auto=compress%2Cformat&w=740&h=555&fit=max
為您的操作系統(tǒng)下載正確的配置
?
processing_greeting_page_MJyP0FiO3U.png?auto=compress%2Cformat&w=740&h=555&fit=max
當(dāng)您第一次打開(kāi) Processing 應(yīng)用程序時(shí),您會(huì)看到此頁(yè)面
?

2.d 使用處理:測(cè)試模式

本小節(jié)的 Github 鏈接。

打開(kāi)一個(gè) Arduino 草圖,將下面的草圖復(fù)制并粘貼到草圖中,將其上傳到您的電路板。

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 板后,打開(kāi) Processing 應(yīng)用程序并將以下代碼復(fù)制粘貼到一個(gè)新文件中。

處理草圖:

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;
}

現(xiàn)在,在上面取消注釋特定于您的操作系統(tǒng)的行。然后單擊“運(yùn)行”按鈕。

// 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

您應(yīng)該得到如下所示的輸出:

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

2.e 解釋?zhuān)簻y(cè)試模式

Processing_test_pattern.ino:

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

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

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

這行代碼設(shè)置了串口,用于在計(jì)算機(jī)和單片機(jī)之間傳輸數(shù)據(jù)。

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

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

Camera.testPattern();

這行代碼設(shè)置相機(jī)通過(guò)串行端口發(fā)送測(cè)試圖像。

Camera.readFrame(data);

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

Serial.write(data, bytesPerFrame);

最后,這行代碼將數(shù)組的值寫(xiě)入串行監(jiān)視器。

處理草圖:

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

這些代碼行設(shè)置 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

這些代碼行指定了微控制器和計(jì)算機(jī)之間傳輸數(shù)據(jù)的串行端口。

// 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 顏色格式轉(zhuǎn)換為 RGB888 格式以顯示在您的計(jì)算機(jī)屏幕上。這將在后面的章節(jié)中詳細(xì)解釋。

2.f 使用處理:實(shí)時(shí)圖像

本小節(jié)的 Github 鏈接。

打開(kāi)一個(gè) Arduino 草圖,將下面的草圖復(fù)制并粘貼到草圖中,將其上傳到您的電路板。

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 板后,打開(kāi) Processing 應(yīng)用程序并將以下代碼復(fù)制粘貼到一個(gè)新文件中。

處理草圖:

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;
}

現(xiàn)在,在上面取消注釋特定于您的操作系統(tǒng)的行。然后單擊“運(yùn)行”按鈕。

// 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

您應(yīng)該得到如下所示的輸出:

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

2.g 解釋?zhuān)簩?shí)時(shí)圖像

Processing_ov7670_live_image.ino:

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

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

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

這行代碼設(shè)置了串口,用于在計(jì)算機(jī)和單片機(jī)之間傳輸數(shù)據(jù)。

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

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

Camera.testPattern();

這行代碼設(shè)置相機(jī)通過(guò)串行端口發(fā)送測(cè)試圖像。

Camera.readFrame(data);

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

Serial.write(data, bytesPerFrame);

最后,這行代碼將數(shù)組寫(xiě)入串行監(jiān)視器。

處理草圖:

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

這些代碼行設(shè)置 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

這些代碼行指定了微控制器和計(jì)算機(jī)之間傳輸數(shù)據(jù)的串行端口。

// 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 顏色格式轉(zhuǎn)換為 RGB888 格式,以便在您的計(jì)算機(jī)屏幕上顯示。這將在后面的章節(jié)中詳細(xì)解釋。

2.h 這種方法的問(wèn)題,以及可能的解決方案

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

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

一些建議的解決方案:

1.使用較短的電線

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

2. 試試 Ubuntu Linux

3.改變FPS

  • 我的看法:我將其更改為 1/5/30 FPS,但沒(méi)有任何改進(jìn)。

4.更改串口速率

  • 我的看法:我將串行速率從 9600 bps 更改為 115200 bps。但問(wèn)題仍然沒(méi)有改善

問(wèn)題的合理原因:

  • 論壇上的大多數(shù)人都認(rèn)為導(dǎo)致問(wèn)題的是 Windows 處理速度,切換到 Ubuntu 應(yīng)該可以解決問(wèn)題。
25d878d8fbecdca5bc1693b8e52bb4cfb63d4b2c_JN0FbZFtDp.png?auto=compress%2Cformat&w=740&h=555&fit=max
真實(shí)測(cè)試模式輸出
?
94660018-01a9a600-02ba-11eb-8dc1-c9350230eadb_DApm9lW9qp.png?auto=compress%2Cformat&w=740&h=555&fit=max
真實(shí)的實(shí)時(shí)圖像輸出
?
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 關(guān)于RGB888的一般信息

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

紅色、藍(lán)色和綠色可能的最大值為 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 關(guān)于RGB565的一般信息

RGB565 用于以 16 位表示顏色,而不是 24 位來(lái)指定顏色。為了充分利用這 16 位,紅色和藍(lán)色編碼為 5 位,綠色編碼為 6 位。這是因?yàn)槿搜勰軌蚋玫乜吹礁嗟木G色陰影。

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

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

3.c 將 RGB888 值轉(zhuǎn)換為 RGB565

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

我們轉(zhuǎn)移:

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

我們最終按位或?qū)⑦@ 3 個(gè)連接成一個(gè) 16 位表示。

例子:

讓我們將白色從 RGB888 顏色空間轉(zhuǎn)換為 RGB565 顏色空間。

由于我們已經(jīng)知道兩個(gè)顏色空間可能的最大可能值,我們應(yīng)該期望

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

在這個(gè)問(wèn)題中,

  • r = 十進(jìn)制的 255 或二進(jìn)制的 0000000011111111
  • g = 十進(jìn)制的 255 或二進(jìn)制的 0000000011111111
  • b = 十進(jìn)制的 255 或二進(jìn)制的 0000000011111111

對(duì)于紅色:

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

對(duì)于綠色:

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

對(duì)于藍(lán)色:

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

結(jié)合這三個(gè)等式:

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

在RGB565色彩空間中,

  • 前5位對(duì)應(yīng)紅色值
  • 接下來(lái)的 6 位對(duì)應(yīng)綠色值
  • 最后 5 位對(duì)應(yīng)藍(lán)色值
  • 這轉(zhuǎn)換為 (31, 63, 31),這是預(yù)期的輸出!

3.d 將 RGB565 值轉(zhuǎn)換為 RGB888

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

例子:

讓我們將白色從 RGB565 顏色空間轉(zhuǎn)換為 RGB888 顏色空間。

由于我們已經(jīng)知道兩個(gè)顏色空間可能的最大可能值,我們應(yīng)該期望

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

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

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

在這個(gè)問(wèn)題中,

RGB 格式中,白色 = 1111111111111111

對(duì)于紅色:

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

對(duì)于綠色:

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

對(duì)于藍(lán)色:

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

結(jié)合這三個(gè)輸出:

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

結(jié)論

我感謝我的 GSoC 導(dǎo)師 Paul Ruiz,他在整個(gè)項(xiàng)目中指導(dǎo)我!

鏈接


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

評(píng)論

查看更多

下載排行

本周

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

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費(fèi)
  3. 2555集成電路應(yīng)用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費(fèi)
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費(fèi)
  7. 4開(kāi)關(guān)電源設(shè)計(jì)實(shí)例指南
  8. 未知  |  21549次下載  |  免費(fèi)
  9. 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書(shū))
  10. 0.00 MB  |  15349次下載  |  免費(fèi)
  11. 6數(shù)字電路基礎(chǔ)pdf(下載)
  12. 未知  |  13750次下載  |  免費(fèi)
  13. 7電子制作實(shí)例集錦 下載
  14. 未知  |  8113次下載  |  免費(fèi)
  15. 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德?tīng)栔?/a>
  16. 0.00 MB  |  6656次下載  |  免費(fèi)

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費(fèi)
  3. 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
  4. 78.1 MB  |  537798次下載  |  免費(fèi)
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費(fèi)
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費(fèi)
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費(fèi)
  11. 6電路仿真軟件multisim 10.0免費(fèi)下載
  12. 340992  |  191187次下載  |  免費(fèi)
  13. 7十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
  14. 158M  |  183279次下載  |  免費(fèi)
  15. 8proe5.0野火版下載(中文版免費(fèi)下載)
  16. 未知  |  138040次下載  |  免費(fèi)