こんにちは、ぱそきいろです。
OpenCVで遊んでたら、「画像から星座を生成できるのでは?」と思い、実装してみました。
よろしくお願いします。
星座を作る方法
輪郭検出
まずは画像の輪郭を検出します。
ここら辺を参考にしてコードを書いていきます。
輪郭: 初めの一歩 — OpenCV-Python Tutorials 1 documentation
オブジェクト輪郭検出 | OpenCV / findContours を使用して画像中のオブジェクトの輪郭を検出する方法
こんな感じで輪郭が検出されました。
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にした画像
1/50にした点を線で繋いだ画像
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)
できたもの
実際に星座を作った画像を載せます。
成功例と失敗例があります。
成功例
餃子(ぎょう座)
便座(べん座)
土下座(どげ座)
失敗例
フリーザ(ふりー座)
輪郭の線が多すぎて、分かりにくい星座になってしまった。。。
ヤクザ(やく座)
顔のあたりがうまく星座で表せなかった。。。
まとめ
そこまで時間を掛けずに実装できたので楽しかったです。
線が多い画像でうまく星座を作る方法を考えないとなぁ。。。