【OpenCV】ツムを判別する方法2

Uncategorized
481 words

前回 ツムを判別する方法に、ハフ変換を使って円を検出しました。

今回はハフ変換で見つけたツムを、識別してグループ化していきます。

処理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import cv2
import numpy
import math

def main():

img = cv2.imread('IMG_0941.png')
img = img[300: 900, 0: 554]

circles = GetHoughCircles(img)
averaging = GetAveraging(img, circles)

# 描画
for item in averaging:
cv2.circle(img, (item['x'], item['y']), item['radius'], (item['blue'], item['green'], item['red']), thickness=-1)
cv2.putText(img, str(item['index']), (item['x']-10, item['y']+12), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), thickness=2)

cv2.imshow('detected circles', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

def GetHoughCircles(img):
cimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
circles = cv2.HoughCircles(cimg, cv2.HOUGH_GRADIENT, 1.2, 30, param1=100, param2=40, minRadius=20, maxRadius=54)
circles = numpy.uint16(numpy.around(circles))
return circles

def GetAveraging(img, circles):
average = []

for i in circles[0, :]:
# img[top : bottom, left : right]
imgcrop = img[i[1]-2: i[1]+2, i[0]-2: i[0]+2]
imgblur = cv2.blur(imgcrop, (10, 10))

b = math.floor(imgblur.T[0].flatten().mean() * 0.1) * 10
g = math.floor(imgblur.T[1].flatten().mean() * 0.1) * 10
r = math.floor(imgblur.T[2].flatten().mean() * 0.1) * 10

average.append({"blue": b, "green": g, "red": r, 'x': i[0], 'y': i[1], 'radius': i[2]})

SetGrouping(average)

return average

def SetGrouping(averaging):

group = []
for average in averaging:
isOK = False
idx = 0

# 初回
if len(group) <= 0:
average['index'] = idx
group.append(average)

for item in group:

if item['blue'] - 10 <= average['blue'] and average['blue'] <= item['blue'] + 10 and item['green'] - 10 <= average['green'] and average['green'] <= item['green'] + 10 and item['red'] - 10 <= average['red'] and average['red'] <= item['red'] + 10:

isOK = True
average['index'] = item['index']
break

if not isOK:
idx = len(group)
average['index'] = idx
group.append(average)

return

if __name__ == '__main__':
main()

使った機能

画像のぼかし (平滑化)

cv2.blur() を使ってツムにぼかしを入れてから、円の中心の色を取得しています。精度を上げたかったので、下一桁を切り捨ててからグループ化処理をしました。

グループ化処理では、ある程度似た色を1つのグループとするようにしています。まったく同じ色ってのは、難しかったのでここは調整が必要ですね。

終わりに

後は、最短経路をつなぐアルゴリズムですかね。