うみゅ commited on
Commit
1bf41f9
·
unverified ·
1 Parent(s): f1a6fac

- ThirdPartyNoticesを追加。
 使用ライブラリのライセンス情報です。
- ブラウザのタイトルバーに、アプリ名とバージョンを表示
- app.pyの内容を分割
 launch.py…起動処理
 app.py…画面
 utils.py…ユーティリティ。アプリのバージョン情報とストップウォッチクラス。

Files changed (6) hide show
  1. README.md +15 -6
  2. ThirdPartyNotices.txt +18 -0
  3. run.bat +1 -1
  4. src/app.py +34 -20
  5. src/launch.py +28 -0
  6. src/utils.py +34 -0
README.md CHANGED
@@ -1,10 +1,11 @@
1
- # saliencymap
2
- ## Introduction
3
  gradioを使って、opencv-contribパッケージのcv2.saliency.StaticSaliencySpectralResidualを呼び出すサンプルプログラムです。
 
4
  私は画像処理についてはまだ初心者ですが、興味を持っています。
5
- 以下から導入方法です。
6
 
7
- ## 1. 仮想環境(venv)に必要ライブラリのインストール
 
8
  - リポジトリ直下にある以下のバッチを実行する。
9
  ~~~
10
  01-installation.bat
@@ -12,15 +13,23 @@ gradioを使って、opencv-contribパッケージのcv2.saliency.StaticSaliency
12
  > **NOTE**
13
  仮想環境の名称は「venv」で作成します。
14
 
15
- ## 2. 実行
16
  - リポジトリ直下にある以下のバッチを実行する。
17
  ~~~
18
  run.bat
19
  ~~~
 
20
  > **NOTE**
21
  > デフォルトポートは9999です。
22
  > 他のポート番号例えば8888に変更したい場合は、run.bat内の以下の行を書き換えてください。
23
- > python src\app.py --server_port 8888
 
 
 
 
 
 
 
24
 
25
  ## Source code License.
26
  [MIT License](LICENSE)
 
1
+ # SaliencyMap
2
+ ## 概要
3
  gradioを使って、opencv-contribパッケージのcv2.saliency.StaticSaliencySpectralResidualを呼び出すサンプルプログラムです。
4
+
5
  私は画像処理についてはまだ初心者ですが、興味を持っています。
 
6
 
7
+ ## 導入方法
8
+ ### 1. 仮想環境(venv)に必要ライブラリのインストール
9
  - リポジトリ直下にある以下のバッチを実行する。
10
  ~~~
11
  01-installation.bat
 
13
  > **NOTE**
14
  仮想環境の名称は「venv」で作成します。
15
 
16
+ ### 2. 実行
17
  - リポジトリ直下にある以下のバッチを実行する。
18
  ~~~
19
  run.bat
20
  ~~~
21
+ 実行するとブラウザが起動します。
22
  > **NOTE**
23
  > デフォルトポートは9999です。
24
  > 他のポート番号例えば8888に変更したい場合は、run.bat内の以下の行を書き換えてください。
25
+ > python src\launch.py --server_port 8888
26
+
27
+ ## 補足事項
28
+ - ローカルで処理が完結します。画像を外部には送信しません。
29
+
30
+ ## Uninstall
31
+ このアプリをアンインストールするには、以下の手順に従ってください。
32
+ - アプリのフォルダをフォルダ毎削除してください。
33
 
34
  ## Source code License.
35
  [MIT License](LICENSE)
ThirdPartyNotices.txt ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ NOTICES
2
+
3
+ This repository uses the materials listed or described below.
4
+
5
+ ---------------------------------------------------------
6
+
7
+ Gradio - Apache-2.0
8
+ https://github.com/gradio-app/gradio
9
+ ---------------------------------------------------------
10
+
11
+ ---------------------------------------------------------
12
+
13
+ opencv-python - MIT
14
+ https://github.com/opencv/opencv-python
15
+
16
+ LICENSE-3RD-PARTY.txt
17
+ https://github.com/opencv/opencv-python/blob/master/LICENSE-3RD-PARTY.txt
18
+ ---------------------------------------------------------
run.bat CHANGED
@@ -2,6 +2,6 @@
2
 
3
  cd %~dp0
4
  call venv\Scripts\activate
5
- python src\app.py --server_port 9999
6
 
7
  TIMEOUT /T 10
 
2
 
3
  cd %~dp0
4
  call venv\Scripts\activate
5
+ python src\launch.py --server_port 9999
6
 
7
  TIMEOUT /T 10
src/app.py CHANGED
@@ -3,15 +3,23 @@
3
  SaliencyMapDemo
4
  """
5
  import argparse
 
 
 
 
6
  import cv2
7
  import gradio as gr
8
  import numpy as np
9
- import sys
 
10
 
11
  PROGRAM_NAME = 'SaliencyMapDemo'
12
- __version__ = '0.0.1'
13
 
14
  def compute_saliency(image: np.ndarray):
 
 
 
15
  # OpenCVのsaliencyを作成
16
  saliency = cv2.saliency.StaticSaliencySpectralResidual_create()
17
  # 画像の顕著性を計算
@@ -21,17 +29,28 @@ def compute_saliency(image: np.ndarray):
21
  # 顕著性マップをカラーマップに変換
22
  saliencyMap = (saliencyMap * 255).astype("uint8")
23
  saliencyMap = cv2.applyColorMap(saliencyMap, cv2.COLORMAP_JET)
 
 
24
  # 元の画像とカラーマップを重ね合わせ
25
  overlay = cv2.addWeighted(image, 0.5, saliencyMap, 0.5, 0)
 
26
  return overlay
27
  else:
28
  return image # エラーが発生した場合は元の画像を返す
29
 
30
- def main(args):
 
 
 
 
 
 
 
 
31
  """
32
- Entry Point
33
  """
34
- with gr.Blocks() as demo:
35
  gr.Markdown(
36
  """
37
  # Saliency Map demo.
@@ -46,26 +65,21 @@ def main(args):
46
  with gr.Tab("input"):
47
  image_input = gr.Image()
48
  with gr.Tab("overlay"):
49
- image_overlay = gr.Image()
50
 
51
 
52
  submit_button.click(compute_saliency, inputs=image_input, outputs=image_overlay)
53
- sys.version
54
  gr.Markdown(
55
  f"""
56
  Python {sys.version}
57
  App {__version__}
58
  """)
59
- demo.queue(default_concurrency_limit=5).launch(max_file_size=args.max_file_size, server_port=args.server_port)
60
-
61
- if __name__ == "__main__":
62
- """
63
- コマンドライン引数の解析
64
- """
65
- parser = argparse.ArgumentParser(prog=PROGRAM_NAME, description="SaliencyMapDemo")
66
- parser.add_argument('--server_port', type=int, default=9999, help="Gradio server port")
67
- parser.add_argument('--max_file_size', type=int, default=20 * gr.FileSize.MB, help="Gradio max file size")
68
- parser.add_argument('--version', action='version', version='%(prog)s {0}'.format(__version__))
69
-
70
- main(parser.parse_args())
71
-
 
3
  SaliencyMapDemo
4
  """
5
  import argparse
6
+ from datetime import datetime
7
+ import sys
8
+ from threading import Timer
9
+
10
  import cv2
11
  import gradio as gr
12
  import numpy as np
13
+
14
+ import utils
15
 
16
  PROGRAM_NAME = 'SaliencyMapDemo'
17
+ __version__ = utils.get_package_version()
18
 
19
  def compute_saliency(image: np.ndarray):
20
+ """
21
+ 顕著性MAP画像を作成します。
22
+ """
23
  # OpenCVのsaliencyを作成
24
  saliency = cv2.saliency.StaticSaliencySpectralResidual_create()
25
  # 画像の顕著性を計算
 
29
  # 顕著性マップをカラーマップに変換
30
  saliencyMap = (saliencyMap * 255).astype("uint8")
31
  saliencyMap = cv2.applyColorMap(saliencyMap, cv2.COLORMAP_JET)
32
+
33
+ #overlay = saliencyMap
34
  # 元の画像とカラーマップを重ね合わせ
35
  overlay = cv2.addWeighted(image, 0.5, saliencyMap, 0.5, 0)
36
+
37
  return overlay
38
  else:
39
  return image # エラーが発生した場合は元の画像を返す
40
 
41
+ def browser_worker(server_port: int) -> None:
42
+ from webbrowser import open_new_tab
43
+ open_new_tab(f"http://127.0.0.1:{server_port}")
44
+
45
+ def webbrowser_launch(args: argparse.Namespace) -> None:
46
+ timer = Timer(1, browser_worker, args=[args.server_port])
47
+ timer.start()
48
+
49
+ def run(args: argparse.Namespace, watch: utils.Stopwatch) -> None:
50
  """
51
+ アプリの画面を作成し、Gradioサービスを起動します。
52
  """
53
+ with gr.Blocks(title=f"{PROGRAM_NAME} {__version__}") as demo:
54
  gr.Markdown(
55
  """
56
  # Saliency Map demo.
 
65
  with gr.Tab("input"):
66
  image_input = gr.Image()
67
  with gr.Tab("overlay"):
68
+ image_overlay = gr.Image(interactive=False)
69
 
70
 
71
  submit_button.click(compute_saliency, inputs=image_input, outputs=image_overlay)
72
+
73
  gr.Markdown(
74
  f"""
75
  Python {sys.version}
76
  App {__version__}
77
  """)
78
+
79
+ demo.queue(default_concurrency_limit=5)
80
+
81
+ webbrowser_launch(args)
82
+
83
+ print(f"{datetime.now()}:アプリ起動完了({watch.stop():.3f}s)")
84
+
85
+ demo.launch(max_file_size=args.max_file_size, server_port=args.server_port)
 
 
 
 
 
src/launch.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ SaliencyMapDemo
4
+ """
5
+ import argparse
6
+ from datetime import datetime
7
+
8
+ from utils import get_package_version, Stopwatch
9
+
10
+ def main():
11
+ """
12
+ エントリーポイント
13
+ コマンドライン引数の解析を行います
14
+ """
15
+ print(f"{datetime.now()}:アプリ起動中")
16
+ watch = Stopwatch.startNew()
17
+
18
+ import app
19
+
20
+ parser = argparse.ArgumentParser(prog=app.PROGRAM_NAME, description="SaliencyMapDemo")
21
+ parser.add_argument('--server_port', type=int, default=9999, help="Gradio server port")
22
+ parser.add_argument('--max_file_size', type=int, default=20 * 1024 * 1024, help="Gradio max file size")
23
+ parser.add_argument('--version', action='version', version=f'%(prog)s {get_package_version()}')
24
+
25
+ app.run(parser.parse_args(), watch)
26
+
27
+ if __name__ == "__main__":
28
+ main()
src/utils.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import time
3
+
4
+ def get_package_version() -> str:
5
+ return '0.0.2'
6
+
7
+ class Stopwatch:
8
+ """
9
+ Stopwatch 経過時間を計測するためのクラスです。
10
+ """
11
+
12
+ def __init__(self):
13
+ self._start_time = None
14
+ self._elapsed = 0;
15
+
16
+ @property
17
+ def Elapsed(self):
18
+ return self._elapsed
19
+
20
+ def start(self) -> None:
21
+ self._start_time = time.perf_counter()
22
+ self._elapsed = 0;
23
+
24
+ @classmethod
25
+ def startNew(cls):
26
+ stopwatch = Stopwatch()
27
+ stopwatch.start()
28
+ return stopwatch
29
+
30
+ def stop(self):
31
+ end_time = time.perf_counter()
32
+ self._elapsed = end_time - self._start_time
33
+ return self._elapsed
34
+