HOME | Raspberry Pi | ビジネス書籍紹介 | 2026-01-04 (Sun) Today's Access : 149 Total : 1260847. Since 10 Sep. 2019

画像処理・基本変換
2021.05.16


YouTube でも紹介しています。画像をクリックすると再生できます。

Interface 2020年11月号特集「ESP32で画像処理プログラム100」では画像処理の仕組みをソースコードとともに解説しています。 画像処理ライブラリを使用しないで、pixel単位での変換処理を行っているので、画像処理の本質を理解するのには最適です。 pythonでは扱えないポインタを使ったプログラミングになるので、C/C++言語の知識が必要になりまが、 短時間に幅広く学習されたい方にはよい教材だと思います。 画像処理用ソースコードは少しの変更で別環境への転用・応用も可能です。

Interface 2020年11月号
特集「ESP32で画像処理プログラム100」
第1章 画像処理プログラムを試す準備
第2章 明るさ&色
第3章 形&大きさ変換
第4章 フィルタ
第5章 拡大/回転/移動/膨張
第6章 画像分析
第7章 特殊加工


まずは、この特集で紹介しているプログラムの実行環境を整えます。
特集では、M5StackとESP32-DevKitCでの実装方法を紹介しています。
ここでは、ESP32-DevKitC (ESP32 General Development Kit)を使用します。

■実行環境

ノートパソコンから、TeraTermによりラズベリーパイにSSH接続して操作します。

■Sparkfun ESP32 Thing Plus

Espressif Systems社のESP32-WROOM-32Dモジュールを搭載し、強力なWi-FiとBluetooth MCUを備えた開発プラットフォームThing Plusの新しいバージョンです。Featherボード互換で、Qwiicシステムの利用によりハンダ付けやシールドなしで接続が可能です。
静電容量式タッチセンサ、ホール(磁気)センサ、SDカードインターフェース、イーサネット、高速SPI、UART、I2S、 I2Cなど、豊富な周辺機器を統合し、16 MBのフラッシュメモリ、520 KBの内蔵SRAM、802.11 b/g/n Wi-Fi、デュアルモードBluetooth機能、およびLiPoバッテリー用JST型コネクタを特徴としています。

プログラムのビルドには、Platformioを使用します。
Arduino開発環境構築 PlatformIO

まずは、ラズベリーパイに繋いで、接続デバイスを確認します
$ pio device list
/dev/ttyUSB0
------------
Hardware ID: USB VID:PID=21F3:EC73 SER=86B13DA3 LOCATION=1-1.3
Description: CP2104 USB to UART Bridge Controller

/dev/ttyAMA0
------------
Hardware ID: 4e836500.serial
Description: ttyAMA0
利用できるボードを確認します
$ pio boards "sparkfun"
.....
Platform: espressif32
==========================================================================
ID               MCU    Frequency  Flash  RAM    Name
---------------  -----  ---------  -----  -----  -------------------------
esp32thing       ESP32  240MHz     4MB    320KB  SparkFun ESP32 Thing
esp32thing_plus  ESP32  240MHz     16MB   320KB  SparkFun ESP32 Thing Plus
.....
プロジェクトを作成します
$ mkdir ~/Interface521
$ cd ~/Interface521
$ pio init -b esp32thing_plus

■Adafruit 2.2" 18-bit color TFT LCD display with microSD card breakout
ILI9340搭載の解像度240x320、TFT液晶モジュールを使用しました。
・2.2" diagonal true TFT LCD display has 320x240 colour pixels
・The TFT driver (ILI9340) can display full 18-bit color (262,144 shades!)
・ultra-low-dropout 3.3V regulator and a 3/5V level shifter so you can use it with 3.3V or 5V power and logic.
・comes with a microSD card holder so you can easily load full color bitmaps from a FAT16/FAT32 formatted microSD card (card not included)


SparkFun ESP32 - Adafruit TFT display
GND  - GND
3V3  - VIN
GPIO[26] - DC:SPI data / command selection
3V3  - RESET
GPIO[16] - SD CS:Chipselect
GPIO[17] - LCD CS:Chipselect
MOSI[18] - SDI(MOSI):SPI data line
MISO[19] - SDO(MISO):SPI data line
SCK[5]  - SCK:SPI clock line

描画テスト
■adafruit/Adafruit_ILI9341 - graphictest.ino
Ref.graphictest.ino

$ vi plaformio.ini
[env:esp32thing_plus]
platform = espressif32
board = esp32thing_plus
framework = arduino
lib_deps =
 adafruit/Adafruit ILI9341
 adafruit/Adafruit ST7735 and ST7789 Library
 adafruit/Adafruit GFX Library
 adafruit/Adafruit BusIO

$ vi src/graphictest.ino
#include "SPI.h"
#include "Wire.h" ← 追加
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"

//#define TFT_DC 9
//#define TFT_CS 10
#define TFT_DC 26
#define TFT_CS 17

$ pio run -t upload



画像基本変換
CQ出版社 Interface のサイトからソースプログラムをダウンロードします。
https://www.cqpub.co.jp/interface/download/2020/11/IF2011T.zip

IF2011T.zip を解凍→[IF2011T]→[ESP32_LCD]→[ImageProcessing]
この中のファイルすべてをプロジェクトのsrcディレクトリ(~/Interface521/src)に配置します。

DCとCSのGPIO番号を配線に合わせて変更します。
$ vi src/LcdWrapper.cpp
//#define TFT_DC 5
//#define TFT_CS 16
#define TFT_DC 26
#define TFT_CS 17

ino ファイルにヘッダーファイルを追記します。
$ vi ImageProcessing.ino
#include "LcdWrapper.h"
#include "ModeManage.h"
#include <FS.h>
#include <SPIFFS.h>
#include <Wire.h> ← 追加

■画像ファイルのアップロード
PlatformIOでESP32のSPIFFS(SPI Flash File System)にサンプル画像ファイルを書き込みます。
1.プロジェクト直下に data という名前で新しいフォルダーを作成します
$ cd ~/Interface521
$ mkdir data
2.ダウンロードしたソースコードを解凍すると、オリジナル画像というディレクトリ内に、サンプル画像が格納されています。 これらのファイルをdataディレクトリー内にコピーします。
3.ファイルアップロード用オプションを付加して、コマンドを実行します
$ pio run --target uploadfs
削除する場合は
$ pio run --target erase

自分の好みで画像を変更する場合は、画像ファイル名を、src/Original.h 記載のファイル名に変更するか、 SPIフラッシュ・メモリーに書き込む画像ファイル名に合わせて、ヘッダーファイルを修正します。
$ vi src/Original.h
class Original {
public:
  const char* fname = "/mandrill.jpg";
  const char* noise_fname = "/mandrill_noise.jpg";
  const char* small_fname = "/mandrill_small.jpg";
  const char* lena_fname = "/lena.jpg";
  // const char* interface_fname = "/interface_noise_white.jpg";
  const char* interface_fname = "/interface_noise_black.jpg";
オリジナル画像ディレクトリーにあるマンドリルというサルの画像では向学心に火が付かないと思いますので、サンプル画像に三乳亭しん太さんのカバーイラストを使わせていただきました。
本当はやってはいけない刑罰マニュアル
ギロチン、絞首刑、電気椅子、ガス殺、断手。あまたの刑罰を既に絶滅したもの、未だに行われているもの、現実には存在しなかったものに分類し、刑罰が発明・採用された当時の法典、社会情勢、宗教的な意義、登場する作品を解説した刑罰本がついに登場。この本を読んでも、絶対に真似をしないでください……。
三乳亭 しん太 (イラスト)


$ pio run -t upload



10秒ごとにオリジナル画像の画像変換処理が切り替わって表示されます。
その中のいくつかの変換処理を紹介します。

Chchange
チャネル入れ替え
画素のRGBをBGRに入れ替えています。


ReverseColor
色の反転
画素のRGB値それぞれを、最大値(255)から引いて反転させています。
R = 255 - R
G = 255 - G
B = 255 - B


GrayScale
グレー・スケール化
CIE(国際照明委員会) XYZ を用いた、輝度変換です。
RGBとは別の色空間XYZを用います。この空間では、XとZが色味、Yが輝度になります。
Y = 0.2126 * R + 0.7152 * G + 0.0722 * B


ThreshBinary
2値化
しきい値(Thresh)を決めて、画素の輝度がしきい値より大きければ白、小さければ黒に変換します。


AvePooling
平均プーリング化
グリッド・サイズを、8x8 にして、各領域内の平均値で領域を埋めています。


■応用

今回の説明の中で用いている変換処理画像は、Interface掲載プログラムを書き換え、変換処理画像をTGA画像ファイルとしてSDカードに書き出したものを、JPEG画像に変換して使用しています。

JPEG - MCU(Minimum Coded Unit)
JPEGは、画像をデータにする時に一片を8pixelの倍数の小さい画像に分割し、 個々の画像をデータに変換します。この小さい画像をMCU(Minimum Coded Unit)と呼びます。
Ref.JPEGファイルの理解を深める

特集記事では、1 MCUごとに画像情報を読み込み、その都度、画像変換をおこなっているものが多く、SRAMの少ないESP32でも処理が可能です。
例えば、掲載プログラムのOriginal.cpp に下記の太字部分を追記して、ビルドします。

$ vi src/Original.cpp
void Original::display(const char *fname){
  uint8_t *pImg;
  int x,y;

  Lcd.clearDisplay(BLACK);

  JpegDec.decode(fname);

  // Image Information
  Serial.print("JpegDec.width :");
  Serial.println(JpegDec.width);
  Serial.print("JpegDec.height :");
  Serial.println(JpegDec.height);
  Serial.print("JpegDec.MCUWidth :");
  Serial.println(JpegDec.MCUWidth);
  Serial.print("JpegDec.MCUHeight :");
  Serial.println(JpegDec.MCUHeight);
  Serial.print("JpegDec.MCUSPerRow :");
  Serial.println(JpegDec.MCUSPerRow);
  Serial.print("JpegDec.MCUSPerCol :");
  Serial.println(JpegDec.MCUSPerCol);
  Serial.println("");

  ......
platformio のデバイスモニターを起動、ESP32の[RESET]ボタンを押して、ビルドしたプログラムを再起動すると、JPEG画像の情報が表示されます。

$ pio device monitor -p /dev/ttyUSB0 -b 115200
JpegDec.width :320
JpegDec.height :240
JpegDec.MCUWidth :16
JpegDec.MCUHeight :16
JpegDec.MCUSPerRow :20
JpegDec.MCUSPerCol :15

width と height が画像サイズです。
MCUWidth と MCUHeight がMCUのブロックサイズです。
MCUSPerRow が行に含まれるMCUのブロック数、MCUSPerCol が列に含まれるMCUのブロック数になります。

MCUのブロックサイズごとに画像処理を行い、ディスプレイに表示するのは容易なことですが、 実用面で考えると、SDカードに保存したデータを読み取り、画像処理をして、SDカードに処理後の画像を書き出せれば利便性が向上します。

実用に際しては2つの点が課題となります。
1.画像情報をRGB情報を保持したまま、すべて読み込んでから処理しようとするとESP32のSRAMが足りない。
2.SDカード使用の際には、複数個のファイルを同時に開けない。

対策としては、

1.画像横サイズ分のMCUブロックに対して画像処理を行い、TGA形式の画像配列(BGRBGRBGR....)に並び替えて、メモリ上に格納します。
 320x240のJPEG画像を例に取ると、
 1MCU は 16x16 pixel (MCUWidth,MCUHeight)
 横方向に、20ブロック(MCUSPerRow)
 縦方向に15ブロック(MCUSPerCol)
 となっています。
 横方向1列分のブロックを格納するのに必要なメモリーは
  16 x 16 x 20 x 3 → 15360バイト
 SRAM 520KB の Sparkfun ESP32 Thing Plus では確保できました。

2.横1列分の処理が終わるたびに、SPI FLASHメモリー上のファイルに書き出します。

3.すべての処理が完了した時点で、SPI FLASH 上のファイルを、SDカードに書き出します。

ただし、一度に画像の全領域を処理対象にする変換に関しては、SRAMが不足して、画像ファイルを生成できない可能性があります。 ESP32-WROVER でしたら、PSRAMを使うことで回避できるかもしれません。

■参考文献
ESP32でSPIFFSにファイルを読み書きする方法
PlatformIOでESP32のSPIFFSにファイルを書き込むコマンド
adafruit/SD - GitHub
Hiletgoの2.8インチ TFT液晶でBMP画像を表示してみた
Python/OpenCVで任意色を透過させたpng画像に変換
Adafruit_ILI9340/examples/spitftbitmap/spitftbitmap.ino
Raspberry Pi(ラズベリー パイ)は、ARMプロセッサを搭載したシングルボードコンピュータ。イギリスのラズベリーパイ財団によって開発されている。
2020.05.28 画像処理 第1回トイカメラ
2020.06.09 画像処理 第2回カメラモジュール制御
2020.06.28 画像処理 第3回リアルタイムクロック
2020.07.08 画像処理 第4回電源回路
2020.10.27 画像処理 第5回自作デジカメ初号機完成
2020.11.10 画像処理 第6回ドーナツデジカメ
2021.05.16 画像処理・基本変換
2021.07.10 M5Stackアプリの移植
2022.04.04 減色処理 雑談
2022.04.18 減色処理 均等量子化法とK平均法
2022.05.04 減色処理 グレースケール・二値化
2022.05.18 減色処理 二値化画像印刷
2022.08.12 京セラ feelH” Treva カメラ
2022.10.15 デジカメ弐号機 1.仕様変更
2022.10.21 デジカメ弐号機 2.SDカードとRTC
2022.11.04 デジカメ弐号機 3.SPI DISPLAY
2022.11.18 デジカメ弐号機 4.ストリーミング
2022.12.02 デジカメ弐号機 5.機能統合
2022.12.17 デジカメ弐号機 6.完成
2023.05.15 アナログ風ゲージ
2023.06.01 ADS1115デジタル電圧計
2023.10.01 立体視(ステレオグラム)
2023.10.16 漢字フォントの表示と拡張
2024.04.08 自作デジカメ参号機・雑談
2024.08.24 シリアルカメラ
2025.07.23 C3.jsによるグラフ描画
2025.09.09 東芝デジタルカメラユニット DMR-C1
2025.10.10 AQM1248A小型液晶ボード
2025.10.11 Monochrome OLED
2025.12.31 キャラクターディスプレイで遊ぶ

たいていのことは100日あれば、うまくいく。長田英知著
「時間がなくて、なかなか自分のやりたいことができない」 「一念発起して何かを始めても、いつも三日坊主で終わってしまう」 「色んなことを先延ばしにしたまま、時間だけが過ぎていく」 そこで本書では、そんな著者が独自に開発した、 まったく新しい目標達成メソッド「100日デザイン」について、 その知識と技術を、余すところなくご紹介します。

まんがで納得ナポレオン・ヒル 思考は現実化する
OLとして雑務をこなす日々に飽き足らず、科学者だった父が残した薬品を商品化すべく、起業を決意した内山麻由(27)。彼女はセミナーで知り合った謎の女性からサポートを得ながら、彼女と二人三脚でナポレオン・ヒルの成功哲学を実践し、さまざまな問題を乗り越えていく。 ヒル博士の<ゴールデンルール>に従い、仕事に、恋に全力疾走する彼女の、成功への物語。

今日は人生最悪で最高の日 1秒で世界を変えるたったひとつの方法 ひすいこたろう著
偉人の伝記を読むと、最悪な日は、不幸な日ではなく、新しい自分が始まる日であることがわかります。最悪な出来事は、自分の人生が、想像を超えて面白くなる兆しなのです。偉人伝を読むことで、このときの不幸があったおかげで、未来にこういう幸せがくるのかと、人生を俯瞰する視線が立ち上がるのです。

ご飯は私を裏切らない heisoku著
辛い現実から目を背けて食べるご飯は、いつも美味しく幸せを届けてくれる。 29歳、中卒、恋人いない歴イコール年齢。バイト以外の職歴もなく、短期バイトを転々とする日々。ぐるぐると思索に耽るけど、ご飯を食べると幸せになれる。奇才の新鋭・heisokuが贈るリアル労働グルメ物語!

【最新版Gemini 3に対応!】できるGemini (できるシリーズ)
Geminiを「最強の知的生産パートナー」として使いこなすための、実践的なノウハウを凝縮した一冊です。 基本的な操作方法から、具体的なビジネスシーンでの活用、日々の業務を自動化するGoogle Workspaceとの連携、さらには自分だけのオリジナルAIを作成する方法まで余すところなく解説します。

Rustプログラミング完全ガイド 他言語との比較で違いが分かる!
Rustの各手法や考え方を幅広く解説! 500以上のサンプルを掲載。実行結果も確認。 全24章の包括的なチュートリアル。

ポチらせる文章術
販売サイト・ネット広告・メルマガ・ブログ・ホームページ・SNS… 全WEB媒体で効果バツグン! カリスマコピーライターが教える「見てもらう」「買ってもらう」「共感してもらう」すべてに効くネット文章術

小型で便利な Type-C アダプター USB C オス - USB3.1 オスアダプター
Type-C端子のマイコンボードをこのアダプタを介して直接Raspberry Piに挿すことができます。ケーブルなしで便利なツールです。

Divoom Ditoo Pro ワイヤレススピーカー
15W高音質重低音/青軸キーボード/Bluetooth5.3/ピクセルアート 専用アプリ/USB接続/microSDカード

電源供給USBケーブル スリム 【5本セット】
USB電源ケーブル 5V DC電源供給ケーブル スリム 【5本セット】 電源供給 バッテリー 修理 自作 DIY 電子工作 (100cm)

Copyright © 2011-2027 Sarako Tsukiyono All rights reserved®.