目的
https://dailyportalz.jp/kiji/shibuya-nobodify
ここの記事のプログラムを実装してみよう
準備
pythonで実装しようと思うので、anacondaにopencv3をインストール
アルゴリズム
定点撮影した写真を準備する。この写真を順番に読みだして、前のn個の写真と画素ごとに比較してもっとも頻度の高い画素に置き換える。
置き換え方法としては、平均、中央値、最頻などが考えられたが中央値を採用する
プログラム
激重プログラムなのでもっと改善が必要ですがなんとか動いたものができた
import cv2
import glob
import statistics
import numpy as np
class PHOTO_REMOVE():
"""description
写真で背景のみ抽出する
"""
output_file = "./output.mp4"
hist = 10
is_First = True
stack_index = 0
read_img_count = 0
def __init__(self,param=None):
"""
初期化
hist : 背景判定を何フレームで行うか?
path : 写真があるフォルダのパス
"""
if param != None:
self.hist = param["hist"]
self.set_photo_file(param["path"])
else:
self.set_photo_file("./sample")
self.set_output_video(self.output_file)
self.image_stack = [None for _ in range(self.hist)]
print(len(self.image_stack))
def run(self):
self.read_jpg_files(self.path)
def main_analize(self,image):
print("test")
def set_photo_file(self,name):
self.is_photo = True
self.is_video = False
self.path = glob.glob('{}/*.JPG'.format(name))
self.file_num = len(self.path)
#print(self.path)
def read_jpg_files(self,files):
self.fill_stack_data(files)
self.img_height, self.img_width, self.img_channels = cv2.resize(cv2.imread(files[0]),(640,480)).shape[:3]
print(self.img_height, self.img_width, self.img_channels)
#for img in cv2.resize(cv2.imread(files[0]),(640,480)):
# for rgb in img:
# print(rgb)
for f in files:
img = cv2.imread(f)
img = cv2.resize(img, (640,480))
self.read_img_count = self.read_img_count + 1
print("FRAME {0}番目".format(self.read_img_count))
ret_img = self.photo_remove(img)
cv2.imshow("frame",ret_img)
self.make_output_video(ret_img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
self.output_video.release()
def set_output_video(self,name):
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
self.output_video = cv2.VideoWriter(name,fourcc, 2.0, (640,480))
def make_output_video(self,img):
self.output_video.write(img)
def fill_stack_data(self,files):
for i in range(self.hist-1):
self.image_stack[i] = cv2.resize(cv2.imread(files[i]), (640,480))
def photo_remove(self,img):
ret_img = img
self.image_stack[self.stack_index] = img
if self.stack_index == self.hist-1:
self.stack_index = 0
else:
self.stack_index = self.stack_index + 1
for h in range(self.img_height-1):
for w in range(self.img_width-1):
tmp = []
for i in range(self.hist-1):
tmp.append(np.linalg.norm(self.image_stack[i][h,w]))
#tmp.append(self.image_stack[i][h,w])
median = statistics.median(tmp)
for i in range(self.hist-1):
if median == tmp[i]:
ret_img[h,w] = self.image_stack[i][h,w]
break
return ret_img
if __name__ == "__main__":
test_obj = PHOTO_REMOVE()
test_obj.run()
追記
中央値を採用するアルゴリズムだとじわじわ消すことはできないので件名に偽りあり。