ステーキ定食の画像から物体を選別できないかやってみた - ②オーバーラップ数選別編

# はじめに
[前回](http://qiita.com/neriai/items/d420b78f35033408ccda)、Selective Searchを使ってステーキ定食の画像の物体検出を行いました。確かに精度は上がったものの、約50毎の画像の内、ゴミのような画像、同じ画像（若干切り抜き位置が違う）、必要な物体画像の約３種類に分類されていることに気づきました。今回は、その中から必要な物体画像のみを選別できないかをやってみようと思います。

# 仮説
画像から物体抽出する際にオーバラップの数が多い画像こそ必要な物体画像ではないか。と言いながらも、実は親子関係の矩形の子の部分を除けないかといったものです。

## こいつは何を言っているんだ

ようするに画像から物体検出をする際に、矩形で抽出してますが、矩形同士が混ざりあった部分をオーバラップと呼んでいます。
下記の画像の赤い部分です。

![overlap.png](https://qiita-image-store.s3.amazonaws.com/0/90598/9e352019-a36f-f9d7-2f45-65863dbc2655.png)

## 参考元

- (たのしい当たり判定講座１　-矩形同士の当たり判定(初級編)-)[http://d.hatena.ne.jp/ono36/20070718/p1]

## ソースコード

とりあえず書いてみました。

```py:group_image
# -*- coding: utf-8 -*-

import cv2
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import selectivesearch
import os

def main():
    # loading lena image
    img = cv2.imread("{ステーキ定食画像}")

    # perform selective search
    img_lbl, regions = selectivesearch.selective_search(
        img,
        scale=500,
        sigma=0.9,
        min_size=10
    )

    candidates = set()

    for r in regions:
        # excluding same rectangle (with different segments)
        if r['rect'] in candidates:
            continue

        # excluding regions smaller than 2000 pixels
        if r['size'] < 2000:
            continue

        # distorted rects
        x, y, w, h = r['rect']

        if w / h > 1.2 or h / w > 1.2:
            continue

        candidates.add(r['rect'])

    # draw rectangles on the original image
    fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
    ax.imshow(img)

    overlaps = {}

    # オーバーラップの数をカウントして配列に代入します。
    for x, y, w, h in candidates:
        group = '%s_%s_%s_%s' % (x, y, w, h)

        for x2, y2, w2, h2 in candidates:
            if x2 - w < x < x2 + w2 and y2 - h < y < y2 + h2:

                if not group in overlaps:
                    overlaps[group] = 0

                overlaps[group] = overlaps[group] + 1

    print overlaps

    # オーバーラップの数が30以上のファイルを出力します（30は勝手に閾値を敷いています）。
    for key, overlap in enumerate(overlaps):
        if overlap > 30:
            for x, y, w, h in candidates:
                group = x + y + w + h

                if group in overlaps:
                    cv2.imwrite("{ディレクトリパス}" + str(group) + '.jpg', img[y:y + h, x:x + w])
```

## 補足

- 物体検出した画像とオーバーラップしているかどうかを判定します。

```py
if x2 - w < x < x2 + w2 and y2 - h < y < y2 + h2:
```

- オーバーラップの数が30以上の抽出結果のみ画像として保存します。

# 結果

（元）50枚　→　36枚

ステーキ定食の画像の中で約3割くらい不要なものが除かれました。

また、[前回](http://qiita.com/neriai/items/d420b78f35033408ccda)の5種類の物体画像が5種類ともの残ってました。

# まとめ

- 今回、検証画像が1種類なので少し調整と結果判定を寄せてますので、他の画像で試してみるとまた異なった結果になってくるかもしれません。
- 次回はクラスタリングちっくな事をできればと思ってます。
- 
# 全ページリンク
- [PythonとOpenCVを使って物体検出をやってみた](http://qiita.com/neriai/items/448a36992e308f4cabe2)
- [ステーキ定食の画像から物体を選別できないかやってみた - ①物体検出編](http://qiita.com/neriai/items/d420b78f35033408ccda)
- [ステーキ定食の画像から物体を選別できないかやってみた - ②オーバーラップ数選別編](http://qiita.com/neriai/items/e718290e8b14b0594008)
- [ステーキ定食の画像から物体を選別できないかやってみた - ③類似画像ヒートマップ検出編](http://qiita.com/neriai/items/615c9233582a91a1396a)
- [ステーキ定食の画像から物体を選別できないかやってみた - ④クラスタリング編](http://qiita.com/neriai/items/6df233918513a51a7147)
- [ステーキ定食の画像から物体を選別できないかやってみた - ⑤類似画像特徴点検出編](http://qiita.com/neriai/items/e96d70fc3b89f050daa5)