LoginSignup
4
4

More than 5 years have passed since last update.

OpenCVでドロップ認識 -課題2-

Last updated at Posted at 2019-01-14

前書き

OpenCVの開発環境は作ったので、実際になにか動かしてみます。
今回はOpenCV-Pythonのチュートリアル、OpenCV-Python Tutorials日本語版をやっていきます。
多少アレンジすると思う。

物体認識をやっていきたいので、とりあえず簡単なところから練習していきます。
今回は「丸ドロップが別物として認識する(5パターン:6×5盤面)」をやっていきます。

シリーズ

開発環境

機種名 : MacBook Pro
OS : Mojave 10.14.2
プロセッサ名 : Intel Core i5 2.6 GHz
メモリ : 16 GB
グラフィック : Intel Iris 1536MB

python系

% pip freeze
numpy==1.15.4
opencv-python==4.0.0.21

画像データ

今回はこの画像を使っていきます。

IMG_0451.PNG

本題

画面下部のそれぞれのドロップを認識することを目標とします。
5色を別物として認識したい。

課題

  1. 丸ドロップと四角ドロップを別物として認識する(2パターン:6×5盤面)
  2. 丸ドロップが別物として認識する(5パターン:6×5盤面):今回やるやつ
  3. 5×4盤面、6×5盤面、7×6盤面で認識する(2019/02/03 追記:しばらく手をつけられないかも)

丸ドロップが別物として認識する(5パターン:6×5盤面)

Watershedアルゴリズムを使った画像の領域分割このあたりのやり方を参考になにかできるんじゃないかと思っているんだけど、、、、。

sample.py
    img = cv2.imread('6_5.PNG')
    img = getBoard(img)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    cv2.imshow('thresh', thresh)
    cv2.imwrite('thresh.png', thresh)

    # ノイズ除去
    kernel = np.ones((3, 3), np.uint8)
    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
    cv2.imshow('opening', opening)
    cv2.imwrite('opening.png', opening)

    # 背景 確信領域
    sure_bg = cv2.dilate(opening, kernel, iterations=3)
    cv2.imshow('sure_bg', sure_bg)
    cv2.imwrite('sure_bg.png', sure_bg)

    # 前景 確信領域
    dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
    ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)
    cv2.imshow('sure_fg', sure_fg)
    cv2.imwrite('sure_fg.png', sure_fg)

    # 未知の領域
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg, sure_fg)
    cv2.imshow('unknown', unknown)
    cv2.imwrite('unknown.png', unknown)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

大津の二値化
thresh.png

ノイズ除去後
opening.png

背景 確信領域
sure_bg.png

前面 確信領域
sure_fg.png

未知領域
unknown.png

んーなかなか思ったように行きません。

色狙い撃ちで取り出してみる

「pythonで赤い物体を認識しよう」を参考に、特定色だけ狙い撃ちでピックアップしてみる。

  1. 特定色をピックアップ
  2. その色だけうまく輪郭抽出
  3. 前回の手法で、特定色のドロップに縁つけて特定してみる。

特定色をピックアップしてみる

red.png

赤ドロップ結構大きく捉えてくれてるけど、背景色だったり、回復ドロップだったりにも反応していまいちうまく取り出せてない。

輪郭抽出、特定

sample.py
    img = cv2.imread('6_5.PNG')
    img = getBoard(img)
    # 円形取得
    circles = houghCircles(img)
    # 矩形取得
    rects = find_rect_of_target_color(img)

    for i in circles[0, :]:
        for rect in rects:
            # cv2.rectangle(img, tuple(rect[0:2]), tuple(rect[0:2] + rect[2:4]), (0, 0, 255), thickness=2)
            # cv2.circle(img, (i[0], i[1]), 2, (0, 255, 0), -1)

            x1, y1 = tuple(rect[0:2])
            x2, y2 = tuple(rect[0:2] + rect[2:4])
            polygon = np.array([[x1, y1], [x1, y2], [x2, y1], [x2, y2]])
            # 矩形の内側に円の中心点が含まれている場合
            if cv2.pointPolygonTest(polygon, (i[0], i[1]), False) >= 0:
                cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
                cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), thickness=2)
                print((i[0], i[1]), (x1, y1), (x2, y2))

    cv2.imshow('red', img)
    cv2.imwrite('red.png', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

red.png

紫が取れてる。ただ、全部の紫が取得されているわけではないのよね。
難しい。
あとは、色指定がうまく行けば対象の特定ができそう。

後日やりますーー

多分、色相をいい感じに定義してあげればうまくいくと思うので時間あるときにまた調整します。

感想

なかなか画像処理は、奥が深く思ったように欲しいデータ取ることができないな。
もう少しやってればなれてきてイメージ通りに切り抜いたり、複雑な形扱ったりもできるかな。

4
4
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
4