デイリーポータルZの渋谷の交差点から人をじわじわ消すプログラムを書いてみた

# 目的
https://dailyportalz.jp/kiji/shibuya-nobodify
ここの記事のプログラムを実装してみよう

# 準備
pythonで実装しようと思うので、anacondaにopencv3をインストール

# アルゴリズム
定点撮影した写真を準備する。この写真を順番に読みだして、前のn個の写真と画素ごとに比較してもっとも頻度の高い画素に置き換える。
置き換え方法としては、平均、中央値、最頻などが考えられたが中央値を採用する

# プログラム
激重プログラムなのでもっと改善が必要ですがなんとか動いたものができた


```py
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()

```

追記
中央値を採用するアルゴリズムだとじわじわ消すことはできないので件名に偽りあり。