iPX社員によるブログ

iPX社員が"社の動向"から"自身の知見や趣味"、"セミナーなどのおすすめ情報"に至るまで幅広い話題を投下していくブログ。社の雰囲気を感じ取っていただけたら幸いです。

【OpenCV】GrabCutの使い方【セグメンテーション】

入社して半年が経ちました。最年少社員の安藤です。



つい一月半ほど前まで高校時代の同級生と同居していたのですが、最近のぼくのこころのなかにはコンピュータビジョン(CV)が住み着いています。
そんな彼はふとした時、ぼくに問いかけてきます。

「CVは楽しいかね?」

仕事は楽しいかね? (きこ書房)

仕事は楽しいかね? (きこ書房)



楽しいです。



そんなわけで今回はOpenCVの便利なメソッドのひとつを紹介したいと思います。



GrabCutとは?

GrabCutとはセグメンテーションに利用されるアルゴリズムの名称です。

グラフ理論を応用したコスト最小化手法GraphCutを用いたくりかえし処理を行っているそうです。
アルゴリズム本体の詳細については他にまとめが存在しているので、下記をご覧ください。

http://visitlab.jp/pdf/GrabCut.pdf
http://zellij.hatenablog.com/entry/20131004/p1


むずかしそうな数式がたくさん並んでいますね。

こんな時もぼくの精神的CVはいつもそばにいて、助言をあたえてくれるのです。



OpenCVを使え」




OpenCVを使いましょう。

解説

import cv2 as cv
import numpy as np


BLUE = [255,0,0]        # rectangle color
RED = [0,0,255]         # possible BG
GREEN = [0,255,0]       # possible FG
BLACK = [0,0,0]         # obvious BG
WHITE = [255,255,255]   # obvious FG

DRAW_BG = {'color' : BLACK, 'val' : 0}
DRAW_FG = {'color' : WHITE, 'val' : 1}
DRAW_PR_FG = {'color' : GREEN, 'val' : 3}
DRAW_PR_BG = {'color' : RED, 'val' : 2}


# 現在の描画する線の色
value = DRAW_FG


# 描画する線の太さ
thickness = 3


# ウィンドウ名
win_name = "WINDOW"


# grabcut結果表示の際、alphaが大きいほど黒背景が濃ゆくなる
alpha = 0.7
beta = 1 - alpha


# grabcutイテレーション回数
itr = 1


# 描画フラグ
drawing = False


# 出力イメージ番号
pic_num = 1



def mouse_event(event, x, y, flags, param):
    global display, mask, thickness, value, drawing, bgdModel, fgdModel

    if event == cv.EVENT_LBUTTONDOWN:
        drawing = True
        cv.circle(display, (x, y), thickness, value['color'], -1)
        cv.circle(mask, (x, y), thickness, value['val'], -1)

        
    elif event == cv.EVENT_MOUSEMOVE:
        if drawing == True:
            cv.circle(display, (x, y), thickness, value['color'], -1)
            cv.circle(mask, (x, y), thickness, value['val'], -1)
        
        
    elif event == cv.EVENT_LBUTTONUP:
        if drawing == True:
            drawing = False
            cv.circle(display, (x, y), thickness, value['color'], -1)
            cv.circle(mask, (x, y), thickness, value['val'], -1)
            

if __name__ == '__main__':


    img = cv.imread("lena.png")
    display = img.copy()

    mask = np.zeros(img.shape[:2], dtype=np.uint8) 
    bgdModel = np.zeros((1,65), dtype=np.float64)
    fgdModel = np.zeros((1,65), dtype=np.float64)

    cv.namedWindow(win_name, cv.WINDOW_NORMAL)

    roi = cv.selectROI(win_name, img)

    cv.grabCut(img, mask, roi, bgdModel, fgdModel, itr, cv.GC_INIT_WITH_RECT)
    
    mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
    display = img * mask2[:,:,np.newaxis]
    display = cv.addWeighted(display, alpha, img, beta, 0)

    cv.setMouseCallback(win_name, mouse_event)
    
    while (True):

        cv.imshow(win_name, display)
        key = cv.waitKey(1)

        if key == 27:
            cv.destroyAllWindows()
            break


        elif key == ord("n"):

            drawing = False

            cv.grabCut(img, mask, roi, bgdModel, fgdModel, itr, cv.GC_INIT_WITH_MASK)
            mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
            display = img * mask2[:,:,np.newaxis]
            display = cv.addWeighted(display, alpha, img, beta, 0)


        elif key == ord("s"):
            cv.imwrite("processed" + str(pic_num) + ".png", display)
            pic_num += 1


        elif key == ord('0'): # BG drawing
            print(" mark background regions with left mouse button \n")
            value = DRAW_BG
            print("Obvious BGD")


        elif key == ord('1'): # FG drawing
            print(" mark foreground regions with left mouse button \n")
            value = DRAW_FG
            print("Obvious FGD")


        elif key == ord('2'): # PR BG drawing
            value = DRAW_PR_BG
            print("Possible BGD")


        elif key == ord('3'): # PR FG drawing
            value = DRAW_PR_FG
            print("Possible FGD")


このコードをつかってLena氏の顔を抽出してみましょう。

f:id:ipx-writer:20190215154053p:plain

初期矩形情報だけでここまでとれました。

f:id:ipx-writer:20190215154103p:plain

これを修正すると…

f:id:ipx-writer:20190215154126p:plain

f:id:ipx-writer:20190215154130p:plain



きれいに顔だけ抽出できましたね!

大阪旅行

こんにちは。昨年入社いたしましたkuboです。
まだ入社してから1年たっていないので、今は日々、技術について、ビジネスについて勉強しております。
初めての記事で何を書こうか迷ったのですが、まだ技術的なことを書くことは難しいので年末にプライベートで行ってきた大阪旅行について書きたいと思います。

旅行前日

東京から大阪まで夜行バスで移動したのですが、バスがド派手でびっくりしました。
f:id:ipx-writer:20190204205128j:plain
f:id:ipx-writer:20190204205209j:plain
久しぶりの夜行バスで、朝5時ごろにサービスエリアで休憩があったのですが、足がむくみすぎて靴がはけなかったです。

初日

大阪に到着後は最初に海遊館へ。
f:id:ipx-writer:20190204205402j:plain
f:id:ipx-writer:20190204205448j:plain
魚たちを見た後は夜行バスの疲れを取るためにホテルで昼寝。
夜はお好み焼きを食べに行きました。

帰りに綺麗なイルミネーションも見ることができました。
f:id:ipx-writer:20190204205515j:plain

2日目

とりあえずこれ!
f:id:ipx-writer:20190204205542j:plain
お昼はたこ焼きを食べました。
f:id:ipx-writer:20190204205621j:plain
夜は今回の旅行のメインのライブ。大阪城ホールへ向かいます。
f:id:ipx-writer:20190204205715j:plain
f:id:ipx-writer:20190204205736j:plain
ライブの後は疲れ果てて、すぐにホテルで寝ました。

3日目

3日目は通天閣を観光しました。
f:id:ipx-writer:20190204205757j:plain
最後はふたたび明石焼きを食べて旅行終了!
f:id:ipx-writer:20190204205817j:plain
やはり大阪は天下の台所と言われるだけあってご飯はおいしかったです。

リハビリとは何でしょうか

初めまして。カマタです。
入社してからちょうど半年が経ちました。月日が流れるのは早いですね。
私は異業種からの転職のため、今回は前職のことを紹介したいと思います。

前職は作業療法士をしておりました。
皆様、作業療法士をご存知でしょうか???

作業療法士リハビリを提供する職種の一つです。
リハビリと聞いてもあまりイメージが湧かないと思いますので、
今回のブログでリハビリのイメージを少しでも掴んでいただければと思います。

リハビリと介護の違い??

リハビリは介護のようなイメージを持っている方も多いかもしれません。
たしかに、似ているところはありますが、専門としている業務内容が異なります。

リハビリは理学療法士作業療法士言語聴覚士の3職種があり、
いずれも、心身に障害のある対象者の自立、自律した日常生活の獲得を図るために、
機能訓練代償手段の活用などの指導を行います。

介護福祉士は心身に障害のある対象者が日常生活をスムーズに営めるように、
排泄や入浴などの身の回りの介護を行います。

何となく伝わりますでしょうか。
興味のある方は調べてみてください。

リハビリの職種の違い

さて、リハビリには3職種あると紹介しました。
これらの職種の違いについても一言で書いていきたいと思います。


理学療法士(PT):基本的な動作(寝返り、立ち上がり、歩行など)の獲得を目指します。
作業療法士(OT)日常生活動作(食事、排泄、入浴など)や家事動作などの獲得を目指します。
言語聴覚士(ST):認知機能や嚥下機能の向上や維持を目指します。


専門としている分野が違いますが、対象者の自立、自律した日常生活の獲得のためには、
作業療法士であっても基本的な動作や認知機能、嚥下機能の評価をします。


対象者が座位姿勢を保てるのかが不明な状態で、
「椅子に座って食事の訓練をしましょう!」とはなりません。


もしも、そのような状態で訓練をしていた場合、
インシデントアクシデントを多発すること間違いありません・・・。
基本的な動作は理学療法士が得意としているため、情報共有しながらアプローチしていきます。


リハビリの職種の違いに関して、何となくでもご理解いただけましたでしょうか。

作業療法士の一日

では、続いてとある病院の作業療法士の一日の流れリハビリの流れを紹介します。

私は、とある総合病院の急性期脳神経外科チームに所属しておりました。

毎朝必ず行うことは

  • 所属している病棟に新規の入院患者さんがいるか確認。

  入院患者さんがいる場合、カルテから情報収集し、
  医師からリハビリのオーダーがでそうか検討。
  リハビリオーダーがでそうな場合、初回介入者となるスタッフを決める。

  • リハビリ予定の患者さんの情報収集(7~9人程度)
  • 検査などがリハビリ介入時間と重なっている or 医師からリハビリオーダーが出そうな新規の患者さんがいる場合は

  リハビリ予定の患者さんの介入時間の変更(何かと制約があり難しい)


患者さんの情報収集とリハビリ介入時間の調整を終え、いよいよ順番に介入していきます。

患者さんに予めリハビリの開始時刻を伝えておき、実際に開始時刻に迎えに行きます。
しかし、突然の検査であったり、談話室で家族や友人と話していたりと
病室におらず行方不明なことが多々あり、探すのが一苦労なときもあります・・・。

基本的に、お昼休憩以外は
リハビリ介入→カルテ記載(5分)+情報共有→リハビリ介入
を繰り返します。例外もありますが、ここでは省略します。


リハビリ介入後は

  • 脳神経外科チームでミーティング(病状の変化や日常生活の安静度の変更を報告)
  • 次の日のリハビリ介入患者さんのリハビリ介入時刻の調整
  • 書類作成

以上が大雑把な一日の流れです。カルテ記載の時間が5分と短く、常に時間との闘いです。
この他にもDr.やNs、MSWとのカンファレンスなど週1や月1で行う業務もあります。

リハビリの流れ

毎朝、新規の入院患者さんがいるか確認すると書きましたが、
Dr.から患者さんのリハビリオーダーが出た場合、リハビリの治療計画を立案していきます。

リハビリの流れは、

  1. 基本情報の収集
  2. 初期評価
  3. 目標設定
  4. 問題点の抽出
  5. 治療プログラムの立案
  6. 再評価

であり、治療期間中、4~6を繰り返します。
最近読んだロジカルシンキングの本にでてくるPDCAサイクルに似ているかもしれません。

患者さんの担当となる理学療法士作業療法士言語聴覚士それぞれが初期評価し、
現在の心身機能の状態から、歩行の自立が可能か自立した排泄動作の獲得は可能かなど、
予測を立てたうえで、患者さんやご家族と一緒にリハビリの目標を設定します。

その後は、目標達成に向けて、現状から問題となっている
心身機能や基本動作などを抽出し、訓練していきます。
治療の妥当性を検討するために再評価を繰り返し、
必要に応じて問題点の変更治療プログラムの立て直しを行います。

リハビリ終了はいつ?

患者さんの生活環境によって求められる能力が異なるため、
病院の環境日常生活動作を獲得できたからリハビリ終了という訳にはいきません。

数cmの高さの違いにより、座位から立ち上がれなくなることは
よくあります!!!

そのため、実際の生活環境でも安全に動作可能か評価するため、
ご家族見守り下にて外泊を行うことや、実際に家に訪問し動作可能か評価することがあります。

対象者の生活環境でも目標としていた動作を安全に遂行可能となると、
Dr.にリハビリ終了レベルであることを報告し、患者さんの退院日程の調整が進みます。


以上、リハビリの全体的な紹介でした。何となくイメージが湧きましたでしょうか?

最後に

もしも今後リハビリを受ける機会があれば、リハビリの開始時刻には
約束した場所(病室の場合が多い)にいるようにしてください。よろしくお願いいたします。

はじめまして、堀越です。

はじめまして。ホリコシです。
入社してから初めてのブログです!

あらたな業界で日々精進しています。。。
前職(正確には前々職)は専門学校で4年ほど、情報処理試験対策講師をしていました。

今回はどんなことをやっていたのかを書いてみたいと思います。

FE_基本情報技術者試験

経済産業省が行っている国家試験です。
レベル1~4のなかのレベル2の試験です。
午前と午後で試験があり、両方で基準点(60%)を超えると合格になります。

CASLⅡ(アセンブラ言語)

午後試験に出てくる『ソフトウェア開発』の項目で登場します。
※一番簡単なのは表計算だと思います。

こんな感じの問題です。
f:id:ipx-writer:20190131142101j:plain

まずは準備
f:id:ipx-writer:20190131142254j:plain

f:id:ipx-writer:20190131142352p:plain

準備その2
f:id:ipx-writer:20190131142520j:plain
f:id:ipx-writer:20190131142608p:plain

流れを見ていきます
f:id:ipx-writer:20190131142709j:plain
最初の『RPUSH』でレジスタの中身をスタックにコピーします。
※プログラム終了時に初期状態に戻すためです。
f:id:ipx-writer:20190131142843j:plain

f:id:ipx-writer:20190131142931j:plain
3~5行目で各レジスタ(GR)に値を設定します。
・GR5に『GR2の中身 + 0』のメモリの場所の中身
・GR3に『GR2の中身 + 1』のメモリの場所の中身
・GR1に『GR2の中身 + 2』のメモリの場所の中身
f:id:ipx-writer:20190131143010j:plain

f:id:ipx-writer:20190131143043j:plain
6~8行目でレジスタ1(GR1)に基準日からの日数を設定します。
・GR1に設定されているのは、指定された日付が入っているのでー1をして調整します。
※基準日が1月1日、指定日が1月10日の時、最初の1月1日は含まず「2,3,4,5,6,7,8,9,10」の9(10-1)日となるのと同じです。
f:id:ipx-writer:20190131143119j:plain

f:id:ipx-writer:20190131143150j:plain
8行目でレジスタ1(GR1)にレジスタ4(GR4)の番地の中身を足しています。
・GR1に設定されているのは、指定された『日付のみ』が入っています。
※基準日が1月1日、指定日が2月10日の場合
f:id:ipx-writer:20190131143309j:plain
26行目に上図の足りない部分が用意されているので、この値を使って計算していきます。

f:id:ipx-writer:20190131143358j:plain
8行目の『ADDL GR1, -1, GR4』でGR1に足りない部分『334』を足したいので、
(-1 + GR4の中身)が211になるように7行目の空欄でGR4に値を設定します。

f:id:ipx-writer:20190131143500j:plain
といったところが基本的なながれになります。

平成最後の情報処理検定(国家資格)も『2月18日(月)20時まで』
申込み受付中です。ぜひ、挑戦してみてはいかがでしょうか。

オートモーティブワールド2019にご来訪いただきありがとうございました

1/16, 17, 18に東京ビックサイトにて開催されましたオートモーティブワールド2019におきましては、たくさんの方に弊社ブースへお立ち寄りいただきまして誠にありがとうございました。
弊社ブースでご紹介させていただきました技術につきましては、弊社公式サイト内のTIPSページでもご紹介しておりますので、是非ご覧ください。
f:id:ipx-writer:20190130142410j:plain

オートモーティブワールド 2019のご案内

この度、弊社は来週1/16, 17, 18に東京ビックサイトにて開催されるオートモーティブワールド 2019に出展致します。
弊社の最新技術を用いた取り組みをご紹介致しますので、ぜひお誘い合わせの上ご来場いただけますと幸いです。

出展情報

イベント:第11回 オートモーティブワールド(オートモーティブワールド 2019)
会  期:2019年1月16日(水)~1月18日(金)
開場時間:10:00~18:00 ※最終日は17:00まで
会  場:東京ビックサイト
出  展:第2回 自動運転EXPO
出展場所:東7・8ホール E60-002

展示内容

  • 強化学習を用いたラジコン走行デモンストレーション
  • Jetson AGX Xavier - Caffe vs TensorRT(TensorRTによるインファレンス高速化)
  • CarSim×Vissim連携(シミュレーション車両相互間連携)
    PTVグループジャパン様 共同出展
  • 特殊センサーデモンストレーション (PROPHESEE)

First come, first served.

年の瀬に失礼しますHirosakiです。
前回の投稿から約半年が経ちました。
これまでコンパイル・共有メモリアプリと色々やってきましたが、
もう少し役割のある何かを作れる記事を書けたらな・・・と模索しておりました。

そんな中ふと目にしたライブラリが気になったので触ってみたいと思います。
出来たもの次第では何か発見が得られるのではいか、という実験企画です。
先んずれば人を制す、と行きたいものです。

以下より続きます。

続きを読む