静寂とプログラミング

技術について書いたり、日常について書いたり

画像処理入門1日目

はじめに

こににちは、山田です。今日から画像処理についての記事を書いていくつもりです。まぁ、僕の専門が画像なので(ざっくりしてますけどw)なので、どんどん専門知識を深めていきたいと思い1日少しずつでも学習できたらと思います。

多視点幾何

今回は多視点幾何を勉強して行こうかと思います。

多視点幾何学とはなにか

異なる視点から撮影された画像間に対応関係があるときに、カメラや特徴量との関係性を研究する分野である。

エピポーラ幾何

エピ極(エピポール)とエピ極線を定義する。

F行列の計算

データモデリング入門1日目

はじめに

僕はデータベース関連をしっかりと勉強をしたことがなく(なんとなくで実装したり、フロント実装がほとんど)生きてきた人間で、これからフルスタックエンジニア(フルスタックエンジニアの定義も自分の中であいまいですがw)を目指してデータ側もやっていきたいと思い始めました。まとまりはないかもしれないですが、がんばっていく所存ですw。

また、ここで書かれていることは以下の本を参考にして書いています。 実践的データモデリング入門 (DB magazine selection) | 真野 正 |本 | 通販 | Amazon

なぜデータモデリングをするのか

データモデリングとはなにか

モデリングとは、現実の業界の世界を抽象化することである。言い換えると、「システムの対象を定まった記法で図式表現するもの」。文章によって、定義するものではないことを注意していた。ここで説明されるモデルは数学のように、誰が見ても同じ解釈になるようなものであり、つまり記法について読む側が理解している必要がある。

データモデルの種類

  1. 概念モデル システムのラフスケッチのようなもので、この段階ではデータ項目を全て決定しているわけではない。
  2. 論理モデル 概念モデルをより詳細にして、データ項目を全て決定している。
  3. 物理モデル RDBのテーブルと一対一に対応している。

対応範囲による分類

コーポレートデータモデル。 データモデリングDOA(Data Oriented Application)に基づいた手法である。

データモデル≒ER図 ER図はトップダウン分析に基づい区データモデル図であると言える。(なんで?...)

モデリングの手順

以下の手順はウォーターフォール型の開発工程にしたがって書かれた手順である。 1. 概念CDMの作成 構築したい対象のビジネス構造からトップダウン分析によって、エンティティを抽出する。このモデルはシステム構築ために行うというより、情報戦略ドキュメントの一つとして現在不足しているエンティティを知るためのものである。 2. 概念PDMの作成 概念モデルを作成せずに、論理モデルを作成すると重複や不整合成が生じるらしいが明確な理由はわからない...

  1. 論理PDMの作成 論理モデルを作成するためには、新たな画面イメージや現行システムの画面、帳票などからデータ項目を収集していく。最後にDFDをもちいてCRUD分析をして、データの充足性を検証する。
  2. 論理PDMに属性を追加して、関係づける テーブル、カラム名、インデックスなどのDBMS固有情報を付加して物理 PDMを作成。
  3. 物理PDMからDBMS上に実装 ログデータを含めた物理的な配置や適切な容量計算などが主な作業である。

トップダウン分析 / ボトムアップ分析

データモデリングには、二つの手法がある。 これらはどちらか一方を選択して使うわけではなく、両方の使い分けをする。最初はトップダウン的にエンティティを切り出して、次にボトムアップ的に抽出した結果を付加していく。 既存のシステムに対して、モデリングするときはボトムアップ分析をする。

まとめ

  • データベース実装だけが、データモデルの目的ではない。
  • データモデルには、マクロで捉えるコーポレートデータモデルと対象システムにターゲットを絞ったプロジェクトデータモデルがある。
  • モデリングは概念データモデル、論理モデル、物理モデルという手順を踏んで実施する。

OpenGLをmac0S Catalinaで使う

macOS CatalinaでOpenGLをインストールする

環境

OS: macOS Catalina version 10.15.3

macOSでのOpenGLの扱い

macOSでは、OpenGLは非推薦になった。 けど自分の勉強のためや、ちょっと触ってみたいという時にOpenGLを使いたいということもあると思います。
OpenGLmacOSで使うためには、GLUTやGLFWをインストールすることで使うことができます。 これらは何かというと、 OpenGLによって描画するものをWindowを起動してそこに描画したり、キーボードやマウスの入力を受け取るために 使われるものです。

1. GLUT
このライブラリはOpenGLの初期に作られたライブラリだが、GLUTはバグがあるのに、メンテナンスがされていないらしい。また、そこで、OpenGL3.2 CoreProfileは使用することができません。

2. GLFW
これは、LinuxWindowsMacOSXで使うことのできるクラスプラットフォームなライブラリです。これを使うことでGLUTにはなかった多くの機能を使うことができます。 またGLUTでは、OpenGL2.1にしか対応してませんでしたが、GLFWではOpenGL3.2にも対応することができます。

ここら辺のGLUTなのかGLFWなのかの議論は*1*2でなされており、特に*3では、そもそもOpenGLって今から手をつける必要あるかを議論してくれているので、大変勉強になります。

OpenGLのVersionを確認する

OpenGLのバージョンを確認してみましょう。
*4に書かれているようなコードを加えると、自分が使っているOpenGLのバージョンを確認することができます。 私のOpenGLのバージョンはMacの標準バージョンの2.1でした。

GLFWのインストール

brew install glfw でインストールすることができます。ただ、homebrewをインストールしている必要がありますので、他の記事で適宜補ってください。

Exampleを書いてみよう

公式ドキュメントの*5にGLFWのExampleコードがあります。 これをまずは適当なファイルに保存してください。

#include <GLFW/glfw3.h>

int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

このプログラムは、windowを立ち上げるだけのプログラムなので何か描画がされるわけではありません。実際にはwhileループ内で描画処理と更新処理を行う必要があります。

コンパイル

では、上のコードをコンパイルしましょう。 *6コンパイルスクリプトが書かれています。

clang++ -std=c++11 -stdlib=libc++ -lglfw3 -framework CoreVideo -framework OpenGL -framework IOKit -framework Cocoa -framework Carbon </path/to/cpp/file>

と書いてありますが、下の方に-lglfw3-lglfwに置き換えてくださいと書いてあるので、

clang++ -std=c++11 -stdlib=libc++ -lglfw -framework CoreVideo -framework OpenGL -framework IOKit -framework Cocoa -framework Carbon </path/to/cpp/file>

と書いてください。これで、コンパイルができるはずです。
あとは最後に、./a.outでwindowを立ち上げることができます。
プログラムを実行すると以下のようなwindowが立ち上がります。

f:id:dayama-daily:20200406232628p:plain
Exampleコードを実行した画面

おわりに

今回はOpenGLとGLFWの簡単なプログラムを実行するところまで書きました。GLUTだとスレッド処理が(おそらく...)書けなくて、困っていました。原因としてはglutMainLoop()という関数でループしており、他の処理が割り込めないためです。GLFWだとここら辺のループを自分で書くことができるので、自由が効いていいですね。他にもTextureの読み込みとかできる関数とかあるので、他の記事で紹介できたらなと思います。それでは。

参考

画像局所記述子 - Harris Corner 検出器

はじめに

実践コンピュータビジョンに書かれているものを自分の整理のために、まとめたものです。また、他の言語で書き直することで理解も深まるので、今回はSwiftで書き直したいと思います。(まだ、未完記事です)

画像の局所記述子とは

画像間の対応づけをするために使われる。 そのなかでも一番簡単なHarrisコーナー検出器について書きたいと思います。


Harrisコーナー検出器

判別関数
以下の関数が判別関数である。

    \frac{\det(M_1) }{\mathrm{Tr}(M_1)}

  1. 微分係数を計算する
  2. Harris行列の成分を計算する
  3. 判別式と対角成分(判別関数)を計算する

閾値を超えるコーナー候補を調べる
次に、判別関数によって各ピクセルのHarris行列を求めた画像と、Thersholdを使って、コーナーを 画像にプロットする。 1. 閾値を超えるコーナー候補を見つける 2. 候補の座標をとる 3. 候補の値を得る 4. 候補をソートする 5. 許容する点の座標を配列に格納する 6. 最小距離を考慮しながら、最良の点を得る


実装

インポートするライブラリ

from scipy.ndimage import filters # 微分係数を求めるために使用
import numpy as np
from matplotlib import pyplot as plt


判別関数によって出力された値を返す

def compute_harris_response(img, sigma=3):
    """
    グレイスケール画像の各ピクセルについて
    Harrisコーナー検出器の応答関数を定義する
    :param img: グレイスケール画像
    :param sigma:
    :return: Harris画像
    https://docs.scipy.org/doc/scipy-0.16.1/reference/generated/scipy.ndimage.filters.gaussian_filter.html
    """

    # 微分係数
    img_x = np.zeros(img.shape)
    filters.gaussian_filter(img, (sigma, sigma), (0, 1), img_x)
    img_y = np.zeros(img.shape)
    filters.gaussian_filter(img, (sigma, sigma), (0, 1), img_y)
    # Harris行列の成分を計算する
    Wxx = filters.gaussian_filter(img_x * img_x, sigma)
    Wxy = filters.gaussian_filter(img_x * img_y, sigma)
    Wyy = filters.gaussian_filter(img_y * img_y, sigma)
    # 判別式と対角成分(判別関数)を計算する
    Wdet = Wxx * Wyy - Wxy * 2
    Wtr = Wxx + Wyy

    return Wdet / Wtr


Harris応答画像からコーナーを返す

def get_harris_points(harris_img, min_dist=10, threshold=0.1):
    """
    :param harris_img: ハリス画像
    :param min_dist: コーナーや画像今日から分離する最小ピクセル数(値範囲が謎)、おそらく[0,1]
    :param threshold: コーナー候補を絞るための閾値(値範囲が謎)
    :return: 最小距離を考慮した、最良の座標配列
    """
    # 閾値を超えるコーナー候補を見つける
    corner_threshold = harris_img.max() * threshold
    harris_img_t = (harris_img > corner_threshold) * 1
    # 候補の座標をとる
    # ここの演算がよくわからん..
    coords = np.array(harris_img_t.nonzero()).T
    # 候補の値を得る
    candidate_values = [harris_img[c[0], c[1]] for c in coords]
    # 候補をソートする
    index = np.argsort(candidate_values)
    # 許容する点の座標を配列に格納する
    allowed_locations = np.zeros(harris_img.shape)
    allowed_locations[min_dist:-min_dist, min_dist:-min_dist] = 1
    # 最小距離を考慮しながら、最良の点を得る
    filtered_coords = []
    for i in index:
        if allowed_locations[coords[i, 0], coords[i,1]] == 1:
            filtered_coords.append(coords[i])
            allowed_locations[(coords[i,0]-min_dist):(coords[i,0]+min_dist),
                (coords[i,1]-min_dist):(coords[i,1]+min_dist)] = 0

    return filtered_coords


ついでにプロットする関数

def plot_harris_points(image, filtered_coords):
    """
    :param image: グレイスケール画像
    :param filtered_coords: 点の描画
    """
    plt.figure()
    plt.gray()
    plt.imshow(image)
    plt.plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')
    plt.axis('off')
    plt.show()

画像間の対応づけ

ここは後日...

Swiftでやってみる

ここは後日...

Atcoderで灰色から水色になる(現在進行形)

はじめに

この記事は現在進行形で変更されていきます。 基本的に、Atcoderで灰色から水色になるまでに解いた問題や、参考にしたいand参考にした記事について紹介します。

水色になるためにやること

水色に早くなるために、以下のことをやろうと思います。

  • 毎日A~Cの問題を20分で解く練習をする
  • D~F問題に関してはどんな問題が出たかを読んで理解する。(問題の傾向を理解するため)
  • 参考記事で推薦されている問題を1日1問ずつ解いていく。(基礎力をつけるため)
  • 毎回コンテストに必ず参加する

ちなみに

皆さん、アルゴリズムとデータ構造を理解した後に、重要となってくることは過去問を解くことです。水色コーダーになる辺りまでは、
競プロの実力 = アルゴリズムの理解度 × 競プロの演習量
だと考えることもできます。そのため、過去問を解くことはとても重要です。実際に、mencotton さんのツイート によると、800 問解けば 60% 以上、1100 問解けば 90% 以上の人が水色コーダーになれます。

と言っておられる方もいるので、今年で何問解いたかをこの記事の下の方に書いておこうかと

覚える知識

以下のアルゴリズムについて自分の理解を深めるために、記事を書く予定です。

参考

レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【上級編:目指せレッドコーダー!】 - Qiita

レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編:目指せ水色コーダー!】 - Qiita

厳選!C++ アルゴリズム実装に使える 25 の STL 機能【後編】 - Qiita

厳選!C++ アルゴリズム実装に使える 25 の STL 機能【前編】 - Qiita

自分が解いた問題

水色までTotal: 17 / 1100
年内に到達するには、この記事を書いたのが4/4なので年内の残りの日数は272です。
つまり(1100 - 17) / 272 = 3.98...
なので、1日最低4問解くペースですね...がんばります...

問題選定

以下の記事の中で選定してくれているので、それを随時解いていこうかと... レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編:目指せ水色コーダー!】 - Qiita
あとは、コンテストに参加して解いた分とかが加算しようかと
ついでにAOJのVolume0も

AIZU ONLINE JUDGE

ABC157
1. A - Duplex Printing
2. B - Bingo
ABC158
3. A - Station and Bus
4. B - Count Balls
5. C - Tax Increase
6. D - String Formation
ABC159
7. A - The Number of Even Pairs
8. B - String Palindrome
9. C - Maximum Volume
10. D - Banned K
ABC160
11. A - Coffee
12. B - Golden Coins
13. C - Traveling Salesman around Lake
14. D - Line++
ABC161
15. A - ABC Swap
16. B - Popular Vote
17. C - Replacing Integer

コンピュータシステムの理論と実装(1) - 基本論理ゲートをゲットした

基本論理ゲートをゲットした

はじめに

コンピュータシステムの理論と実装という本を読んでいます。 自分はコンピュータサイエンスを生業として生きていくつもりなので、学部時代に学んだことを 復習するような目的でこの本を読もうと思いました。また、最近C++を書くことが多いため、 どうせならさらに下のレイヤーまで復習したいなぁと思い立ったという次第です。
ついでに、他の方の参考になればと思います。 (ざっくりとしたまとめなので、本当にさっくり読む程度にしていただけると)

Nand2Tetris

この本では、自分で手を動かすためにNand2TetrisというCourseが公開されています。
https://www.nand2tetris.org/
これをつかって実際に手を動かすことができるような内容になっています。

ちなみに、このnad2tetrisをつかって、シューティングゲームを作った方とかもいます。(強い...)
www.youtube.com

ちなみに、Githubにコードが公開されています。(自分もこんな感じのものが作れたらいいなぁ)
GitHub - QuesterZen/hackenstein3D: Raycasting game for the Hack computer from Elements of Computing Systems / Coursera NAND2Tetris

HDL(ハードウェア記述言語)

回路を仮想的にシミュレートするために作られた言語である。
さまざまなソフトウェアが作られているが、この本では無料のHDLを提供してくれています。(神!)

https://www.nand2tetris.org/

そして、本の章で1章に対応する内容である、基本論理ゲートの実装を紹介します。

HDLシミュレータの使い方

論理ゲートを実装していくためにHDLを使用していきますが、HDLで回路を作るために まずは使い方について紹介します。

ソフトウェアの起動方法

DLしたフォルダ内にあるtoolsディレクトリにある、*.shを呼び出すことによってそれぞれのソフトウェアを起動することができます。

コーディング規則

回路名はXxxの形で名前をつけます。
XOR回路 -> Xor、AND回路 -> Andのような感じです。

Xxxは別ファイルとしてXxx.hdlが定義されていることになる。

回路構造の記述

回路を作成すために二つの要素で構成されています、

  1. ヘッダ:インターフェース部分を記述する
  2. ボディ:実際の実装を記述する

まずは例を出します

Chip chipname {
IN pinName1, pinName2, ...;
OUT pinName1, pinName2, ...;
BUILDN: java_class_name

PARTS :
chipName(a=pinName1, in=pinName2)
internal chip part2;
internal chip part3;
...

}

ヘッダ部分はIN, OUT, BUILDINの部分になります。
ボディ部分はPARTS以下になります。

ボディ

ボディについてはさらに3つの要素で構成されています。 1. PARTS 2. ピンとピンの接続 3. バス

PARTS

ピントピンの接続

バス

入力ピン、出力ピン、内部ピンのどれであっても多ビットバスを使うことができる。

ビルドイン回路

BUILDIN java_class_name

ファイル構成

.hdl

シミュレート用のプログラムを実装するファイル

.tst

シミュレーターのテストファイル

..cmp

正しい出力結果のファイル

基本論理ゲートを作ってみる

HDLの記述方法はだいたい紹介したので、次は基本的な論理ゲートとなる回路を Nand回路を組み合わせることで作成してみたいと思います。

Nand

まずはNandから。
次に紹介していくゲートは基本ゲートと呼ばれる。 全てのゲートはNandのみで表現することが可能である。 また、実装する上でもNandをプリミティブなゲートとして他のゲートを作っていく。 また、3つのファイルから構成している。

また、次に作成していくゲートはprojects/01の中で作成していく。

ここで、力尽きた。。。(数日内に書き上げます)

Not

And

Or

Xor

Unity Evangelistってなんぞ

Unity Evangelistってなんぞ

タイトル通りUnity Evangelistってなんだろうと思い調べてみました。

Unity Evangelistとは

The Unity evangelism team ここには、こう書いてありました。

Unity evangelists help the real-time creator community flourish by sharing their passion and knowledge. By showcasing the power and potential of Unity’s real-time 3D platform and tools – at game jams, studios, conferences, online or elsewhere – our evangelists enhance users’ skill sets and spark excitement about Unity’s limitless possibilities for creativity.

まぁ、いろいろ書いてありますが、Unityを使うコミュニティの拡大と強化をするために、ユーザに協力する人たちということだと思います。

ちなみに、Unity Evangelistたちのお顔が見れます。
国ごとに区切られているので、国ごとのチームということになるんでしょうか。

竹内一生のご挨拶 には、さらに面白いことが書いてあります。

ところで皆さんはエバンジェリストって何かご存知でしょうか。 エバンジェリスト(Evangelist)とは「キリスト教における伝道者」を指しています。 これだけ聞くと胡散臭いですね。 意味合いとしては、日々進化を続けるITのトレンドや最新技術について解説し、啓蒙する、IT業界の新しい職種の名称として使用されるようになっています。

Unityを広める活動をするUnity信者ってことですかね。

他、 クリエイター | Made with Unity

Unity Evangelistたちは具体的に何をするのか?

GIthub上に以下のようなものを発見しました。 github.com おそらくここにEvangelistたちが作った、面白いサンプルやツールがありますね。 個人的には、DOTSが気になってます。(こんどDOTSの記事をあげる予定。。。)

あとは、UniteやUnity道場などのカンファレンス、勉強会等の主催や登壇をしてくれているみたいですね。

meetup.unity3d.jp

learning.unity3d.jp (このスライドはすごい参考になります)

また、何か気になったことがあれば追記していきますので、これくらいで終わります。