ぱそきいろのIT日記

ぱそきいろがITに関する記事を書いていきます。

Python + OpenCV で星座を作るプログラム

こんにちは、ぱそきいろです。

OpenCVで遊んでたら、「画像から星座を生成できるのでは?」と思い、実装してみました。
よろしくお願いします。

星座を作る方法

輪郭検出

まずは画像の輪郭を検出します。
ここら辺を参考にしてコードを書いていきます。
輪郭: 初めの一歩 — OpenCV-Python Tutorials 1 documentation

オブジェクト輪郭検出 | OpenCV / findContours を使用して画像中のオブジェクトの輪郭を検出する方法

こんな感じで輪郭が検出されました。
f:id:takabsk55:20200513113017j:plain:h240

import cv2
import numpy as np

inputname="gyouza.jpg"

im = cv2.imread(f'./image/{inputname}')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,170,255,0)
cv2.imwrite("output/temp.jpg",thresh)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
星座の描画

このままだと星座にならないので、点の数を減らして線でつなぎます。
流れとしては、点を1/50に減らして、残った点を線で結ぶといった感じです。

点の数を1/50にした画像
f:id:takabsk55:20200513113236j:plain:h240

1/50にした点を線で繋いだ画像
f:id:takabsk55:20200513113318j:plain:h240

shapetemp=im.shape

# 背景
height = shapetemp[0]
width = shapetemp[1]
blank = np.zeros((height, width, 3))

for i in range(0, len(contours)):
    if len(contours[i]) > 0:

        # remove small objects
        if cv2.contourArea(contours[i]) < 500:
            continue
        prex,prey=contours[i][0][0][0],contours[i][0][0][1]
        startx,starty=contours[i][0][0][0],contours[i][0][0][1]

        for j in range(0,len(contours[i]),50): #点の数を1/50にする
            cv2.circle(blank,(contours[i][j][0][0],contours[i][j][0][1]),5,(255,255,255),-1)
            cv2.line(blank,(contours[i][j][0][0],contours[i][j][0][1]),(prex,prey),(255,255,255),1)
            prex=contours[i][j][0][0]
            prey=contours[i][j][0][1]

        cv2.line(blank,  (prex, prey),(startx,starty), (255, 255, 255), 1)

# save
cv2.imwrite(f'output/{inputname}', blank)

できたもの

実際に星座を作った画像を載せます。
成功例と失敗例があります。

成功例

餃子(ぎょう座)
f:id:takabsk55:20200509170753p:plain:h240

便座(べん座)
f:id:takabsk55:20200509170806p:plain:h240

土下座(どげ座)
f:id:takabsk55:20200509170810p:plain:h240

失敗例

フリーザ(ふりー座)
輪郭の線が多すぎて、分かりにくい星座になってしまった。。。
f:id:takabsk55:20200509170820p:plain:h240

ヤクザ(やく座)
顔のあたりがうまく星座で表せなかった。。。
f:id:takabsk55:20200509170823p:plain:h240

まとめ

そこまで時間を掛けずに実装できたので楽しかったです。
線が多い画像でうまく星座を作る方法を考えないとなぁ。。。