課題1について
シールの色は決まっているので、単純が画像処理でいいと思います。
2値化する。
python
1import cv2
2import matplotlib.pyplot as plt
3from matplotlib.patches import Polygon
4
5img = cv2.imread('image1.jpg') # 画像を読み込む。
6
7# 色基準で2値化する。
8hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # HSV 色空間に変換
9
10red = cv2.inRange(hsv, np.array([145, 70, 0]), np.array([180, 255, 255]))
11yellow = cv2.inRange(hsv, np.array([10, 80, 0]), np.array([50, 255, 255]))
12green = cv2.inRange(hsv, np.array([30, 190, 0]), np.array([90, 255, 255]))
13blue = cv2.inRange(hsv, np.array([108, 121, 0]), np.array([120, 255, 255]))
14white = cv2.inRange(hsv, np.array([108, 21, 0]), np.array([255, 70, 255]))
15
16# 白だけゴミがあるので、収縮演算
17kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
18white = cv2.erode(white, kernel)
19
20
21bin_imgs = {'red': red, 'yellow': yellow, 'green': green,
22 'blue': blue, 'white': white}
23
24# 2値化結果を可視化する。
25####################################################
26fig, axes_list = plt.subplots(2, 3, figsize=(10, 6))
27axes_list[1, 2].remove()
28for ax, (label, bin_img) in zip(axes_list.ravel(), bin_imgs.items()):
29 ax.axis('off')
30 ax.set_title(label)
31 ax.imshow(bin_img, cmap=plt.cm.gray)
32plt.show()
輪郭抽出して、輪郭の数を数える。
python
1fig, ax = plt.subplots(figsize=(8, 5))
2ax.axis('off')
3ax.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
4
5# 輪郭検出し、数を求める。
6##############################################
7for label, bin_img in bin_imgs.items():
8 _, contours, _ = cv2.findContours(
9 bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
10 # 輪郭を構成する頂点数で誤検出を除く。
11 contours = list(filter(lambda cnt: len(cnt) > 30, contours))
12 count = len(contours)
13
14 print('color: {}, conunt: {}'.format(label, count))
15
16 # 描画する。
17 for cnt in contours:
18 cnt = np.squeeze(cnt, axis=1) # (N, 1, 2) -> (N, 2)
19 ax.add_patch(Polygon(cnt, fill=None, lw=2., color=label))
20plt.show()
OUTPUT
1color: green, conunt: 3
2color: blue, conunt: 3
3color: red, conunt: 4
4color: white, conunt: 3
5color: yellow, conunt: 3
課題2について
2.1.の静止画でシールを貼ってある対象の太さを知りたい(画像はシールを貼ってあるものと仮定する)
配管に貼ってあるシールで大きさを決めるということでしょうか?
それとも、配管の太さは別途検出するということでしょうか。
後者の場合、撮影する距離が固定とか限定された条件がない限り、画像からは実際のスケールはわからないので無理です。
追記
CNN で物体の検出、分類を行う場合、以下のアプローチがあります。
- クラス分類: 与えた画像からクラスを分類する。
- 物体検出: 与えた画像から物体の位置及びクラスを矩形で検出する。
- Semantic Segmentation: 与えた画像から物体の位置及びクラスをピクセル単位で分類する。
- Instance Segmentation: 与えた画像から物体の位置及びインスタンスをピクセル単位で分類する。(同じクラスの物体が複数写っている場合、それぞれ区別する。)
難易度としては後者ほど難しくなります。
また物体検出や Segmentation は、大量の画像に対して人手でアノテーションを行わないといけないので、データセット作成にかなり労力がかかります。
引用元 Semantic segmentation2
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/10/03 00:45
2018/10/03 04:52 編集
2018/10/05 02:39
2018/10/05 03:12
2018/10/05 05:03