「時間の無駄」の見分け方

目次

  • 事実無根ッ!
  • 目的と違うッ!!
  • 無為無策
  • 無駄無駄無駄無駄ァーッ!!

 

事実無根ッ!

事実に基づかない思考や議論は時間の無駄。

論理の組み立てにおいて、前提条件が違うならば、その後の議論はすべて無意味だからだ。

 

目的と違うッ!!

目的地が前方にあるとき、真横に進んでもたどり着けない。

 

無為無策

課題や障害を乗り越えようとするとき、無為無策に走ることは時間の無駄だ。

 

人は「天国」へ行くためにその人生を過ごすべきなのだ。

日曜の昼からひとりで飲んだくれてボケッとしてる時間さえ、それは「天国」へ行くための道のりの一部だ。

 

 

 

 

無駄無駄無駄無駄ァーッ!!

生まれてきてから大人になるまで、沢山の無駄を経験してきた。

ようやく、無駄とそれ以外が分かるようになってきた。

 

自ら窮地に陥っていく主人公は見てられない

  • 隠れ場所に不意に敵がやって来たとき、くしゃみする。
  • 敵に追われて逃げているときに一人で勝手に転ぶ。
  • 無事に安全な場所に逃げてきたあとで、落とし物/忘れ物に気付いて危険な現場に戻る。結果、捕まって窮地に陥る。
  • 先にやられた仲間と同じやられ方をする。
  • 敵の目を盗んでやっとこさ電話を掛けたとき、十分に伝える時間があったのにもかかわらず、どーでもいいことばかり話して要件を伝えずに通話が切れる。

 

逆境にも屈しない主人公を描くなら、敵の能力が高いゆえにピンチになる展開の方がいい。

 

主人公が無能ゆえにピンチになるときは、大人しくやられてほしい。

 

人に好かれたかったら、何か役に立つことをすればいい

好きな人を振り向かせるのに、一番確実な方法は、その人の役に立つことだ。

 

ひとつだけ気を付けなくてはならないことがある。

 

役に立ったかどうかを決めるのはあなたではなく、相手だ。

 

「何かをしてあげた」などと思わない方がうまくいくだろう。

 

役に立つかどうかは相手が判断する。だから、何が役に立つかを推測するのは難しく感じるかもしれない。

 

でも、コツをつかめば意外と簡単だ。

 

キーワードは快楽だ。

一応補足するが、快楽と言っても性的なものに限らない。

 

▪美味しい食事を振る舞う。

▪楽しいジョークで笑いをとる。

▪キレイなアクセサリーをプレゼントする。

 

味覚への快楽だったり、コミュニケーションへの快楽だったり、財産所有への快楽だったりする。

 

巷で言われる、「※ただし、イケメンに限る」、というのは、視覚や自己顕示欲、承認欲求への快楽が重視されやすいというに過ぎない。

 

仮に不細工でも、他に役に立つところがあればいいのだ。

 

「開発する!」と机に向かったならッ!その時スデに行動は終わっているんだッ!

机に向かっただけで開発が終わるというのは少し言い過ぎでしたので訂正させていただきます。

「机に向かって座ることさえできれば、開発は半分終わったも同然」ということです。

というのも、開発や勉強をするとき、机に向かうことが最初にして最大の障壁です。

逆に言えば、机に向かって座りさえしてしまえば、あとは作業を行うしかないので、必然的に行動は終わってしまうのです。

ただ、ひとつだけ注意しておきたいことがあります。

机に向かうときは、「手ぶら」で。

スマホやら漫画やら持ってたら、座ったあと開発や勉強を始めることが難しくなります。

「手ぶら」であれば、無為に座り続けるか行動するかの2択を自らに課すことができます。

もし、その状態で無為を選択するのであれば、その日は無理と諦めるのもある意味「勇気」と言えるでしょう。

画像中の特定の領域を切り取る方法

Open Skirtでは、ユーザがアップロードした画像データを分析し、どの部分がスカートかを特定して切り抜く処理を行っています。

f:id:openskirt-master:20180304203810p:plain

本記事では、スカート領域の特定を行う処理についてソースコードを交えて具体的に書いていきます。

 

前提

Ubuntu 16.0.4

Python 2.7

OpenCV 3.0

 

まず、問題を定義する

やりたいこと(要件)は下記です。

  1. WEBサービスの利用者は、PC / スマホからアクセスする一般ユーザである。
  2. 入力画像はユーザによってアップロードされる写真データである。
  3. 入力画像ごとに位置・形状が異なるスカート領域を簡単に抽出できる。

 

解決方法を検討する

最初に検討したのは、WEB画面上でユーザ自身にスカート領域を指定してもらう方法でした。

しかし、ブラウザ上でスカート領域をきれいに切り取らせるのはユーザビリティの観点で問題があると判断し、断念しました。

 

次に検討したのは、アップロードされた画像をAIで自動的に領域抽出する方法です。こちらの手法についての詳細は、「セグメンテーション」というキーワードで検索するといろいろ出てきます。
将来的にはこのような先端的な技術を取り入れたいところですが、開発の初期段階では工数が大きすぎると判断し、いったん見送ることにしました。

 

そんなわけで、Open Skirtで採用したのは、OpenCVに実装されているヒストグラムの逆投影法(cv2.calcBackProject)を使う方法です。

ユーザがブラウザ上でスカートの位置をクリックし、スカート領域を半自動的に特定するようにしました。

 

処理内容

アルゴリズムの概要は下記です。

  1. ユーザからスカートの位置(座標)を受け取る。
  2. 領域抽出の前処理を行う。
  3. 受け取った座標を中心として、所定の範囲の色情報を取得する。
  4. cv2.calcBackProjectでスカート領域の抽出を行う。
  5. 抽出結果を返す

 

ヒストグラムの逆投影法とは

そもそも、ヒストグラムの逆投影法とは何かというところから紹介します。

OpenCVチュートリアルにこんな説明がありました。

簡単に言うと,各画素が対象物体に属している確率を表す入力画像と同じサイズで単相の画像を作成します.さらに言うと,出力画像中で対象物体のように見える部分は白く,それ以外の部分は黒くなります.これは直観的な説明です(これ以上単純に説明できません).

OpenCVのチュートリアルより引用

 

全然簡単に思えませんので捕捉しますと、要するに下記の図のような処理をしますよ、ということです。

f:id:openskirt-master:20180305132829p:plain

 

少しはわかりやすくなったでしょうか。

上記ヒストグラムの逆投影法を行うには、入力画像と対象物体を指定する必要があることがわかりますね。

 

対象物体の扱い方について

入力画像はユーザがアップロードしたものをそのまま使えばいいとして、対象物体については要件に応じて調整する必要がありますので、そこらへんをもう少し詳しく書きます。

 

後述するソースコードを見ていただければわかりますが、 ヒストグラムの逆投影法を行うためには、入力画像・対象物体のヒストグラムを利用します。

ヒストグラムとは何ぞ?という方はこちらを参考になさってください。

ヒストグラムとは画像中の画素値の全体的な分布を知るためのグラフやプロットとみなせます.

f:id:openskirt-master:20180305134425j:plain

OpenCVのチュートリアルより引用

 

ヒストグラムの逆投影法では、入力画像中で対象物体のヒストグラムと似た領域を抽出します。

 

もし対象物体の大きさが小さすぎると(極端な話、対象物体の大きさが1ピクセルだけだとすると)、その色しか抽出されなくなってしまいます。実際の写真データを扱う場合、光の当たり方によって同じ色に見えても正確には同じではないですし、スカートの場合はチェック柄などの柄ものを抽出できなくなってしまうのは困ります。

 

したがって、対象物体の大きさは、抽出したい領域に含まれる色をある程度含む程度の大きさにする必要があります。

 

さて、能書きはこれくらいにして、いよいよソースコードを見ながら具体的な処理を見ていきたいと思います。

 

ソースコード

Open Skirtで実装しているソースコードより抜粋。

import cv2

# ヒストグラムの逆投映法
# img : ユーザアップロードの入力画像
# pos : 対象物体の中心座標
# size: 対象物体の大きさ
def doBackProject(img, pos, size = 30):
    # posを中心に、上下左右size分の正方形領域を対象物体とする。
    maskRect = {
        "top": int(pos[1] - size),
        "bottom": int(pos[1] + size),
        "left": int(pos[0] - size),
        "right": int(pos[0] + size)
    }

    # 領域抽出の前処理を行う
    target = cv2.GaussianBlur(img, ksize=(51,51), sigmaX=2)
    target = cv2.cvtColor(target, cv2.COLOR_BGR2HSV)

    # 対象物体の範囲の色情報(HSV)を取得する
    mask = target[
                int(maskRect["top"]):int(maskRect["bottom"]),
                int(maskRect["left"]):int(maskRect["right"]),
                :
            ]

# 対象物体のヒストグラムを計算する。 maskHist = cv2.calcHist([mask], [0,1], None, [180,256], [0, 180, 0, 256]) cv2.normalize(maskHist, maskHist, 0, 255, cv2.NORM_MINMAX) # ヒストグラムの逆投影法で領域抽出を行う dst = cv2.calcBackProject([target], [0,1], maskHist, [0, 180, 0, 256], 1) disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (17, 17)) cv2.filter2D(dst, -1, disc, dst) # 抽出結果を返す ret, thresh = cv2.threshold(dst, 120, 255, 0) thresh = cv2.merge((thresh, thresh, thresh)) res = cv2.bitwise_and(img, thresh)   return res

 

ソースコード内のコメントで表現しきれない部分を補足します。

 

領域抽出の前処理について

ガウシアンブラー(cv2.GaussianBlur)は、ぼかし処理です。

ぼかす理由は、領域抽出の精度が上がるからです。

なぜぼかすと精度が上がるかというと、抽出領域中のノイズや細かい模様が平準化されるため、対象物体のヒストグラムと類似する確率が上がるためです。

 

対象物体のヒストグラムを計算するについて

このサンプルはOpenCVのチュートリアルに記載の実装と同じです。

[0, 1]は、ヒストグラムを計算する系列の定義です。今回はHSVに変換しているので、0番目と1番目の系列はH(色相)とS(彩度)です。

続く[180, 255] や [0, 180, 0, 255]は各系列に対する集計単位と集計対象の定義になります。OpenCVではHの定義域が0 ~ 180なので、0番目の系列に対する定義に180という数字が出てきています。

 

ヒストグラムの逆投影法で領域抽出を行うについて

cv2.calcBackProjectの引数の[0, 1]や[180, 255]部分は対象物体のヒストグラム計算で用いた値と同じ値を使います。

cv2.getStructuringElementは、単に半径17ピクセルの白い円を取得しているだけです。

cv2.filter2Dについては、OpenCVのドキュメントにあまり詳しく書いてないのでぶっちゃけよく分かっていないです。きちんと理解したい方はOpenCVのソース読んでください。

 

抽出結果を返すについて

ヒストグラムの逆投影法で取得した領域を白黒の2値化して、入力画像と重ね合わせることで対象物体の領域だけ切り抜いています。

 

 

まとめ

 

画像から手軽に不定形領域を切り抜く処理を探している方の参考になれば幸いです。

また、記事中の間違いや、もっといい実装方法があるよ、という方がいらっしゃったら気軽にコメントしてください。

 

Open Skirtの技術ブログできました!!

閲覧ありがとうございます。

 

先日OpenSkirtというWebサービスをHerokuに公開しました。

openskirt.herokuapp.com

 

個人開発のWebサービスですが、中身的にはディープラーニングや画像解析、3D描画などの技術を利用しています。

宣伝がてら、技術ブログデビューしてみようと考えて、いつもお世話になっているはてなブログのアカウントを取ってみました。

 

これからOpen Skirtの開発に用いた技術を少しずつ公開していこうと思いますので、温かく見守っていただければと思います。

 

またもし、Open Skirtを使っていただけた方から「ここってどういう仕組みになってるの?」などのご質問をいただければ、優先的に記事にしていこうと考えています。

 

なにぶんブログ初心者のため、マイペースな更新になると思いますが、気長にお付き合いください。