前回 ツムを判別する方法に、ハフ変換を使って円を検出しました。
今回はハフ変換で見つけたツムを、識別してグループ化していきます。
処理
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つのグループとするようにしています。まったく同じ色ってのは、難しかったのでここは調整が必要ですね。
終わりに
後は、最短経路をつなぐアルゴリズムですかね。