Diff of /mpg2png.py [000000] .. [76022b]

Switch to unified view

a b/mpg2png.py
1
import os, datetime, glob, re
2
import cv2
3
import numpy as np
4
import pandas as pd
5
import csv
6
import sys
7
8
#RAPIDから保存した小腸カプセル内視鏡動画(mpg)を画像(png)にして保存
9
#   ※simplemain()を実行するとできる
10
11
def matching(x, y, image, num):
12
    '''
13
    パターンマッチングの実行
14
    '''
15
    w = 17
16
    h = 24
17
    _time = 0
18
    try:
19
        for i in range(10, -1, -9):
20
            img = image[y:y+h, x:x+w]
21
            mat = []
22
            for n in num:
23
                match_result = cv2.matchTemplate(img, n, cv2.TM_CCOEFF_NORMED)
24
                mat.append(match_result.max())
25
            t = np.argmax(mat)
26
            _time += t*i
27
            x += 17
28
    except Exception as e:
29
        print(f'numbers/0~9.pngが見つかりません。CE画像の時間読み取り用の0~9.pngをnumbersフォルダに入れて適切に配置してください。\nエラー内容:{e}')
30
        sys.exit()
31
    return _time
32
33
def readtime(img):
34
    '''
35
    パターンマッチングによりCE画像の時刻を読み取る
36
    '''
37
    _time = []
38
    x = 5
39
    y = 7
40
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
41
    numpath = glob.glob('./numbers/*.png')
42
    num = []
43
    for path in numpath:
44
        n = cv2.imread(path)
45
        n = cv2.cvtColor(n, cv2.COLOR_BGR2GRAY)
46
        num.append(n)
47
48
    for i in range(3):
49
        t = matching(x, y, img, num)
50
        _time.append(t)
51
        x += 44
52
53
    return _time[0], _time[1], _time[2]
54
55
def fiximg(img, mask):
56
    '''
57
    画像を512×512にして淵の白文字を黒くする
58
    '''
59
    return img[32:-32, 32:-32, :]*mask
60
61
def mpg2png(movpath, folder, img_save, inp_save, imgpath=None, inppath=None):
62
    '''
63
    動画を画像にして保存
64
    (画像名:CE画像の時間で保存、時間が重複している場合は、名前の最後が"_00""_01"などになる)
65
    '''
66
    if inp_save:
67
        try:
68
            mask = cv2.imread('./mask.png')
69
            mask = np.where(mask < 100, 0, 1)
70
        except Exception as e:
71
            print(f'mask.pngが見つかりません。CE画像の名前や時間を黒塗りするためのmask.pngが読み込めませんでした。パスを確認してください。\nエラー内容:{e}')
72
            sys.exit()
73
    hours = []
74
    minute = []
75
    second = []
76
    total_second = []
77
    i = 0
78
    tmp = None
79
    tmps = 0
80
    cap = cv2.VideoCapture(movpath)
81
    if(cap.isOpened()):
82
        ret, frame = cap.read()
83
        while(ret):#画像枚数分ループ
84
            if(i%5 == 0):#CE動画は5枚連続で同じ画像のため5回に一回保存
85
                h, m, s = readtime(frame)
86
                hours.append(h)
87
                minute.append(m)
88
                second.append(s)
89
                ts = h*3600 + m*60 + s
90
                total_second.append(ts)
91
92
                if (ts < tmps):
93
                    print(f'failed pattern matching.CE画像から時刻の読み取りに失敗しました。')
94
                    sys.exit()
95
96
                ce_time = '{0:02}{1:02}{2:02}'.format(h, m, s)
97
                if(ce_time == tmp):
98
                    n += 1
99
                else:
100
                    n = 0
101
                if img_save:
102
                    cv2.imwrite(os.path.join(imgpath, ce_time + '_{:02}.png'.format(n)), frame)
103
                if inp_save:
104
                    frame = fiximg(frame, mask)
105
                    cv2.imwrite(os.path.join(inppath, ce_time + '_{:02}.png'.format(n)), frame)
106
                tmp = ce_time
107
                tmps = ts
108
            i += 1
109
            ret, frame = cap.read()
110
    cap.release()
111
    cv2.destroyAllWindows()
112
113
    if img_save or inp_save:
114
        #各画像に書かれている内視鏡の時間をcsvに保存
115
        df = pd.DataFrame({'Hours': hours, 'Minute': minute, 'Second': second, 'Total_Second': total_second})
116
        df.to_csv(os.path.join(folder, 'time.csv'))
117
118
def simplemain(mpg_paths='./mpg', out_path='./output', img_save=True, inp_save=True):
119
    '''
120
    PillCamSB3動画(COLON2非対応)を画像に変換(mpg2pngの実行)と保存するフォルダを生成
121
    (元画像保存先:out_path/現在の時刻/動画の名前/image/*.png)
122
    (トリミング後画像保存先:out_path/現在の時刻/動画の名前/input_image/*.png)
123
    ※time.csvに各画像の時間を書き込む
124
    args
125
    mpg_paths:動画を含むフォルダ
126
    out_path:動画を画像変換後の保存先
127
    img_save:動画を画像変換後に保存するか
128
    inp_save:動画を画像変換後にトリミングと白塗りして保存するか
129
    '''
130
    mpgpaths = glob.glob(f'{mpg_paths}/*')
131
    mpgpaths = sorted([p for p in mpgpaths if re.search('/*\.(avi|mp4|mov|mpg|wmv|flv)', str(p))])
132
    if len(mpgpaths)==0:
133
        print(f'読み込んだ動画{len(mpgpaths)}本。動画が読み込まれていません。パスの確認やフォルダ名とファイル名に日本語を含まないようにしてください。')
134
        sys.exit()
135
    print(f'確認(動画数{len(mpgpaths)}。{mpgpaths}\n以上の動画を画像にして保存します。')
136
    outpath = os.path.join(out_path, datetime.datetime.now().strftime('%Y%m%d_%H%M%S'))
137
    imgpath, inppath = None, None
138
    for mpgpath in mpgpaths:
139
        mpgname = os.path.splitext(os.path.basename(mpgpath))[0]
140
        path = os.path.join(outpath, mpgname)
141
        if img_save:
142
            imgpath = os.path.join(outpath, mpgname, 'image')
143
            os.makedirs(imgpath, exist_ok=True)
144
        if inp_save:
145
            inppath = os.path.join(outpath, mpgname, 'input_image')
146
            os.makedirs(inppath, exist_ok=True)
147
148
        mpg2png(mpgpath, path, img_save, inp_save, imgpath=imgpath, inppath=inppath)
149
150
if __name__ == '__main__':
151
    simplemain(mpg_paths='./mpg', out_path='./output', img_save=True, inp_save=True)
152
    #※mask/pngとnumbers/0から9まで.pngを適切に配置する
153
    #引数
154
    #mpg_paths:動画を含むフォルダ
155
    #out_path:動画を画像変換後の保存先
156
    #img_save:動画を画像変換後に保存するか
157
    #inp_save:動画を画像変換後にトリミングと白塗りして保存するか