Spaces:
Sleeping
Sleeping
Merge pull request #7 from umyuu/feature/0.0.6
Browse files- .vscode/settings.json +1 -0
- app.py +2 -3
- config.json +42 -0
- src/__init__.py +47 -0
- src/myapp.py +12 -15
- src/reporter.py +25 -31
- src/saliency.py +1 -1
- src/utils.py +2 -2
.vscode/settings.json
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
{
|
2 |
"cSpell.words": [
|
|
|
3 |
"astype",
|
4 |
"dtype",
|
5 |
"fromarray",
|
|
|
1 |
{
|
2 |
"cSpell.words": [
|
3 |
+
"asctime",
|
4 |
"astype",
|
5 |
"dtype",
|
6 |
"fromarray",
|
app.py
CHANGED
@@ -4,10 +4,9 @@
|
|
4 |
"""
|
5 |
from argparse import ArgumentParser, BooleanOptionalAction
|
6 |
|
7 |
-
from src
|
8 |
from src.myapp import run_app
|
9 |
|
10 |
-
PROGRAM_NAME = 'SaliencyMapDemo'
|
11 |
__version__ = get_package_version()
|
12 |
|
13 |
|
@@ -17,7 +16,7 @@ def main():
|
|
17 |
1, コマンドライン引数の解析を行います
|
18 |
2, アプリを起動します。
|
19 |
"""
|
20 |
-
parser = ArgumentParser(prog=PROGRAM_NAME, description=
|
21 |
parser.add_argument('--inbrowser',
|
22 |
action=BooleanOptionalAction, default=True, help="Gradio inbrowser")
|
23 |
parser.add_argument('--share',
|
|
|
4 |
"""
|
5 |
from argparse import ArgumentParser, BooleanOptionalAction
|
6 |
|
7 |
+
from src import PROGRAM_NAME, get_package_version
|
8 |
from src.myapp import run_app
|
9 |
|
|
|
10 |
__version__ = get_package_version()
|
11 |
|
12 |
|
|
|
16 |
1, コマンドライン引数の解析を行います
|
17 |
2, アプリを起動します。
|
18 |
"""
|
19 |
+
parser = ArgumentParser(prog=PROGRAM_NAME, description=PROGRAM_NAME)
|
20 |
parser.add_argument('--inbrowser',
|
21 |
action=BooleanOptionalAction, default=True, help="Gradio inbrowser")
|
22 |
parser.add_argument('--share',
|
config.json
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"version": 1,
|
3 |
+
"disable_existing_loggers": false,
|
4 |
+
"formatters": {
|
5 |
+
"iso8601": {
|
6 |
+
"format": "%(asctime)s%(message)s",
|
7 |
+
"datefmt": "%Y-%m-%dT%H:%M:%S%z"
|
8 |
+
},
|
9 |
+
"jst": {
|
10 |
+
"()": "src.LocalTimeFormatter",
|
11 |
+
"fmt": "%(asctime)s%(message)s",
|
12 |
+
"datefmt": "%Y-%m-%dT%H:%M:%S.%03f%z",
|
13 |
+
"." :{
|
14 |
+
"time_zone": "Asia/Tokyo"
|
15 |
+
}
|
16 |
+
},
|
17 |
+
"utc": {
|
18 |
+
"()": "src.LocalTimeFormatter",
|
19 |
+
"fmt": "%(asctime)s%(message)s",
|
20 |
+
"datefmt": "%Y-%m-%dT%H:%M:%S.%03f%z",
|
21 |
+
"." :{
|
22 |
+
"time_zone": "GMT"
|
23 |
+
}
|
24 |
+
}
|
25 |
+
},
|
26 |
+
"handlers": {
|
27 |
+
"console1": {
|
28 |
+
"class": "logging.StreamHandler",
|
29 |
+
"level": "DEBUG",
|
30 |
+
"formatter": "jst"
|
31 |
+
}
|
32 |
+
},
|
33 |
+
"loggers": {
|
34 |
+
"SaliencyMapDemo": {
|
35 |
+
"level": "DEBUG",
|
36 |
+
"handlers": ["console1"]
|
37 |
+
}
|
38 |
+
},
|
39 |
+
"root": {
|
40 |
+
"level": "DEBUG"
|
41 |
+
}
|
42 |
+
}
|
src/__init__.py
CHANGED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
"""src Module"""
|
3 |
+
from datetime import datetime
|
4 |
+
import logging.config
|
5 |
+
import re
|
6 |
+
from zoneinfo import ZoneInfo
|
7 |
+
|
8 |
+
from src.utils import get_package_version
|
9 |
+
|
10 |
+
__all__ = ["LocalTimeFormatter"]
|
11 |
+
|
12 |
+
PROGRAM_NAME = 'SaliencyMapDemo'
|
13 |
+
__version__ = get_package_version()
|
14 |
+
|
15 |
+
|
16 |
+
class LocalTimeFormatter(logging.Formatter):
|
17 |
+
"""
|
18 |
+
ログの時刻表示を指定したタイムゾーンに変換するクラス。
|
19 |
+
"""
|
20 |
+
time_zone: str = "GMT"
|
21 |
+
pattern = re.compile(r"([\.|,]\%\d{1,}f)(\%z)?", re.IGNORECASE)
|
22 |
+
"""
|
23 |
+
%Y-%m-%dT%H:%M:%S.%03f
|
24 |
+
%Y-%m-%dT%H:%M:%S.%03f%z
|
25 |
+
"""
|
26 |
+
def formatTime(self, record, datefmt=None):
|
27 |
+
dt = datetime.fromtimestamp(
|
28 |
+
record.created,
|
29 |
+
ZoneInfo(self.time_zone)
|
30 |
+
)
|
31 |
+
|
32 |
+
if datefmt is None:
|
33 |
+
s = dt.strftime(self.default_time_format)
|
34 |
+
return s
|
35 |
+
|
36 |
+
t = dt.strftime(re.sub(self.pattern, "", datefmt))
|
37 |
+
match = re.search(self.pattern, datefmt)
|
38 |
+
if not match:
|
39 |
+
return t
|
40 |
+
|
41 |
+
groups = match.groups()
|
42 |
+
msec_format = groups[0] if groups[0] else ""
|
43 |
+
time_zone_format = groups[1] if groups[1] else ""
|
44 |
+
time_zone_str = dt.strftime(time_zone_format)
|
45 |
+
msec_format = msec_format.replace("f", "d")
|
46 |
+
s = f"{t}{msec_format % record.msecs }{time_zone_str}"
|
47 |
+
return s
|
src/myapp.py
CHANGED
@@ -1,21 +1,18 @@
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""myapp Widget"""
|
3 |
-
from typing import Literal
|
4 |
-
|
5 |
import argparse
|
6 |
#from datetime import datetime
|
7 |
import sys
|
|
|
8 |
|
9 |
import gradio as gr
|
10 |
import numpy as np
|
11 |
|
12 |
-
from
|
|
|
13 |
from src.saliency import SaliencyMap, convert_colormap
|
14 |
-
from src.
|
15 |
|
16 |
-
PROGRAM_NAME = 'SaliencyMapDemo'
|
17 |
-
__version__ = get_package_version()
|
18 |
-
log = get_current_reporter()
|
19 |
log.info("#アプリ起動中")
|
20 |
watch = Stopwatch.start_new()
|
21 |
|
@@ -59,23 +56,23 @@ def submit_clicked(image: np.ndarray, algorithm: Literal["SpectralResidual", "Fi
|
|
59 |
np.ndarray: JET画像
|
60 |
np.ndarray: HOT画像
|
61 |
"""
|
62 |
-
|
63 |
-
|
64 |
#
|
65 |
saliency = SaliencyMap(algorithm)
|
66 |
success, saliency_map = saliency.compute(image)
|
67 |
-
#
|
68 |
|
69 |
if not success:
|
70 |
return image, image # エラーが発生した場合は入力画像を返します。
|
71 |
|
72 |
-
#
|
73 |
jet = convert_colormap(image, saliency_map, "jet")
|
74 |
# jet = None
|
75 |
-
#
|
76 |
hot = convert_colormap(image, saliency_map, "hot")
|
77 |
saliency = None
|
78 |
-
|
79 |
return jet, hot
|
80 |
|
81 |
|
@@ -91,7 +88,7 @@ def run_app(args: argparse.Namespace) -> None:
|
|
91 |
# https://github.com/gradio-app/gradio/issues/4226
|
92 |
with gr.Blocks(
|
93 |
analytics_enabled=False,
|
94 |
-
title=f"{PROGRAM_NAME} {
|
95 |
head="""
|
96 |
<meta name="format-detection" content="telephone=no">
|
97 |
<meta name="robots" content="noindex, nofollow, noarchive">
|
@@ -141,7 +138,7 @@ def run_app(args: argparse.Namespace) -> None:
|
|
141 |
|
142 |
gr.Markdown(f"""
|
143 |
Python {sys.version}
|
144 |
-
App {
|
145 |
""")
|
146 |
|
147 |
demo.queue(default_concurrency_limit=5)
|
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""myapp Widget"""
|
|
|
|
|
3 |
import argparse
|
4 |
#from datetime import datetime
|
5 |
import sys
|
6 |
+
from typing import Literal
|
7 |
|
8 |
import gradio as gr
|
9 |
import numpy as np
|
10 |
|
11 |
+
from . import PROGRAM_NAME
|
12 |
+
from src.reporter import log
|
13 |
from src.saliency import SaliencyMap, convert_colormap
|
14 |
+
from src.utils import Stopwatch, get_package_version
|
15 |
|
|
|
|
|
|
|
16 |
log.info("#アプリ起動中")
|
17 |
watch = Stopwatch.start_new()
|
18 |
|
|
|
56 |
np.ndarray: JET画像
|
57 |
np.ndarray: HOT画像
|
58 |
"""
|
59 |
+
log.info("#submit_Clicked")
|
60 |
+
watch = Stopwatch.start_new()
|
61 |
#
|
62 |
saliency = SaliencyMap(algorithm)
|
63 |
success, saliency_map = saliency.compute(image)
|
64 |
+
#log.info("#SaliencyMap compute()")
|
65 |
|
66 |
if not success:
|
67 |
return image, image # エラーが発生した場合は入力画像を返します。
|
68 |
|
69 |
+
#log.info("#jet")
|
70 |
jet = convert_colormap(image, saliency_map, "jet")
|
71 |
# jet = None
|
72 |
+
#log.info("#hot")
|
73 |
hot = convert_colormap(image, saliency_map, "hot")
|
74 |
saliency = None
|
75 |
+
log.info(f"#submit_Clicked End{watch.stop():.3f}")
|
76 |
return jet, hot
|
77 |
|
78 |
|
|
|
88 |
# https://github.com/gradio-app/gradio/issues/4226
|
89 |
with gr.Blocks(
|
90 |
analytics_enabled=False,
|
91 |
+
title=f"{PROGRAM_NAME} {get_package_version()}",
|
92 |
head="""
|
93 |
<meta name="format-detection" content="telephone=no">
|
94 |
<meta name="robots" content="noindex, nofollow, noarchive">
|
|
|
138 |
|
139 |
gr.Markdown(f"""
|
140 |
Python {sys.version}
|
141 |
+
App {get_package_version()}
|
142 |
""")
|
143 |
|
144 |
demo.queue(default_concurrency_limit=5)
|
src/reporter.py
CHANGED
@@ -3,54 +3,48 @@
|
|
3 |
Reporter
|
4 |
ログハンドラーが重複登録されるのを防ぐために1箇所で生成してログハンドラーを返します。
|
5 |
Example:
|
6 |
-
from reporter import
|
7 |
|
8 |
-
|
9 |
-
|
10 |
"""
|
11 |
-
|
12 |
-
from logging import
|
|
|
|
|
13 |
|
14 |
-
|
15 |
|
16 |
|
17 |
-
|
18 |
"""
|
19 |
-
|
20 |
-
|
21 |
-
return _reporters[-1]
|
22 |
-
|
23 |
-
|
24 |
-
def __make_reporter(name: str = 'SaliencyMapDemo') -> None:
|
25 |
-
"""
|
26 |
-
ログハンドラーを生成します。
|
27 |
@see https://docs.python.jp/3/howto/logging-cookbook.html
|
28 |
-
|
29 |
-
Parameters:
|
30 |
-
name: アプリ名
|
31 |
"""
|
32 |
-
|
33 |
-
formatter = Formatter('%(asctime)s%(message)s')
|
34 |
-
handler.setFormatter(formatter)
|
35 |
-
handler.setLevel(DEBUG)
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
|
43 |
-
|
44 |
|
45 |
|
46 |
def main():
|
47 |
"""
|
48 |
Entry Point
|
49 |
"""
|
50 |
-
|
51 |
-
|
52 |
-
logger = get_current_reporter()
|
53 |
-
logger.debug("main")
|
54 |
|
55 |
|
56 |
if __name__ == "__main__":
|
|
|
3 |
Reporter
|
4 |
ログハンドラーが重複登録されるのを防ぐために1箇所で生成してログハンドラーを返します。
|
5 |
Example:
|
6 |
+
from src.reporter import log
|
7 |
|
8 |
+
log.info("message")
|
9 |
+
# 2024-05-24T12:34:56+0900#アプリ起動中
|
10 |
"""
|
11 |
+
import json
|
12 |
+
from logging import Logger, getLogger
|
13 |
+
import logging.config
|
14 |
+
from typing import Optional
|
15 |
|
16 |
+
from . import PROGRAM_NAME
|
17 |
|
18 |
|
19 |
+
class Reporter:
|
20 |
"""
|
21 |
+
シングルトンパターンを適用したロガークラス。
|
22 |
+
このクラスのインスタンスがまだ存在しない場合は新たに作成し、既に存在する場合はそのインスタンスを返します。
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
@see https://docs.python.jp/3/howto/logging-cookbook.html
|
|
|
|
|
|
|
24 |
"""
|
25 |
+
_instance: Optional[Logger] = None # Reporterクラスの唯一のインスタンスを保持します。
|
|
|
|
|
|
|
26 |
|
27 |
+
def __new__(cls):
|
28 |
+
"""
|
29 |
+
"""
|
30 |
+
# インスタンスがまだ存在しない場合は新たに作成します。
|
31 |
+
if not cls._instance:
|
32 |
+
logger = getLogger(PROGRAM_NAME) # ロガーを取得します。
|
33 |
+
with open(r'config.json', 'r', encoding='utf-8') as f:
|
34 |
+
config = json.load(f)
|
35 |
+
logging.config.dictConfig(config)
|
36 |
+
cls._instance = logger # 作成したロガーを保持します。
|
37 |
+
return cls._instance # 作成したまたは既存のロガーを返します。
|
38 |
|
39 |
|
40 |
+
log: Logger = Reporter() # Reporterクラスのインスタンスを取得します。
|
41 |
|
42 |
|
43 |
def main():
|
44 |
"""
|
45 |
Entry Point
|
46 |
"""
|
47 |
+
log.debug("main")
|
|
|
|
|
|
|
48 |
|
49 |
|
50 |
if __name__ == "__main__":
|
src/saliency.py
CHANGED
@@ -8,7 +8,7 @@ import cv2
|
|
8 |
|
9 |
class SaliencyMap:
|
10 |
"""
|
11 |
-
|
12 |
Example:
|
13 |
from lib.saliency import SaliencyMap
|
14 |
|
|
|
8 |
|
9 |
class SaliencyMap:
|
10 |
"""
|
11 |
+
顕著性マップを計算するクラス。
|
12 |
Example:
|
13 |
from lib.saliency import SaliencyMap
|
14 |
|
src/utils.py
CHANGED
@@ -7,12 +7,12 @@ def get_package_version() -> str:
|
|
7 |
"""
|
8 |
バージョン情報
|
9 |
"""
|
10 |
-
return '0.0.
|
11 |
|
12 |
|
13 |
class Stopwatch:
|
14 |
"""
|
15 |
-
Stopwatch
|
16 |
Example:
|
17 |
from src.utils import Stopwatch
|
18 |
|
|
|
7 |
"""
|
8 |
バージョン情報
|
9 |
"""
|
10 |
+
return '0.0.6'
|
11 |
|
12 |
|
13 |
class Stopwatch:
|
14 |
"""
|
15 |
+
Stopwatch 経過時間を計測するためのクラス。
|
16 |
Example:
|
17 |
from src.utils import Stopwatch
|
18 |
|