Andoroidで画像処理入門

t-kado2010-11-20

来週にはIS03が発売されるということで(予約済み)
Androidの勉強を再開しました


大学時代は画像処理に明け暮れていたので
Androidでもそちらの方面から攻めていこうかなと

この2つページを参考にしました
https://sites.google.com/a/gclue.jp/android-docs/35-%E7%94%BB%E5%83%8F%E3%81%AE%E6%8F%8F%E7%94%BB
http://labs.techfirm.co.jp/android/cho/279

package com.tkada.bitmaptest;

import android.app.Activity;
import android.os.Bundle;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.View;

/**
 *  起動クラス
 */
public class Bitmap_test extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(new MainView( getApplication() ));
    }
}
/**
 * 描画用のクラス
 */
class MainView extends View {
    private Paint myPaint = new Paint();
    private Bitmap myBitmap;
    /**
     * コンストラクタ
     * @param c
     */
    public MainView(Context c) {
        super(c);

        /* Resourceインスタンスの生成 */
        Resources res = this.getContext().getResources();
        /* 画像の読み込み(res/drawable/testj.jpg) */
        myBitmap = BitmapFactory.decodeResource(res, R.drawable.testj);
    }

    /**
     * 描画処理
     */
    protected void onDraw(Canvas canvas) {
        /* 背景色を設定 */
        canvas.drawColor(Color.BLUE);
    //画像の縦横の大きさを取得
        int Width=myBitmap.getWidth();
        int Height=myBitmap.getHeight();
    //出力用画像領域確保
        Bitmap output=Bitmap.createBitmap(Width, Height, Bitmap.Config.ARGB_8888);
    //画像処理用配列
        int[] pixels = new int[Width*Height];
    //pixelsの配列にmyBitmapのデータを格納する
        myBitmap.getPixels(pixels, 0, Width, 0, 0, Width, Height);
        for(int x=0;x<Width;x++){
        	 for(int y=0;y<Height;y++){
         //1画素ずつ取得
        		int pixel=pixels[x+y*Width];
         //RGB各色に分離
        		int r=Color.red(pixel);
        		int g=Color.green(pixel);
        		int b=Color.blue(pixel);
         //今回の画像処理はカラー画像をグレースケールに変換する
        		int gray=(int)(r*0.3+g*0.59+b*0.11); //輝度値=R×0.30+G×0.59+B×0.11
         //データを戻す
        		pixels[x+y*Width]=Color.argb(Color.alpha(pixel),gray,gray,gray);
        	}
        }
    //出力用の領域にセットする
        output.setPixels(pixels, 0, Width, 0, 0, Width, Height);
    /* Bitmapイメージの描画 */        
        canvas.drawBitmap(output, 0,0, myPaint);
    }
}


画像処理できるフレームワークが何となく分かったので
ネイティブ化、カメラとの連携辺りをやっていつかはマーケットに公開したいな

MCPCモバイルシステム技術検定2級を受けてきた

なんだか会社で資格を取らなきゃならない流れだったので
適当にMCPCにエントリー
会員企業だったので若干お安く受験できました


JSTQBと違ってこちらは問題集がない!
WEB上にも無いため、教科書を読み込むしか勉強法がない
一応セミナーとかあるらしいけど、そこまでお金をかけて取る資格なのかというとだいぶ疑問


モバイルシステム技術テキスト第3版―MCPCモバイルシステム技術検定試験2級対応モバイルシステム技術テキスト第3版―
MCPCモバイルシステム技術検定試験2級対応


2009/07発売
監修:モバイルコンピューティング推進コンソーシアム
リックテレコム
価格:¥3,780
この教科書だけを頼りに勉強しました。


内容としては携帯電話の歴史や通信方式の話
TCP/IPの話、周辺機器の話など広く浅くです
話の内容としては大学の学部レベルだと思うので
学生でも充分に理解できます
あと、常識レベルの問題も結構ある
WEBブラウザとHTMLを用いてWEBブラウジングする
・アナログデータをデジタルデータに変換して処理を行い
 出力側ではその逆をする
とか


覚えているだけ、2010年11月13日の試験で出題された問題
過去問としてどうぞ
・P47の図 VPNの話
・P79 セクタ化の話
・P87 毎秒600回の受信状態測定
・P114の図 TCP/IP
・P118 CSMA/CD
・P127 IPv4のヘッダ構成
・P138 DNSサーバの働き
・P147 SIP
・P168 カメラ (イメージセンサ、レンズ、A/D変換器、D/A変換器 画質の良さに影響しないのは?)
・P189 IEEE 802.11a/b/gの通信速度
・P207 ネットワークのトポロジ
・P209 バーコードの規格の種類
・P220 QRコードの数字、英語、日本語の最大文字数を答えよ
・P233 BREWの開発環境
JavaアプリとBREWアプリの違い
・P275の図 WAP2.0
・P300 ストリーミング
・P305 転送不可コンテンツ
・P307 転送許可コンテンツ
・P311 18ビットカラーは何色か
・P352 ビジネスモデル
・P359 プレゼンスモデル
・P361 営業支援システム
・P373 Wakeup機能

問題数100分に対して試験時間は100分ありますが余裕で終わります。
分かった問題は7割ほど
さて合格ラインはどれくらいなんでしょ

12/14追記
合格しました!

2ちゃんねるでURLを含むレスを抽出

2chを見ていて、雑談が多い場所だと新しい情報が貼られたときに見逃してしまうことが多い
なのでURLが入っているレスだけ抽出できればいいなぁと
そんなツールをPHPで作ってみました

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>2ちゃんねるURL抽出</title></head>
<body>
<form action="index.php" method="post">
 スレッドURL: <input type="text" size="80" name="URL"/>
 <input type="submit" name="submit" value="GO!"/>
</form><hr>

<?php
//URLが入力されたら表示開始
if($_POST['submit']){
	$URL=$_POST['URL'];
	
	
	//URLをパースする
	$URL_arr=parse_url($URL);
	//板名取得のためにパースする
	$board=split("/",$URL_arr['path']);

	//read.cgiの場所から板名を取得
	$i=0;
	foreach($board as $read){
		//echo $read."<br>";
		if($read==="read.cgi"){
			$board_pos=$i;
		}
		$i++;
	}
	//2ch以外のBBSに対応するため
	if($board_pos!=2){
		for($j=1;$j<($board_pos-1);$j++){
			$URL_arr['host'].="/".$board[$j];
		}
	}
	//$board_posが板名の場所
	$board_pos++;
	//.datファイルの位置を捜す
	$dat_URL="http://".$URL_arr['host']."/".$board[$board_pos]."/dat/".$board[$board_pos+1].".dat";
	
	//ファイルオープン
	$fp = fopen($dat_URL, "r");
	//エラー処理
	if($fp===FALSE){
			echo $URL."<br>";
			echo $dat_URL."<br>";
		echo "そんなスレありません・・・<br>";
	}
	
	//レス番カウンタ
	$res_count=0;
	//datファイル解析
	while ($line = fgets($fp)) {
		$res_count++;
		//datファイルを"<>"でパースする
		$output=split("<>",$line);
		
		//>>1のときだけスレッド名取得
		if($res_count===1){
			echo "<b>".$output[4]."</b><br>";
			echo "<a href=\"".$URL."\" target=\"_blank\">".$URL."</a><br><hr>";
		}
		//「://」で引っかかるレスを抽出
		if(preg_match("/:\/\//",$output[3])){
			//レス番指定を修正
			$output[3]=str_replace("../test","http://".$URL_arr['host']."/test",$output[3]);
	    	         //URLを抽出してリンクを張る
			$word=ext_url($output[3]);
			//表示
			echo "<b>".$res_count."</b> <font size=\"2\" color=\"forestgreen\"><b>".$output[0]."</b></font>";
			echo " <font size=\"2\" color=\"808080\">".$output[2]."</font><br>".$word."<br><hr>";
      	          }
	} //while END
	fclose($fp);
	
}

//参考http://www.tokujyuu-japan.com/phpBlaz/lesson/regex/php_regex_operation.html
function ext_url($str){
	// ttp://やtp://をhttp://に直す
	$str=preg_replace("/h?t?tp:\/\//i"," http://",$str);
	$pattern='/ (https?(:\/\/[-_.!~*\'()a-z0-9;\/?:\@&=+\$,%#]+)) /i';
	$replacement='<a href="\1" target="_blank">\1</a>';
	// http://にリンクを張る
	$output=preg_replace($pattern,$replacement,$str);
	return $output;
}

?>

<p>Copyright 2010 <a href="http://d.hatena.ne.jp/t-kado/" target="_blank">t-kado</a> All rights reserved.</p>
</body>
</html>

スレのURLを入れれば、URLを含むレスを抽出してくれます。
2ch以外にもlivebays.net,パー速、モータースポーツ実況板、ニコニコ動画質問&交流掲示板等の
外部の2ch掲示板に対応しています。

最近はActionScript,PHP,JavaScript,VBAC言語に全然触ってないなぁ
Androidのネイティブコードには興味があるので、少しずつ触っていこう

JSTQB合格した

ウチの会社では1年生の必須取得資格としてJSTQB Foundation Levelが挙げられています
6月から勉強を始めて8月の試験で一発合格できました


そもそもJSTQB資格って?
ソフトウェアテスト技術者の資格
 人に説明するときは「テストのテスト」「試験の試験」とかよく分からないことを言っていましたw


勉強方法を以下に残しておきます


1.ひたすら教科書を読む

ソフトウェアテスト教科書 JSTQB Foundationソフトウェアテスト教科書 JSTQB Foundation

2009/04/16発売
大西 建児, 勝亦 匡秀, 加藤 大受,
佐々木 方規, 鈴木 三紀夫, 町田 欣史,
湯本 剛, 吉澤 智美
翔泳社
価格:¥3,990

この教科書には節末毎に問題が載っているのでそれを一通り解きます
そして、本の最後には模擬試験が載っているのでそれを満点が取れるまで何度も繰り返しました


2.オススメ問題集

演習で学ぶ ソフトウェアテスト特訓150問 JSTQBテスト技術者認定Foundation対応演習で学ぶ ソフトウェアテスト特訓150問 JSTQBテスト技術者認定Foundation対応

2006/07/28発売
著:正木 威寛
技術評論社
価格:¥2,079


教科書だけでは演習量が足りないのでこちらも購入し。
なんども演習を繰り返しました
こちらの参考書は解説も載っているのですが
よく分からない場合は、教科書に戻って理解を深めました


3.WEB問題を何度も解く
参考書の著者が無料でWEBに問題を公開しています
http://naha.cool.ne.jp/overdrive/JtcbExam/index.htm
実際の試験と同じ40問ですので、解くスピードの参考になると思います。
こちらも満点が取れるまで何度も繰り返しました。


4.本番
ここまで何回も問題を解いてきた人でも実際の試験はかなりびっくりします
教科書に書いてあるような問題がほぼありません
ですが、問われていることは結局教科書に載っていることなので
しっかりと知識が身についていれば解くことが出来ます。

問題量は多くないので、私は20分ほどで回答することが出来ました。
合否判定基準は6割とも8割とも言われています


合否は試験から約2ヶ月で日科技連から発表されました
JSTQBのページの方に名前が載るのはもう少し後になるようです

GDBとLCOVで自動テスト

ちょっと前に扱ったLCOVを使いつつ、代表的なデバッグツールであるGDBを組み合わせて効率的にテストを行う
LCOVはちょっと前に説明したので、今回はGDBを重点的に
前回の記事:gcovとlcov
GDBはここが非常に参考になりました
http://www.fireproject.jp/feature/gdb/advanced/auto-test.html


今回のテスト対象

#include<stdio.h>

int func1(int x)
{
  int result=-1;

  switch(x){
      case 0:{
        result=1;
        break;
      }
      case 1:{
        result=3;
        break;
      }
      case 2:{
        result=5;
        break;
      }
      default:{
        result=-1;
        break;
      }
  }
  return result;
}

int main()
{
  int res;

  res=func1(1);
  printf("%d\n",res);

  return 0;
}


今回はGDBとLCOV両方使うのでコンパイルのコマンドはこんな感じ

gcc -g -coverage -o hoge hoge.c

GDBで自動テストをする場合は、コマンドラインを並べたファイルを用意しておいて
-xオプションをつけてやればいい
今回用意したスクリプトファイル(test-pattern1)

set pagination 0
#ブレイクポイントの設定
break func1
#プログラムを走らせる
run
#ブレイクしたら値を書き換える(この場合、x=0に書き換える)
print x=0
#最後まで実行
continue
#頭文字だけでもコマンドは認識される
r
p x=1
c
r
p x=2
c
r
p x=3
c
quit

先頭の「set pagination 0」を付けないと「Type to continue, or q to quit」が出てきて
スクリプトが最後まで走らないことがある
参考:http://sourceware.org/gdb/wiki/FAQ

スクリプトを書いたら以下のコマンドを実行

gdb hoge -q -x test-pattern1

-qはロゴが出てこなくなるので、ログをとるときには便利


実行が終わったら、あとはLCOVを使うときと同じ

lcov -c -d . -o hoge.info
genhtml -o . hoge.info

これでHTMLにカバレッジ結果が出力される


GDBを使うことで手入力よりはるかに簡単にカバレッジ率100%を達成することができる
スクリプトを発展させて、返り値チェックを行うことも可能なので
2つのツールだけでソースコードを汚さず単体テストができるようになる
CUnitとかと組み合わせると更に効率的かも

GDBを使った実践的デバッグ手法

GDBを使った実践的デバッグ手法
¥2,310

M001復活への道 USB接続に挑戦

先日壊れたM001を復活させるために
分解してUSBを取り出すことに挑戦しました


用意したモノ

  • USB延長ケーブル←かなり短いモノで良い
  • 半田ごて
  • ドライバー


まずは、M001の下部にあるネジ2本を外します
そして、少し無理矢理に開けます
このとき、PCへの接続コネクタが引っかかってなかなか開かなかったが
ドライバーで無理矢理こじ開けました

この時点で、何本かのツメは死亡
もう戻れない



USBはこちらの記事にもあるように、標準とは違う色遣い
http://blogs.yahoo.co.jp/tal0032_jp/25670732.html
しかも、この記事とも色遣いが違うので、きっとランダムなんでしょうw
基盤の方を頼りに、上から、(赤)、(白)、(緑)、(黒)となるように接続しました
無線LANの方も同様に接続



とりあえず、マウスとキーボードを繋いでみるとこんな感じ
wifiがOFFになってしまうと何も効かなくなるので
http://m001etc.blogspot.com/2010/06/scriptcmdwifipowerdown.html
ここのスクリプトを使ってファームウェアを再インストール
そして、マウスを繋いだまま立ち上げると、マウスポインタ登場!
ちゃんと動きました
キーボードもちゃんと反応しているし、一応Android PCとして復活できたみたい

現在残っている問題点は

  • wifiがプチプチ切れる
  • 見た目が良くない

wifiがプチプチ切れてしまうのはハードの問題なのか、バスパワーが足りないのかよく分からないのでさらなる調査が必要
そして、ドリルとヤスリを使ってもう少し見た目をよくしなきゃな

gcovとlcov

コードカバレッジを測るためのツールを紹介
gcovは無料だがいかんせん見づらい
そこで結果をグラフィカルに表示してくれるlcovというものがある

まずインストール

http://ltp.sourceforge.net/coverage/lcov.php
tar xzvf lcov-1.8.tar.gz
cd lcov-1.8
sudo make install

(http://d.hatena.ne.jp/mah11/20080811を参考にしました)


次にカバレッジを測りたいプログラムを用意する。
今回はhoge.cとする
そして、コマンドを色々打つのが面倒なのでスクリプトを用意
こちらはcoverage.shとする

#!/bin/sh
gcc -coverage -o $1 $1.c
./$1
lcov -c -d . -o $1.info
genhtml -o . $1.info

実行できるようにパーミッションを変更

chmod 755 coverage.sh

そして実行

./coverage.sh hoge

これで生成されたindex.htmlをブラウザで見ると
C0、C1あたりは見ることができる。
コードのどの部分を通過しているかもチェックができる


今回はUbuntu 8.04上で確認したけど
Cygwinとかでもできるはず