しょぼちむをExcel方眼紙で表現してみる
これはしょぼちむアドベントカレンダー23日目の記事です。
しょぼちむ Advent Calendar 2014 - Adventar
昨日は、ばふぁさんの「しょぼちむ!スクラムチームの外側の話をちょっと書いてみたよ!」でした!
今日は特にこれといって決めてないので、しょぼちむをExcel方眼紙にしようと思います。
以下の手順で行います。
以上です。
画像のリサイズおよび2値化には OpenCVを使います。
OpenCVのインストール(Mac)はこちらを参考にしました。
Mac - OS X に OpenCV を Homebrew で入れて python で動画入出力をする - Qiita
では早速ソースコードです。
まず vim を起動します。
$ vim syobochim.py
import cv2 img = cv2.imread('syobochim.jpg', cv2.IMREAD_GRAYSCALE) # 2. 画像を適当に小さくする(リサイズ) thumb = cv2.resize(img,(160, 128)) # 3. 画像を2値化する thresh = 120 img_bin = cv2.threshold(thumb, thresh, 255, cv2.THRESH_BINARY)[1] # 4. 画像を 0 と 1 でマッピングして文字列を取り出す for y in range(0, 127): for x in range(0, 159): px = img_bin[y, x] if px != 0: print '1', else: print '0', print ''
そしてこれを
( ^ω^)
⊃ syobochim.py ⊂
こうして…
( ^ω^)
≡⊃⊂≡
$ python syobochim.py > syobochim.txt
こうじゃ
( ^ω^)
⊃ Excel方眼紙 ⊂
本当はここから Arduinoにシリアル通信で画像を送り、LCDディスプレイで表示しようと思ったんだけど、送信データ量が多くて送れませんでした。
バイナリデータで送ろうとしたけどpySerialでは文字列でしか送れないことと、Arduinoは128byteのread bufferしかないのが原因っぽい。多分頑張ればできるはず。
とりあえず時間があったら後でやろうかなと思うので上記ソースをちょっと修正したPythonのソースコードを備忘録で残しておく。
※動いたので追記
Arduinoのバッファを消費するタイミングをうまくスリープで調整すればできた。
けどスリープのタイミングがなかなか難しいし遅い。
バッファサイズをみてやればいいような気がするけどこのへんの知識ないので難しい・・。
# convert image to 160 x 128 pixel resolution. import array import cv2 import serial import time # resize img = cv2.imread('syobochim.jpg', cv2.IMREAD_GRAYSCALE) thumb = cv2.resize(img,(160, 128)) # binary thresh = 120 img_bin = cv2.threshold(thumb, thresh, 255, cv2.THRESH_BINARY)[1] # serial ser = serial.Serial() ser.port = '/dev/tty.usbmodemfa131' ser.baudrate = 9600 ser.open() time.sleep(5) for y in range(0, 128): data = "" for x in range(0, 160): px = img_bin[y, x] if px != 0: data += "1" else: data += "0" ret = ser.write(data) time.sleep(0.5) time.sleep(1) ser.close()
#include <SPI.h> #include <SD.h> #include <TFT.h> // Arduino LCD library // pin definition for the Uno #define sd_cs 4 #define lcd_cs 10 #define dc 9 #define rst 8 TFT tft = TFT(lcd_cs, dc, rst); int x,y = 0; int rcv = 0; void setup() { tft.begin(); tft.background(0, 0, 0); Serial.begin(9600); } void loop() { while((rcv = Serial.available()) > 0){ for(int i=0; i<rcv; i++) { int val = Serial.read(); if (val == 48) { tft.drawPixel(x, y, 0x0000); x++; } else if(val == 49){ tft.drawPixel(x, y, 0xFFFF); // 0xFFFF x++; } if(x>=160) { x = 0; y++; } } } }