INLET’s blog

浅学非才な工業大学生の悪あがき

モノクロ画像をAA化するC++プログラム

概要

大学の授業で使ったプログラムが画像ピクセルの値を読みだして色々するものだったので,01でテキストファイルに書き出せるよう改造しました.
VisualStudio2017で動くことを確認しています.

f:id:INLET:20181219134041j:plain
AA化のイメージ

使い方

二値化した画像をIrfanViewを用いて.pgm形式にします.
ソースファイルと同じ場所にcharacter.pgmを置いてプログラムを実行すると,同じ場所にcharacter.txtが作られます.
画像が存在しなかったり,二値化されていない画像を入れたりするとエラーを吐きます.

プログラム

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>


#define edmalloc(var,ty,n1,n2,msg) {\
if (NULL == ((var) = (ty**)malloc((sizeof(void *) * (n1))))) {	\
  fprintf(stderr,"%s: can't allocate memory.\n" ,msg); \
  exit(1); }					\
if (NULL == ((var)[0] = (ty*)malloc((n2 * n1)* (sizeof(ty))))) {\
  fprintf(stderr,"%s: can't allocate memory.\n" ,msg); \
  exit(1); }					       \
for (int _c1_=1; _c1_<(n1); _c1_++) { \
  (var)[_c1_] = (ty *)( ((char *)(var)[0]) + (_c1_ * sizeof(ty) * n2));	\
 }}

#define edfree(var) {	\
    free((var)[0]);free(var);}


int main(int argc, char **argv) {
	errno_t err;
	FILE *fp;
	char fname[256] = "character.pgm";
	err = fopen_s(&fp, fname, "r");
	if (err != 0) {
		fprintf(stderr, "%s was not opened\n", fname);
		return(-1);
	}

	char buf[1024];
	int ixsize, iysize;
	unsigned char **image;
	/* pgmのヘッダが4行であることを仮定 */
	fgets(buf, 1024, fp);
	fgets(buf, 1024, fp);
	fgets(buf, 1024, fp);
	sscanf_s(buf, "%d %d", &ixsize, &iysize);
	fgets(buf, 1024, fp);
	edmalloc(image, unsigned char, iysize, ixsize, "**image");
	fread(image[0], sizeof(unsigned char) * iysize * ixsize, 1, fp);
	fclose(fp);

	std::ofstream   File("character.txt");

	for (int y = 0; y < iysize; y++) {
		for (int x = 0; x < ixsize; x++) {
			if (image[y][x] == 0) {
				File << 1;
			}
			else if(image[y][x] == 255) {
				File << 0;
			}
			else {
				fprintf(stderr, "%s was not binarized\n", fname);
				return(-1);
			}
		}
		File << "\n";
	}

	edfree(image);
	
	return 1;
}

オシロにラスタ形式で絵を描く

f:id:INLET:20181212212845j:plain

アナログオシロの画面に描かれた「イ」の文字

 

製作動機

ニコニコ動画Youtubeオシロスコープに絵を描いてる人をよく見かけます.

www.youtube.com

www.youtube.com

一度はArduinoで作ってみたいと思っていたのですが,最近になってラジオペンチさんのブログ(電装を作るときに参考にさせてもらいました,後日それについても記事を書く予定です)を眺めていたところ,「アナログオシロでラスタ形式の描画をする」方法が書かれていました.

radiopench.blog96.fc2.com

ラスタ表示は中身が詰まったきれいな絵になりそうだと思い早速作ってみることに.

 

構成

プログラムは全く同じですが,部品は手元にあった物を使っています.

コンデンサと抵抗はRCローパスフィルタ用ですから,2つの積さえ一致していれば実質同じです.

ダイオード:BAT43→1N4148

コンデンサ:0.01uF(103)→0.1uF(104)

・抵抗:100kΩ→10kΩ

Arduino:Uno→Nano

 

結果

ゲイン調整で少し苦労しましたが,とりあえず上手くいきました.

Z軸(輝度)入力は付いていなかったので,ADDで上に飛ばして表示しています.

f:id:INLET:20181212151654j:plain

元旦2016

f:id:INLET:20181212212725j:plain

元旦2016_2

 

それから

アナログオシロと言えばブラウン管,ブラウン管と言えば「イ」の文字,ということでこの文字を40×40pxで描くことにしました.

(世界で初めてブラウン管に伝送・受像されたのは走査線40本の「イ」の文字)

f:id:INLET:20181212154637j:plain

ブラウン管の「イ」

まずモノクロ画像からデータを取り出します.

f:id:INLET:20181212190705p:plain

40px角の「イ」

 gimpTeraPadで画像ファイルをこねくり回すと,各ピクセルの0と1のデータが取り出せます.(本当はCでプログラム書いて自動化したかったんですが,Arduinoに慣れすぎたせいか変数の初期化などで詰まって諦めました)

 

[2018.12.19 追記]

C++を使って自動化できるようになりました.

inlet.hatenadiary.jp

 

f:id:INLET:20181212201041j:plain

0と1でAA化した「イ」

あとは参考元と同様にビットとしてunsigned intに直して16進数に変換して…と行きたいところですが,この型は32ビットが上限であり40ビットは格納できないので,泣く泣く40×40のboolean配列に格納しました.

なお下手にCharやStringで定義すると,RAM不足でコンパイラに怒られるので注意しましょう.(現状でもRAM不足ぎみだと文句を言われています)

この値をタイミングに合わせて読み込みdigitalWriteすれば,次のような画面になります.

f:id:INLET:20181212212845j:plain

アナログオシロの画面に描かれた「イ」の文字

 

気になったこと

よく見ると,描画している絵は上に行くほど上下方向に潰れているような気がします.

元々RCフィルタで作った三角波はステップ応答を切り出した形で近似しているので,そこが影響しているのではないかと考えています.

オシロ側が悪い可能性もありますが,ファンクションジェネレータで確かめるのはまだ先になりそうです.

また,せっかく解像度を上げたのに縁の部分にギザギザが生じています.プログラムの問題かノイズが乗っているのかは分かりませんが,いずれ直したいです.

 

今後の展望

・画像・映像を大量に表示することを考えるとプログラム内に01を記録することは現実的ではないので,SDカードなどから読み込むようにする.

・様々なオシロで使うことを考えるとゲインやタイミングの調整が非常に面倒なので,基板上で変えられるようにしたい.

オシロの画面を撮影するには長時間露光(1/15~1s)するので,手ぶれと映り込みを防止するため治具を作る.

 

電気自動車の大会

電気自動車の大会 #とは

手作りの飛行機なら鳥人間,ロボットならロボコンといったように,ものづくりのサークルには大会がつきものです.

自動車系の大会は次の3つに大別できます.

 

ソーラーカー

ソーラーパネルを車体に貼り,発電・蓄電しながら走行するもの.

オーストラリア縦断で東海大学が優勝したアレです.NHKにも出てましたね.

低燃費

ガソリンエンジンを動力とした車でいかに燃費をよくできるかを競うもの.

燃費3600km/Lという想像もつかない記録を出したチームもあります.

充電池

家庭用の二次電池を動力とした車で速度や周回数を競うもの.

上2つに比べれば簡単な競技らしいですが…

 

我々が毎年出場している「Ene-1GP Motegi」はだいたい↓のような感じです.

 

2018Ene-1GP MOTEGI | ツインリンクもてぎ

 

充電池40本で制限時間内にサーキットを何周できるかを競います.

高低差の激しい鈴鹿サーキットに比べて,もてぎ大会はハードルの低い大会と言えるでしょう.

まずは自己紹介

挨拶

はじめまして.INLETです.

サークル用に製作してきたプログラム・回路について手法や作り方を忘れないように,また後輩への引継ぎをスムーズに行えるようにとの思いからブログを開設しました.

自己満足もいくらか入っています.

おそらくサークル以外のものづくり系についても書くと思います.

 

中の人

名前:INLET

職業:工業大学生

住処:名古屋市のすみっこ

サークル:電気自動車

 

まだまだド素人のコピペエンジニアですが,よろしくお願いします.