LoginSignup
4
2

More than 5 years have passed since last update.

OpenCVを利用してfindContoursで輪郭を取得するサンプルをColaboratoryでサクッと動かして確認する

Posted at

はじめに

対象読者

  • OpenCVを使った画像処理をしてみたい人
  • サンプルを動かしながら確認したい人
  • 画像の輪郭を取得したいけど、どうやったらいいかよくわからんっていう人

このページの目的

  • OpenCVを実際に動かしながら使ってみる。
  • 画像から輪郭を取得してあれこれ処理をする前準備ができるようになること

その他

  • 画像処理を仕事で色々使ってみたなかで調べたことや詰まったことを整理しながら書いてみます。
  • 参考URLは都度書きます。
  • サンプルはgithubにおいてます

アジェンダ

1.Colaboratoryの使い方
2.OpenCVの使い方

1.Colaboratoryの使い方

colaboratory
上記にアクセス(Googleアカウントにログインする必要あり)するだけで、Jupyter Notebookが使えてしまいます。
(無料!)

基本的なコマンド

多分知っておいたほうがいいのが下記のコマンドです
%cd
!pip

ほんとに簡単に使えてしまうので、とりあえずアクセスしてみるのが早いと思います。
あとは、こちらの記事がとても分かりやすかったのでリンクさせてもらいます。

【秒速で無料GPUを使う】深層学習実践Tips on Colaboratory

2.OpenCVの使い方

まずは、画像の読み込みから


# -------------------------------------------------------------------
# まずは画像の読み込みと表示
# -------------------------------------------------------------------

img = cv2.imread('s.jpg')
# opencvではBGRで読み込みされるため、matplotlibようにRGBに変換
# cv2.imshowならBGRで表示できる
im_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# opencvなら、cv2.imshowで表示できる
plt.imshow(im_rgb)
plt.show()

読み込んだ画像を処理して輪郭を取得します


# -------------------------------------------------------------------
# 輪郭の取得
# -------------------------------------------------------------------
# 輪郭を取得するため、グレースケール化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 黒白反転→輪郭を取得するために背景を白くする。外側が黒だと輪郭を取得しないため
gray = cv2.bitwise_not(gray, gray)

# 輪郭を取得しやすくするために二値化
ret,thresh = cv2.threshold(gray,80,255,0)


# 輪郭の頂点の数が最大のものを最大の輪郭として採用している
def index_emax(cnt):
    max_num = 0
    max_i = -1
    for i in range(len(cnt)):
        cnt_num=len(cnt[i])
        # print(cnt_num)
        if cnt_num > max_num:
            max_num = cnt_num
            max_i = i
    return max_i


# 輪郭の取得
img_c, cnt, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
n = index_emax(cnt)


if n != -1 and len(cnt) > 0:
    for i in range(len(cnt)):
        # 凸包の作成
        hull = cv2.convexHull(cnt[i])
        x,y,w,h = cv2.boundingRect(hull)
       # 輪郭の描画
        cv2.drawContours(img, [hull], 0, (0,255,0), 2)

im_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(im_rgb)

findContoursで輪郭を取得するのですが、入力画像を『8UC1 format』にする必要があります。
要は、グレースケールのことです。

今回、グレースケールにしたものを二値化しているのは、差をはっきりさせて輪郭を取得しやすくしたかったからです。
どういった輪郭を取得したいか?という目的で、画像の前処理がいろいろ変わってくることになります。

そのあたりは今後色々書いていきたいと思っています。

パラメータなど細かく色々調べたい方はこちらも確認してください。
画像の輪郭取得について(OpenCVチュートリアル)

サンプルはgithubにおいてます
Claboでサクッと動かせるので、実際に動かしてみてください。
サンプルの画像もgithubに置いてあります。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2