Hatena::ブログ(Diary)

Kazzzの日記 このページをアンテナに追加 RSSフィード

2013-03-24

[][]面倒くさがりはプログラマの基本適性

同僚の外国人プログラマ観察記録 - rinu's blog
外国人の彼がどういう性格だったのかは分からないけれど、きっといい人だったんだと思う。
こういう面倒くさがりやさんがチームにいると有難いんだよね。

日本人は与えられた環境で我慢強く作業しすぎなんだよきっと。

プログラミングにとって、面倒くさがりは正義

2013-03-20

[][]Keep The Cashキャンペーン

Keep The CashPublish apps.Get up to $2000*/ Windows Dev Center

マイクロソフト開発者に対して、アプリケーションを1本公開するごとに100ドルの報酬を与えるキャンペーンを開始した。

今年の6月30日までの期間中にアプリケーションをWindows StoreもしくはWindows Phone Storeで公開するたびに、1本100ドル、最大2000ドルがマイクロソフトから報酬として支払われる。

(恐らくは、Windows Phone 8搭載端末を発売していない日本は蚊帳の外だろう)

今一つ盛り上がらない同社のストアでのアプリケーション展開に業を煮やして打ったのだろうが、Windows Phoneアプリケーションの場合、開発者はApp Hubへの登録料として日本ならば年間¥9,800円を、Windows Storeの場合個人開発者で¥4,900円、法人では¥9,800円を同社に支払っている訳で、その中でアプリケーション1本に対して100$ではお得感はこれっぽっちも無い。

アプリケーション開発を盛り上げたいのであればそのキャンペーン費用を開発プラットホームにの整備やコミュニティ活性化、端末の普及等に使い、個人開発者の登録料を原則無償※にするなどした方が、よほど盛り上がると思うのだが。

※元々学生は無償となっている

2013-02-05

[][]一攫千金

一攫千金!米グーグル、Chrome OSをクラックした人達に約2.9億円プレゼント | ガジェット速報

OSのセキュリティホールの報告で賞金を出すという企画は珍しくないが、総額総額3141590ドル(πに掛けているのか)というのが凄いな。

2013-02-03

[]4頂点座標のソートリベンジ

凸包の取得で解決した4点の座標の並び替えだが、挫折したままでは悔しかったので考え直してみた。

結果上手く出来た図と説明だ。

4つの頂点座標を任意の順にソートする

f:id:Kazzz:20130203205940p:image

1.中点を算出する

以前失敗した絶対座標(0,0)ではなく、全ての頂点座標の中点を使うことで座標の分散位置(4辺なら4カ所)が明確になる。
中点は全ての頂点座標のxとyは全ての座標を加算して、頂点の数で割ることで算出できる。※
中点x = (頂点座標xの和)/(頂点の数)
中点y = (頂点座標yの和)/(頂点の数)

2.領域をNSに分割する

中点を基準にして予めN(上部)領域とS(下部)領域に領域を分ける。

3.EW座標を並べ替える

座標をNとSに分割することで単純にNW(東西)で並び替えることでソートが完了する。

これで凸包を使わずとも、自由に頂点座標を並べ替えることができる。

※1.の中点とは所謂多角形の重心であり、重心を求めることを最初に思いつけば挫折することは無かったはずだ。
こんなの基本だよと知っている人は思うだろう。 やはり基礎って大切だよねというお話。

2013-01-23

[][]凸包とOpenCV

昨日までの件に関して、もう一度困っている事とやりたい事とを整理しておこう。

困っている事

findContourとapproxPolyDPで抽出した輪郭の頂点座標の出現順が一定しない。
座標原点の右上から出現したり、左下から出現したりするため、他の座標系(例:UIView)に変換することができない

やりたい事

findContourとapproxPolyDPで抽出した輪郭の頂点座標の列挙に一貫性を持たせ、他の座標系への変換を容易にする。

昨日までの私の足りない考えでの単純な方法では失敗したが、昨日コメントでアドバイス頂いたように、色々調べてみるとこのアルゴリズムは計算幾何学で言う所の"凸包"を算出する事に等しいのではないかということが判った。

凸包とは?

f:id:Kazzz:20130123193246p:image
「点の集合があったとき、その点を全て含んで且つ凹んでいる部分が無い(凸)多角形を形成する点の集合。」
とでも言えば良いだろうか。詳しくは、Wiki等を参照されたい。凸包 - Wikipedia

ということで方法としては点集合の凸包を元にその頂点を抽出していけば良い訳だが、幸いなことにOpenCVにはこの凸包を取得するためのメソッドが既に用意されている。 (ラッキー!!!)

cv::convexHull


Structural Analysis and Shape Descriptors - convexHull ― OpenCV 2.4.3 documentation

OpenCVのサイトにはサンプルコードも用意されているので、これを見ながらやれば完璧だ。

疑似コード(C++)
    //srcは入力画像をMatに変換したものを渡すこととする
    cv::vector<cv::vector<cv::Point>> squares;
    cv::vector<cv::vector<cv::Point> > contours;// 輪郭情報
    cv::vector<cv::vector<cv::Point> > poly;// ボリゴン情報

    // 輪郭抽出
    cv::findContours(src, contours ,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

    for (size_t i = 0; i < contours.size(); i++)
    {
        cv::Mat contour = cv::Mat(contours[i]);

        //凸包取得
        cv::vector<cv::Point> approx;
        cv::convexHull(contour, approx);

        // 輪郭・ポリライン近似 epsilonはarcLengthに対する割合で指定する
        cv::approxPolyDP(approx, approx, epsilon * cv::arcLength(contour, true), true);

        if (approx.size() == 4 ) //ここでは頂点数4、つまり四辺形の頂点集合だけを対象にしている
        {
           //destは出力先のMat
            cv::drawContours(dest, contours, i, CV_RGB(0, 0, 255), 4);
            //ベクタに格納
            squares.push_back(approx);
        }
    }

findContours〜approxPolyDPに至る間にconvexHullを介することによりベクタには凸包頂点座標が格納される。
convexHullの第3パラメタは頂点を抽出する際の向きとして時計回り/反時計回りを指定できるが、今回はデフォルトでに設定することでSW(右下)→NW(左下)→NE(左上)→SE(右上)と時計回りで座標が格納されるので、あとはUIViewの座標系原点に対して単純に変換すれば良い。

OpenCV convexHullによる凸包の頂点集合と、UIViewの座標系への変換

f:id:Kazzz:20130123193245p:image
iOSであればこのように単純に座標系を変換できる。

これで大丈夫だろう。 

今回もOpenCV様々だったが、正直な所私は"凸包"という用語自体知らなかった。 やはりコンピュータグラフィクスを扱うならば計算幾何学を知らないと駄目なので、もっと勉強しようと思う。

2013-01-22

[][]下手の考え休むに似たりとも限らない

実際に試してみると解ることだが、昨日の案は頂点が4つだとしても全ての頂点がNE、NW、SE、SWそれぞれに綺麗に属する訳もなく、複数属しているケース場合は更にその点を含む矩形を抽出して... とかやっていると切りが無さそうなので止めた。 もっと単純な、座標によるソートのオーダーを考えた方がよさげである。

下手の考え休むに似たり? いいや。おかげでstd:vectorのソート方法も解った訳で損はしていないと思う。

2013-01-21

[][]輪郭とその頂点座標を並べ直す

OpenCVのfindContourにおける輪郭と頂点座標の抽出順だが、色々と調べてもそのアルゴリズムが判らなかったので、以下のように考えて自分で並べ替えることにした。

輪郭(contour)

頂点が4つ以上の閉じた輪郭を対象とし、その面積(cv::contourAreaで取得できる)の降順でソートする

座標(coordinate)

f:id:Kazzz:20130121194534p:image
頂点を含む矩形(cv::boundingRectで取得できる)を4つに分割(北西、北東、南西、南東それぞれ方角の名前つける)し、頂点がどの領域に含まれているかを調べる。

属する領域が決まったら、OpenCVの原点の領域(NE)から1、2、3、4という図の順で並べ替える。

これで一貫した結果を取得できると思うのだが。まずは実装してみよう。