Spaces:
Running
Running
Merge pull request #8 from umyuu/feature/0.0.7
Browse files- .github/workflows/deploy.yml +19 -15
- .vscode/extensions.json +2 -1
- .vscode/launch.json +16 -0
- .vscode/settings.json +3 -0
- CONTRIBUTING.md +0 -5
- README.md +16 -13
- app.py +150 -9
- config.json +1 -1
- docs/CONTRIBUTING.md +42 -0
- ThirdPartyNotices.txt → docs/ThirdPartyNotices.txt +0 -0
- launch_app.ipynb → scripts/launch_app.ipynb +51 -41
- scripts/run_hot_reload.bat +9 -0
- src/__init__.py +2 -2
- src/myapp.py +0 -153
- src/reporter.py +1 -0
- src/saliency.py +1 -1
- src/utils.py +28 -13
.github/workflows/deploy.yml
CHANGED
@@ -1,18 +1,21 @@
|
|
1 |
-
# この
|
2 |
-
#
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
#
|
7 |
-
#
|
8 |
-
#
|
9 |
-
#
|
10 |
-
#
|
11 |
-
#
|
12 |
-
#
|
13 |
-
#
|
|
|
|
|
14 |
name: "Deploy"
|
15 |
on:
|
|
|
16 |
push:
|
17 |
branches: [ "main" ]
|
18 |
# Actionsタブからワークフローの手動実行を許可します。
|
@@ -21,13 +24,14 @@ on:
|
|
21 |
jobs:
|
22 |
sync-to-hub:
|
23 |
runs-on: ubuntu-latest
|
24 |
-
# production
|
25 |
environment: production
|
26 |
steps:
|
|
|
27 |
- uses: actions/checkout@v4
|
28 |
with:
|
29 |
fetch-depth: 0
|
30 |
lfs: true
|
31 |
-
|
32 |
- name: Push to hub
|
33 |
run: git push https://${{ secrets.HF_USER_NAME }}:${{ secrets.HF_TOKEN }}@${{ secrets.HF_SPACE_URL }} main
|
|
|
1 |
+
# このGitHub Actionsのワークフローは、HuggingFaceのSpace(以下、Space)にデプロイを行うためのものです。
|
2 |
+
# 具体的には、GitHubのリポジトリをチェックアウトし、その内容をSpaceにgit pushします。
|
3 |
+
# 詳細な手順はHuggingFaceの公式ドキュメントを参照してください: https://huggingface.co/docs/hub/spaces-github-actions
|
4 |
+
## ワークフローの設定手順
|
5 |
+
# 1, HuggingFaceで「Write」タイプのアクセストークンを生成します。このトークンは認証に使用します。
|
6 |
+
# 生成はこちらから: https://huggingface.co/settings/tokens
|
7 |
+
# 2, GitHubのリポジトリの設定で、生成したアクセストークンと他の情報を環境変数として設定します。
|
8 |
+
# 設定は「Settings」タブの「Secrets and variables」 > 「Actions」 > 「Repository secrets」から行います。
|
9 |
+
# 設定する変数は以下の通りです:
|
10 |
+
# HF_TOKEN: HuggingFaceで生成したアクセストークン
|
11 |
+
# HF_USER_NAME: HuggingFaceのユーザー名
|
12 |
+
# HF_SPACE_URL: SpaceのURL
|
13 |
+
# 3, デプロイ時の環境保護ルールを適用します。
|
14 |
+
# 「Settings」タブの「Environments」 > 「new Environment」 > Name に「production」を入力して新しい環境設定を作成します。
|
15 |
+
# その後、Deployment protection rulesを設定します。
|
16 |
name: "Deploy"
|
17 |
on:
|
18 |
+
# mainブランチへのpushをトリガーにします。
|
19 |
push:
|
20 |
branches: [ "main" ]
|
21 |
# Actionsタブからワークフローの手動実行を許可します。
|
|
|
24 |
jobs:
|
25 |
sync-to-hub:
|
26 |
runs-on: ubuntu-latest
|
27 |
+
# productionの設定情報を使用します。これにより、デプロイ時の環境保護ルールを適用できます。
|
28 |
environment: production
|
29 |
steps:
|
30 |
+
# GitHubのリポジトリをチェックアウトします。
|
31 |
- uses: actions/checkout@v4
|
32 |
with:
|
33 |
fetch-depth: 0
|
34 |
lfs: true
|
35 |
+
# チェックアウトしたコードをSpaceにgit pushします。
|
36 |
- name: Push to hub
|
37 |
run: git push https://${{ secrets.HF_USER_NAME }}:${{ secrets.HF_TOKEN }}@${{ secrets.HF_SPACE_URL }} main
|
.vscode/extensions.json
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
{
|
2 |
"recommendations": [
|
3 |
-
"ms-python.flake8"
|
|
|
4 |
]
|
5 |
}
|
|
|
1 |
{
|
2 |
"recommendations": [
|
3 |
+
"ms-python.flake8",
|
4 |
+
"ms-python.vscode-pylance"
|
5 |
]
|
6 |
}
|
.vscode/launch.json
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
// IntelliSense を使用して利用可能な属性を学べます。
|
3 |
+
// 既存の属性の説明をホバーして表示します。
|
4 |
+
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
|
5 |
+
"version": "0.2.0",
|
6 |
+
"configurations": [
|
7 |
+
{
|
8 |
+
"name": "Python デバッガー: 引数を含む現在のファイル",
|
9 |
+
"type": "debugpy",
|
10 |
+
"request": "launch",
|
11 |
+
"program": "app.py",
|
12 |
+
"console": "integratedTerminal",
|
13 |
+
"args": "${command:pickArgs}"
|
14 |
+
}
|
15 |
+
]
|
16 |
+
}
|
.vscode/settings.json
CHANGED
@@ -2,10 +2,13 @@
|
|
2 |
"cSpell.words": [
|
3 |
"asctime",
|
4 |
"astype",
|
|
|
|
|
5 |
"dtype",
|
6 |
"fromarray",
|
7 |
"Gradio",
|
8 |
"inbrowser",
|
|
|
9 |
"ndarray"
|
10 |
],
|
11 |
"python.analysis.typeCheckingMode": "basic",
|
|
|
2 |
"cSpell.words": [
|
3 |
"asctime",
|
4 |
"astype",
|
5 |
+
"codeql",
|
6 |
+
"Colab",
|
7 |
"dtype",
|
8 |
"fromarray",
|
9 |
"Gradio",
|
10 |
"inbrowser",
|
11 |
+
"msecs",
|
12 |
"ndarray"
|
13 |
],
|
14 |
"python.analysis.typeCheckingMode": "basic",
|
CONTRIBUTING.md
DELETED
@@ -1,5 +0,0 @@
|
|
1 |
-
## プルリクエストについて
|
2 |
-
- プルリクエストの派生元ブランチ
|
3 |
-
main ブランチから派生させてプルリクエストを作成してください。
|
4 |
-
- プルリクエストのライセンス:
|
5 |
-
プルリクエストを送信することで、あなたの貢献がリポジトリと同じMITライセンスに従うこと、そしてあなたの貢献が将来的にプロジェクトのライセンス変更に含まれる可能性があることに**ご理解とご協力**をお願いします。
|
|
|
|
|
|
|
|
|
|
|
|
README.md
CHANGED
@@ -7,33 +7,33 @@ colorFrom: yellow
|
|
7 |
colorTo: yellow
|
8 |
pinned: false
|
9 |
---
|
10 |
-
# SaliencyMap — in Python
|
11 |
-
![Python version](https://img.shields.io/badge/python-3.
|
12 |
-
<a href="https://colab.research.google.com/github/umyuu/SaliencyMapDemo/blob/main/launch_app.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>
|
13 |
|
14 |
-
## 概要
|
15 |
画像における注目すべき領域を可視化する「顕著性マップ」を表示するデモアプリです。
|
16 |
私は画像処理についてはまだ初心者ですが、この技術に興味があります。
|
17 |
本アプリは、opencv-contribパッケージの`cv2.saliency.StaticSaliencySpectralResidual`を関数を実行するラッパーアプリです。
|
18 |
|
19 |
-
## 使い方
|
20 |
### a. Google Colabで実行
|
21 |
-
<a href="https://colab.research.google.com/github/umyuu/SaliencyMapDemo/blob/main/launch_app.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>をクリックして、簡単に実行できます。
|
22 |
|
23 |
### b. アプリをダウンロードして実行
|
24 |
-
#### システム要件
|
25 |
- 必要ディスク容量:500MB(Pythonを含みません)
|
26 |
- Python のダウンロード:https://www.python.org/downloads/
|
27 |
|
28 |
-
#### 導入方法
|
29 |
##### 1. セットアップ
|
30 |
-
1. [Releases](
|
31 |
2. `01-installation.bat`ファイルをダブルクリックします。
|
32 |
##### 2. 実行
|
33 |
`run.bat`ファイルをダブルクリックします。
|
34 |
ブラウザが自動起動し、http://127.0.0.1:9999 にアクセスできます。
|
35 |
|
36 |
-
|
37 |
- アプリが起動しない場合
|
38 |
既定のポート番号 (9999) が使用されている可能性があります。
|
39 |
メモ帳で `run.bat` ファイルを開き、以下の行の `9999` を別の数字 (例: 8888) に変更して上書き保存します。
|
@@ -44,10 +44,10 @@ pinned: false
|
|
44 |
~~~
|
45 |
python app.py --server_port 8888
|
46 |
~~~
|
47 |
-
##### 補足事項
|
48 |
- アプリをダウンロードして実行の場合は、画像処理はローカル環境で行われます。画像は外部に送信されません。
|
49 |
|
50 |
-
##### アンインストール
|
51 |
以下の手順でアンインストールできます。
|
52 |
1. アプリのフォルダを丸ごと削除します。
|
53 |
2. アプリで処理した画像は一時フォルダに残ります。不要な場合は削除してください。
|
@@ -57,5 +57,8 @@ pinned: false
|
|
57 |
C:\Users\%USERNAME%\AppData\Local\Temp\gradio
|
58 |
~~~
|
59 |
|
60 |
-
##
|
|
|
|
|
|
|
61 |
[MIT License](LICENSE)
|
|
|
7 |
colorTo: yellow
|
8 |
pinned: false
|
9 |
---
|
10 |
+
# 📖 SaliencyMap — in Python
|
11 |
+
![Python version](https://img.shields.io/badge/python-3.9+-important)
|
12 |
+
<a href="https://colab.research.google.com/github/umyuu/SaliencyMapDemo/blob/main/scripts/launch_app.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>
|
13 |
|
14 |
+
## 📝 概要
|
15 |
画像における注目すべき領域を可視化する「顕著性マップ」を表示するデモアプリです。
|
16 |
私は画像処理についてはまだ初心者ですが、この技術に興味があります。
|
17 |
本アプリは、opencv-contribパッケージの`cv2.saliency.StaticSaliencySpectralResidual`を関数を実行するラッパーアプリです。
|
18 |
|
19 |
+
## 🚀 使い方
|
20 |
### a. Google Colabで実行
|
21 |
+
<a href="https://colab.research.google.com/github/umyuu/SaliencyMapDemo/blob/main/scripts/launch_app.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>をクリックして、簡単に実行できます。
|
22 |
|
23 |
### b. アプリをダウンロードして実行
|
24 |
+
#### 💻 システム要件
|
25 |
- 必要ディスク容量:500MB(Pythonを含みません)
|
26 |
- Python のダウンロード:https://www.python.org/downloads/
|
27 |
|
28 |
+
#### 📥 導入方法
|
29 |
##### 1. セットアップ
|
30 |
+
1. [Releases](/releases)ページを開き、一番上の `Assets` 欄にある `Source code (zip)` をダウンロードして展開します。
|
31 |
2. `01-installation.bat`ファイルをダブルクリックします。
|
32 |
##### 2. 実行
|
33 |
`run.bat`ファイルをダブルクリックします。
|
34 |
ブラウザが自動起動し、http://127.0.0.1:9999 にアクセスできます。
|
35 |
|
36 |
+
**🔧 トラブルシューティング**
|
37 |
- アプリが起動しない場合
|
38 |
既定のポート番号 (9999) が使用されている可能性があります。
|
39 |
メモ帳で `run.bat` ファイルを開き、以下の行の `9999` を別の数字 (例: 8888) に変更して上書き保存します。
|
|
|
44 |
~~~
|
45 |
python app.py --server_port 8888
|
46 |
~~~
|
47 |
+
##### 💡 補足事項
|
48 |
- アプリをダウンロードして実行の場合は、画像処理はローカル環境で行われます。画像は外部に送信されません。
|
49 |
|
50 |
+
##### 🗑️ アンインストール
|
51 |
以下の手順でアンインストールできます。
|
52 |
1. アプリのフォルダを丸ごと削除します。
|
53 |
2. アプリで処理した画像は一時フォルダに残ります。不要な場合は削除してください。
|
|
|
57 |
C:\Users\%USERNAME%\AppData\Local\Temp\gradio
|
58 |
~~~
|
59 |
|
60 |
+
## 🤝 コントリビューターガイドライン
|
61 |
+
[CONTRIBUTING](docs/CONTRIBUTING.md)
|
62 |
+
|
63 |
+
## 📜 Source code License.
|
64 |
[MIT License](LICENSE)
|
app.py
CHANGED
@@ -3,18 +3,26 @@
|
|
3 |
SaliencyMapDemo
|
4 |
"""
|
5 |
from argparse import ArgumentParser, BooleanOptionalAction
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
from src import PROGRAM_NAME, get_package_version
|
8 |
-
from src.
|
|
|
|
|
9 |
|
10 |
__version__ = get_package_version()
|
|
|
|
|
11 |
|
12 |
|
13 |
-
def
|
14 |
"""
|
15 |
-
|
16 |
-
1, コマンドライン引数の解析を行います
|
17 |
-
2, アプリを起動します。
|
18 |
"""
|
19 |
parser = ArgumentParser(prog=PROGRAM_NAME, description=PROGRAM_NAME)
|
20 |
parser.add_argument('--inbrowser',
|
@@ -25,11 +33,144 @@ def main():
|
|
25 |
type=int, default=7860, help="Gradio server port")
|
26 |
parser.add_argument('--max_file_size',
|
27 |
type=str, default="20MB", help="Gradio max file size")
|
28 |
-
parser.add_argument('--version',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
-
|
31 |
-
run_app(args)
|
32 |
|
33 |
|
34 |
if __name__ == "__main__":
|
35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
SaliencyMapDemo
|
4 |
"""
|
5 |
from argparse import ArgumentParser, BooleanOptionalAction
|
6 |
+
#from datetime import datetime
|
7 |
+
import sys
|
8 |
+
from typing import Literal
|
9 |
+
|
10 |
+
import gradio as gr
|
11 |
+
import numpy as np
|
12 |
|
13 |
from src import PROGRAM_NAME, get_package_version
|
14 |
+
from src.reporter import log
|
15 |
+
from src.saliency import SaliencyMap, convert_colormap
|
16 |
+
from src.utils import Stopwatch
|
17 |
|
18 |
__version__ = get_package_version()
|
19 |
+
log.info("#アプリ起動中")
|
20 |
+
watch = Stopwatch.start_new()
|
21 |
|
22 |
|
23 |
+
def parse_args():
|
24 |
"""
|
25 |
+
コマンドライン引数の解析を行います
|
|
|
|
|
26 |
"""
|
27 |
parser = ArgumentParser(prog=PROGRAM_NAME, description=PROGRAM_NAME)
|
28 |
parser.add_argument('--inbrowser',
|
|
|
33 |
type=int, default=7860, help="Gradio server port")
|
34 |
parser.add_argument('--max_file_size',
|
35 |
type=str, default="20MB", help="Gradio max file size")
|
36 |
+
parser.add_argument('--version',
|
37 |
+
action='version', version=f'%(prog)s {__version__}')
|
38 |
+
|
39 |
+
return parser.parse_args()
|
40 |
+
|
41 |
+
|
42 |
+
def jet_tab_selected(image: np.ndarray):
|
43 |
+
"""
|
44 |
+
JETタブを選択時
|
45 |
+
"""
|
46 |
+
sw = Stopwatch.start_new()
|
47 |
+
log.info(f"#jet_tab_selected({sw.elapsed:.3f}s)")
|
48 |
+
saliency = SaliencyMap("SpectralResidual")
|
49 |
+
success, saliency_map = saliency.compute(image)
|
50 |
+
if not success:
|
51 |
+
return image # エラーが発生した場合は入力画像を返します。
|
52 |
+
retval = convert_colormap(image, saliency_map, "jet")
|
53 |
+
log.info(f"#jet_tab_selected({sw.elapsed:.3f}s)")
|
54 |
+
return retval
|
55 |
+
|
56 |
+
|
57 |
+
def hot_tab_selected(image: np.ndarray):
|
58 |
+
"""
|
59 |
+
HOTタブを選択時
|
60 |
+
"""
|
61 |
+
sw = Stopwatch.start_new()
|
62 |
+
log.info(f"#hot_tab_selected({sw.elapsed:.3f}s)")
|
63 |
+
saliency = SaliencyMap("SpectralResidual")
|
64 |
+
success, saliency_map = saliency.compute(image)
|
65 |
+
if not success:
|
66 |
+
return image # エラーが発生した場合は入力画像を返します。
|
67 |
+
retval = convert_colormap(image, saliency_map, "turbo")
|
68 |
+
log.info(f"#hot_tab_selected({sw.elapsed:.3f}s)")
|
69 |
+
return retval
|
70 |
+
|
71 |
+
|
72 |
+
def submit_clicked(image: np.ndarray, algorithm: Literal["SpectralResidual", "FineGrained"]):
|
73 |
+
"""
|
74 |
+
入力画像を元に顕著マップを計算します。
|
75 |
+
|
76 |
+
Parameters:
|
77 |
+
image: 入力画像
|
78 |
+
str: 顕著性マップのアルゴリズム
|
79 |
+
Returns:
|
80 |
+
np.ndarray: JET画像
|
81 |
+
np.ndarray: HOT画像
|
82 |
+
"""
|
83 |
+
sw = Stopwatch.start_new()
|
84 |
+
log.info(f"#submit_clicked({sw.elapsed:.3f}s)")
|
85 |
+
#
|
86 |
+
saliency = SaliencyMap(algorithm)
|
87 |
+
log.debug(f"#SaliencyMap({sw.elapsed:.3f}s)")
|
88 |
+
success, saliency_map = saliency.compute(image)
|
89 |
+
log.debug(f"#compute({sw.elapsed:.3f}s)")
|
90 |
+
|
91 |
+
if not success:
|
92 |
+
return image, image # エラーが発生した場合は入力画像を返します。
|
93 |
+
|
94 |
+
log.debug(f"#jet({sw.elapsed:.3f}s)")
|
95 |
+
jet = convert_colormap(image, saliency_map, "jet")
|
96 |
+
# jet = None
|
97 |
+
log.debug(f"#hot({sw.elapsed:.3f}s)")
|
98 |
+
hot = convert_colormap(image, saliency_map, "hot")
|
99 |
+
saliency = None
|
100 |
+
log.info(f"#submit_clicked({sw.elapsed:.3f}s)")
|
101 |
+
return jet, hot
|
102 |
+
|
103 |
+
|
104 |
+
args = parse_args()
|
105 |
+
"""
|
106 |
+
アプリの画面を作成し、Gradioサービスを起動します。
|
107 |
+
analytics_enabled=False
|
108 |
+
https://github.com/gradio-app/gradio/issues/4226
|
109 |
+
ホットリロード対応として、topレベルのインデントに。
|
110 |
+
https://www.gradio.app/guides/developing-faster-with-reload-mode
|
111 |
+
"""
|
112 |
+
with gr.Blocks(
|
113 |
+
analytics_enabled=False,
|
114 |
+
title=f"{PROGRAM_NAME} {get_package_version()}",
|
115 |
+
head="""
|
116 |
+
<meta name="format-detection" content="telephone=no">
|
117 |
+
<meta name="robots" content="noindex, nofollow, noarchive">
|
118 |
+
<meta name="referrer" content="no-referrer" />
|
119 |
+
"""
|
120 |
+
) as demo:
|
121 |
+
gr.Markdown("""
|
122 |
+
# Saliency Map demo.
|
123 |
+
""")
|
124 |
+
with gr.Accordion("取り扱い説明書", open=False):
|
125 |
+
gr.Markdown("""
|
126 |
+
1. inputタブで画像を選択します。
|
127 |
+
2. Submitボタンを押します。
|
128 |
+
3. 結果は、JETタブとHOTタブに表示します。
|
129 |
+
""")
|
130 |
+
algorithm_type = gr.Radio(
|
131 |
+
["SpectralResidual", "FineGrained"],
|
132 |
+
label="Saliency",
|
133 |
+
value="SpectralResidual",
|
134 |
+
interactive=True
|
135 |
+
)
|
136 |
+
|
137 |
+
submit_button = gr.Button("submit", variant="primary")
|
138 |
+
|
139 |
+
with gr.Row():
|
140 |
+
with gr.Tab("input", id="input"):
|
141 |
+
image_input = gr.Image(sources=["upload", "clipboard"], interactive=True)
|
142 |
+
with gr.Tab("overlay(JET)"):
|
143 |
+
image_overlay_jet = gr.Image(interactive=False)
|
144 |
+
# tab_jet.select(jet_tab_selected,
|
145 |
+
# inputs=[image_input],
|
146 |
+
# outputs=image_overlay_jet)
|
147 |
+
with gr.Tab("overlay(HOT)"):
|
148 |
+
image_overlay_hot = gr.Image(interactive=False)
|
149 |
+
# tab_hot.select(hot_tab_selected,
|
150 |
+
# inputs=[image_input],
|
151 |
+
# outputs=image_overlay_hot, api_name=False)
|
152 |
+
#
|
153 |
+
submit_button.click(
|
154 |
+
submit_clicked,
|
155 |
+
inputs=[image_input, algorithm_type],
|
156 |
+
outputs=[image_overlay_jet, image_overlay_hot]
|
157 |
+
)
|
158 |
+
gr.Markdown(f"""
|
159 |
+
Python {sys.version}
|
160 |
+
App {get_package_version()}
|
161 |
+
""")
|
162 |
+
|
163 |
+
demo.queue(default_concurrency_limit=1)
|
164 |
|
165 |
+
log.info(f"#アプリ起動完了({watch.elapsed:.3f}s)アプリを終了するにはCtrl+Cキーを入力してください。")
|
|
|
166 |
|
167 |
|
168 |
if __name__ == "__main__":
|
169 |
+
# アプリを起動します。
|
170 |
+
# https://www.gradio.app/docs/gradio/blocks#blocks-launch
|
171 |
+
demo.launch(
|
172 |
+
inbrowser=args.inbrowser,
|
173 |
+
share=args.share,
|
174 |
+
server_port=args.server_port,
|
175 |
+
max_file_size=args.max_file_size,
|
176 |
+
)
|
config.json
CHANGED
@@ -26,7 +26,7 @@
|
|
26 |
"handlers": {
|
27 |
"console1": {
|
28 |
"class": "logging.StreamHandler",
|
29 |
-
"level": "
|
30 |
"formatter": "jst"
|
31 |
}
|
32 |
},
|
|
|
26 |
"handlers": {
|
27 |
"console1": {
|
28 |
"class": "logging.StreamHandler",
|
29 |
+
"level": "INFO",
|
30 |
"formatter": "jst"
|
31 |
}
|
32 |
},
|
docs/CONTRIBUTING.md
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# 📖 Contributing Guide
|
2 |
+
## 🎉 ようこそ!
|
3 |
+
このプロジェクトへの関心と貢献に感謝します!あなたの貢献は、このプロジェクトを改善し、コミュニティを成長させるのに大いに役立ちます。このガイドは、プロジェクトへの貢献をスムーズに進めるためのものです。
|
4 |
+
|
5 |
+
## 📚 概要
|
6 |
+
このガイドでは、リポジトリの構成、プルリクエストの作成方法、バグ報告の方法、およびコーディング規約について説明します。これらのガイドラインを理解し、遵守することで、あなたの貢献がプロジェクトにとって最大の価値を持つことができます。
|
7 |
+
|
8 |
+
## 🏗️ リポジトリ構成
|
9 |
+
- 📂`/src`: Pythonソースコード。
|
10 |
+
主要な機能のコードが含まれています。
|
11 |
+
- 🧪`/test`: Pythonの単体テストコード。
|
12 |
+
各機能の正確さを確認するためのテストスクリプトが含まれています。
|
13 |
+
- 📜`/scripts`: 実行用スクリプト。
|
14 |
+
Jupyter NotebookとGradioの自動再読み込みスクリプトが含まれており、これらはアプリの実行とデバッグを容易にします。
|
15 |
+
- 🎨`/assets`: サンプル画像。
|
16 |
+
視覚的な要素を提供します。
|
17 |
+
- 📚`/docs`: ドキュメンテーション。
|
18 |
+
- `./CONTRIBUTING.md`: これは現在ご覧になっているドキュメントで、プロジェクトへの貢献方法について詳しく説明しています。新しいコントリビューターはここから始めることをお勧めします。
|
19 |
+
- `./ThirdPartyNotices.txt`:参考情報としてこのプロジェクトで使用している外部ライブラリのライセンス情報が記載されています。
|
20 |
+
- 📚`/.github`: GitHubの設定ファイルが格納されています。
|
21 |
+
- `/.github\ISSUE_TEMPLATE`: issueを作成する際のテンプレートが含まれています。これらのテンプレートは、issueを作成する際のフォーマットを提供し、必要な情報を整理するのに役立ちます。
|
22 |
+
- `/.github\workflows`: GitHub Actionsのワークフロー設定。
|
23 |
+
- `./codeql.yml`:コードのセキュリティ問題を自動的に検出します。
|
24 |
+
- `./deploy.yml`:プロジェクトのデプロイを自動化します。
|
25 |
+
- `./python-app.yml`:アプリケーションのコンパイルとflake8のコードチェックとテストコードを実行します。
|
26 |
+
- 📚`/.vscode`: vscodeの設定
|
27 |
+
アプリケーションの開発に適したVSCodeの設定情報が含まれています。これには、推奨される拡張機能、コードフォーマットの設定などが含まれています。
|
28 |
+
|
29 |
+
## 🔀 プルリクエストについて
|
30 |
+
- プルリクエストの派生元ブランチ
|
31 |
+
main ブランチから派生させてプルリクエストを作成してください。
|
32 |
+
- プルリクエストのライセンス:
|
33 |
+
プルリクエストを送信することで、あなたの貢献がリポジトリと同じMITライセンスに従うこと、そしてあなたの貢献が将来的にプロジェクトのライセンス変更に含まれる可能性があることに**ご理解とご協力**をお願いします。
|
34 |
+
|
35 |
+
## 🐛 バグ報告
|
36 |
+
バグを見つけた場合は、まず[既存のissue](../issues)を確認してください。
|
37 |
+
同じバグについてのissueが存在しない場合は、[新しいバグ報告](../issues/new?assignees=&labels=bug&projects=&template=10-problem.yaml)を作成してください。
|
38 |
+
|
39 |
+
## 📝 コーディング規約
|
40 |
+
- コードスタイル: このプロジェクトではPEP8に準拠し、コードチェックツールとしてflake8を採用しています。VSCodeを使用し開発すると拡張機能がレコメンドされます。拡張機能を導入して確認してください。
|
41 |
+
- 変数名: 変数名は明確で意味のある名前を使用してください。ローカル変数以外では一文字の変数名は避け、名前から変数の目的が理解できるようにしてください。
|
42 |
+
- ドキュメンテーション: 公開されるすべての関数やクラス、メソッドにはDocstringを追加してください。これにより、他の開発者がコードの目的と動作を理解しやすくなります。
|
ThirdPartyNotices.txt → docs/ThirdPartyNotices.txt
RENAMED
File without changes
|
launch_app.ipynb → scripts/launch_app.ipynb
RENAMED
@@ -1,33 +1,22 @@
|
|
1 |
{
|
2 |
-
"nbformat": 4,
|
3 |
-
"nbformat_minor": 0,
|
4 |
-
"metadata": {
|
5 |
-
"colab": {
|
6 |
-
"provenance": []
|
7 |
-
},
|
8 |
-
"kernelspec": {
|
9 |
-
"name": "python3",
|
10 |
-
"display_name": "Python 3"
|
11 |
-
},
|
12 |
-
"language_info": {
|
13 |
-
"name": "python"
|
14 |
-
}
|
15 |
-
},
|
16 |
"cells": [
|
17 |
{
|
18 |
"cell_type": "markdown",
|
19 |
-
"source": [
|
20 |
-
"# アプリのインストール"
|
21 |
-
],
|
22 |
"metadata": {
|
23 |
"id": "QBBnZWaddxv4"
|
24 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
},
|
26 |
{
|
27 |
"cell_type": "code",
|
28 |
-
"
|
29 |
-
"%cd /content"
|
30 |
-
],
|
31 |
"metadata": {
|
32 |
"colab": {
|
33 |
"base_uri": "https://localhost:8080/"
|
@@ -35,15 +24,17 @@
|
|
35 |
"id": "7a5Rf_Qee3N1",
|
36 |
"outputId": "c3890145-930e-4889-e57e-22321250461f"
|
37 |
},
|
38 |
-
"execution_count": 1,
|
39 |
"outputs": [
|
40 |
{
|
41 |
-
"output_type": "stream",
|
42 |
"name": "stdout",
|
|
|
43 |
"text": [
|
44 |
"/content\n"
|
45 |
]
|
46 |
}
|
|
|
|
|
|
|
47 |
]
|
48 |
},
|
49 |
{
|
@@ -58,8 +49,8 @@
|
|
58 |
},
|
59 |
"outputs": [
|
60 |
{
|
61 |
-
"output_type": "stream",
|
62 |
"name": "stdout",
|
|
|
63 |
"text": [
|
64 |
"Cloning into 'SaliencyMapDemo'...\n",
|
65 |
"remote: Enumerating objects: 84, done.\u001b[K\n",
|
@@ -77,9 +68,7 @@
|
|
77 |
},
|
78 |
{
|
79 |
"cell_type": "code",
|
80 |
-
"
|
81 |
-
"%cd SaliencyMapDemo"
|
82 |
-
],
|
83 |
"metadata": {
|
84 |
"colab": {
|
85 |
"base_uri": "https://localhost:8080/"
|
@@ -87,15 +76,17 @@
|
|
87 |
"id": "H0HI3iKRenJB",
|
88 |
"outputId": "770d3024-43a2-4282-f59d-bc496cba9cf6"
|
89 |
},
|
90 |
-
"execution_count": 3,
|
91 |
"outputs": [
|
92 |
{
|
93 |
-
"output_type": "stream",
|
94 |
"name": "stdout",
|
|
|
95 |
"text": [
|
96 |
"/content/SaliencyMapDemo\n"
|
97 |
]
|
98 |
}
|
|
|
|
|
|
|
99 |
]
|
100 |
},
|
101 |
{
|
@@ -110,8 +101,8 @@
|
|
110 |
},
|
111 |
"outputs": [
|
112 |
{
|
113 |
-
"output_type": "stream",
|
114 |
"name": "stdout",
|
|
|
115 |
"text": [
|
116 |
"Collecting gradio==4.28.3 (from -r requirements.txt (line 1))\n",
|
117 |
" Downloading gradio-4.28.3-py3-none-any.whl (12.2 MB)\n",
|
@@ -269,18 +260,21 @@
|
|
269 |
},
|
270 |
{
|
271 |
"cell_type": "markdown",
|
272 |
-
"source": [
|
273 |
-
"# 実行"
|
274 |
-
],
|
275 |
"metadata": {
|
276 |
"id": "LUcp4xt2fJU9"
|
277 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
278 |
},
|
279 |
{
|
280 |
"cell_type": "code",
|
281 |
-
"
|
282 |
-
"!python app.py --share"
|
283 |
-
],
|
284 |
"metadata": {
|
285 |
"colab": {
|
286 |
"base_uri": "https://localhost:8080/"
|
@@ -288,11 +282,10 @@
|
|
288 |
"id": "J3kKmi6Rd95n",
|
289 |
"outputId": "d06135be-5c00-4b68-abba-6606f415ccce"
|
290 |
},
|
291 |
-
"execution_count": 5,
|
292 |
"outputs": [
|
293 |
{
|
294 |
-
"output_type": "stream",
|
295 |
"name": "stdout",
|
|
|
296 |
"text": [
|
297 |
"2024-05-11 12:13:31,862#アプリ起動中\n",
|
298 |
"2024-05-11 12:13:36,775#アプリ起動完了(4.912s)\n",
|
@@ -304,7 +297,24 @@
|
|
304 |
"Killing tunnel 127.0.0.1:9999 <> https://90361c40461e1540a1.gradio.live\n"
|
305 |
]
|
306 |
}
|
|
|
|
|
|
|
307 |
]
|
308 |
}
|
309 |
-
]
|
310 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
"cells": [
|
3 |
{
|
4 |
"cell_type": "markdown",
|
|
|
|
|
|
|
5 |
"metadata": {
|
6 |
"id": "QBBnZWaddxv4"
|
7 |
+
},
|
8 |
+
"source": [
|
9 |
+
"### アプリの起動 \n",
|
10 |
+
"アプリを起動するには、以下の手順を実行してください: \n",
|
11 |
+
"1. 画面上部のメニューバーの「ランタイム」をクリックしてください。 \n",
|
12 |
+
"2. ドロップダウンメニューが表示されます、「すべてのセルを実行」をクリックしてください。または、キーボードショートカットの「Ctrl+F9」を使用することもできます。 \n",
|
13 |
+
"\n",
|
14 |
+
"これにより、ノートブック内のすべてのセルが順番に実行され、アプリが起動します。 "
|
15 |
+
]
|
16 |
},
|
17 |
{
|
18 |
"cell_type": "code",
|
19 |
+
"execution_count": 1,
|
|
|
|
|
20 |
"metadata": {
|
21 |
"colab": {
|
22 |
"base_uri": "https://localhost:8080/"
|
|
|
24 |
"id": "7a5Rf_Qee3N1",
|
25 |
"outputId": "c3890145-930e-4889-e57e-22321250461f"
|
26 |
},
|
|
|
27 |
"outputs": [
|
28 |
{
|
|
|
29 |
"name": "stdout",
|
30 |
+
"output_type": "stream",
|
31 |
"text": [
|
32 |
"/content\n"
|
33 |
]
|
34 |
}
|
35 |
+
],
|
36 |
+
"source": [
|
37 |
+
"%cd /content"
|
38 |
]
|
39 |
},
|
40 |
{
|
|
|
49 |
},
|
50 |
"outputs": [
|
51 |
{
|
|
|
52 |
"name": "stdout",
|
53 |
+
"output_type": "stream",
|
54 |
"text": [
|
55 |
"Cloning into 'SaliencyMapDemo'...\n",
|
56 |
"remote: Enumerating objects: 84, done.\u001b[K\n",
|
|
|
68 |
},
|
69 |
{
|
70 |
"cell_type": "code",
|
71 |
+
"execution_count": 3,
|
|
|
|
|
72 |
"metadata": {
|
73 |
"colab": {
|
74 |
"base_uri": "https://localhost:8080/"
|
|
|
76 |
"id": "H0HI3iKRenJB",
|
77 |
"outputId": "770d3024-43a2-4282-f59d-bc496cba9cf6"
|
78 |
},
|
|
|
79 |
"outputs": [
|
80 |
{
|
|
|
81 |
"name": "stdout",
|
82 |
+
"output_type": "stream",
|
83 |
"text": [
|
84 |
"/content/SaliencyMapDemo\n"
|
85 |
]
|
86 |
}
|
87 |
+
],
|
88 |
+
"source": [
|
89 |
+
"%cd SaliencyMapDemo"
|
90 |
]
|
91 |
},
|
92 |
{
|
|
|
101 |
},
|
102 |
"outputs": [
|
103 |
{
|
|
|
104 |
"name": "stdout",
|
105 |
+
"output_type": "stream",
|
106 |
"text": [
|
107 |
"Collecting gradio==4.28.3 (from -r requirements.txt (line 1))\n",
|
108 |
" Downloading gradio-4.28.3-py3-none-any.whl (12.2 MB)\n",
|
|
|
260 |
},
|
261 |
{
|
262 |
"cell_type": "markdown",
|
|
|
|
|
|
|
263 |
"metadata": {
|
264 |
"id": "LUcp4xt2fJU9"
|
265 |
+
},
|
266 |
+
"source": [
|
267 |
+
"### 🚀 実行 \n",
|
268 |
+
"1, 「Running on public URL:」の横のリンクをクリックします。 \n",
|
269 |
+
"2, リンクをクリックすると、新しいブラウザのタブが開きアプリを自由に操作できます。 \n",
|
270 |
+
"### アプリの停止 \n",
|
271 |
+
"1,「!python app.py --share」の行の左側にある■ボタン(停止ボタン)をクリックします。 \n",
|
272 |
+
"2, アプリが停止します。 "
|
273 |
+
]
|
274 |
},
|
275 |
{
|
276 |
"cell_type": "code",
|
277 |
+
"execution_count": 5,
|
|
|
|
|
278 |
"metadata": {
|
279 |
"colab": {
|
280 |
"base_uri": "https://localhost:8080/"
|
|
|
282 |
"id": "J3kKmi6Rd95n",
|
283 |
"outputId": "d06135be-5c00-4b68-abba-6606f415ccce"
|
284 |
},
|
|
|
285 |
"outputs": [
|
286 |
{
|
|
|
287 |
"name": "stdout",
|
288 |
+
"output_type": "stream",
|
289 |
"text": [
|
290 |
"2024-05-11 12:13:31,862#アプリ起動中\n",
|
291 |
"2024-05-11 12:13:36,775#アプリ起動完了(4.912s)\n",
|
|
|
297 |
"Killing tunnel 127.0.0.1:9999 <> https://90361c40461e1540a1.gradio.live\n"
|
298 |
]
|
299 |
}
|
300 |
+
],
|
301 |
+
"source": [
|
302 |
+
"!python app.py --share"
|
303 |
]
|
304 |
}
|
305 |
+
],
|
306 |
+
"metadata": {
|
307 |
+
"colab": {
|
308 |
+
"provenance": []
|
309 |
+
},
|
310 |
+
"kernelspec": {
|
311 |
+
"display_name": "Python 3",
|
312 |
+
"name": "python3"
|
313 |
+
},
|
314 |
+
"language_info": {
|
315 |
+
"name": "python"
|
316 |
+
}
|
317 |
+
},
|
318 |
+
"nbformat": 4,
|
319 |
+
"nbformat_minor": 0
|
320 |
+
}
|
scripts/run_hot_reload.bat
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
REM Gradioのオートリロード用のスクリプトです。
|
2 |
+
@echo on
|
3 |
+
|
4 |
+
cd %~dp0
|
5 |
+
cd ..
|
6 |
+
call venv\Scripts\activate
|
7 |
+
gradio app.py
|
8 |
+
|
9 |
+
TIMEOUT /T 10
|
src/__init__.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""src Module"""
|
3 |
from datetime import datetime
|
4 |
-
import logging
|
5 |
import re
|
6 |
from zoneinfo import ZoneInfo
|
7 |
|
@@ -35,7 +35,7 @@ class LocalTimeFormatter(logging.Formatter):
|
|
35 |
|
36 |
t = dt.strftime(re.sub(self.pattern, "", datefmt))
|
37 |
match = re.search(self.pattern, datefmt)
|
38 |
-
if
|
39 |
return t
|
40 |
|
41 |
groups = match.groups()
|
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""src Module"""
|
3 |
from datetime import datetime
|
4 |
+
import logging
|
5 |
import re
|
6 |
from zoneinfo import ZoneInfo
|
7 |
|
|
|
35 |
|
36 |
t = dt.strftime(re.sub(self.pattern, "", datefmt))
|
37 |
match = re.search(self.pattern, datefmt)
|
38 |
+
if match is None:
|
39 |
return t
|
40 |
|
41 |
groups = match.groups()
|
src/myapp.py
DELETED
@@ -1,153 +0,0 @@
|
|
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 |
-
|
19 |
-
|
20 |
-
def jet_tab_selected(image: np.ndarray):
|
21 |
-
"""
|
22 |
-
JETタブを選択時
|
23 |
-
"""
|
24 |
-
#print(f"{datetime.now()}#jet")
|
25 |
-
saliency = SaliencyMap("SpectralResidual")
|
26 |
-
success, saliency_map = saliency.compute(image)
|
27 |
-
if not success:
|
28 |
-
return image # エラーが発生した場合は入力画像を返します。
|
29 |
-
retval = convert_colormap(image, saliency_map, "jet")
|
30 |
-
#print(f"{datetime.now()}#jet")
|
31 |
-
return retval
|
32 |
-
|
33 |
-
|
34 |
-
def hot_tab_selected(image: np.ndarray):
|
35 |
-
"""
|
36 |
-
HOTタブを選択時
|
37 |
-
"""
|
38 |
-
#print(f"{datetime.now()}#hot")
|
39 |
-
saliency = SaliencyMap("SpectralResidual")
|
40 |
-
success, saliency_map = saliency.compute(image)
|
41 |
-
if not success:
|
42 |
-
return image # エラーが発生した場合は入力画像を返します。
|
43 |
-
retval = convert_colormap(image, saliency_map, "turbo")
|
44 |
-
#print(f"{datetime.now()}#hot")
|
45 |
-
return retval
|
46 |
-
|
47 |
-
|
48 |
-
def submit_clicked(image: np.ndarray, algorithm: Literal["SpectralResidual", "FineGrained"]):
|
49 |
-
"""
|
50 |
-
入力画像を元に顕著マップを計算します。
|
51 |
-
|
52 |
-
Parameters:
|
53 |
-
image: 入力画像
|
54 |
-
str: 顕著性マップのアルゴリズム
|
55 |
-
Returns:
|
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 |
-
|
79 |
-
def run_app(args: argparse.Namespace) -> None:
|
80 |
-
"""
|
81 |
-
アプリの画面を作成し、Gradioサービスを起動します。
|
82 |
-
|
83 |
-
Parameters:
|
84 |
-
args: コマンドライン引数
|
85 |
-
watch: 起動したスタート時間
|
86 |
-
"""
|
87 |
-
# analytics_enabled=False
|
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">
|
95 |
-
<meta name="referrer" content="no-referrer" />
|
96 |
-
"""
|
97 |
-
) as demo:
|
98 |
-
|
99 |
-
gr.Markdown("""
|
100 |
-
# Saliency Map demo.
|
101 |
-
""")
|
102 |
-
with gr.Accordion("取り扱い説明書", open=False):
|
103 |
-
gr.Markdown("""
|
104 |
-
1. inputタブで画像を選択します。
|
105 |
-
2. Submitボタンを押します。
|
106 |
-
3. 結果は、JETタブとHOTタブに表示します。
|
107 |
-
""")
|
108 |
-
algorithm_type = gr.Radio(
|
109 |
-
["SpectralResidual", "FineGrained"],
|
110 |
-
label="Saliency",
|
111 |
-
value="SpectralResidual",
|
112 |
-
interactive=True
|
113 |
-
)
|
114 |
-
|
115 |
-
submit_button = gr.Button("submit", variant="primary")
|
116 |
-
|
117 |
-
with gr.Row():
|
118 |
-
with gr.Tab("input", id="input"):
|
119 |
-
image_input = gr.Image(sources=["upload", "clipboard"],
|
120 |
-
interactive=True)
|
121 |
-
with gr.Tab("overlay(JET)"):
|
122 |
-
image_overlay_jet = gr.Image(interactive=False)
|
123 |
-
# tab_jet.select(jet_tab_selected,
|
124 |
-
# inputs=[image_input],
|
125 |
-
# outputs=image_overlay_jet)
|
126 |
-
with gr.Tab("overlay(HOT)"):
|
127 |
-
image_overlay_hot = gr.Image(interactive=False)
|
128 |
-
# tab_hot.select(hot_tab_selected,
|
129 |
-
# inputs=[image_input],
|
130 |
-
# outputs=image_overlay_hot, api_name=False)
|
131 |
-
#
|
132 |
-
submit_button.click(
|
133 |
-
submit_clicked,
|
134 |
-
inputs=[image_input, algorithm_type],
|
135 |
-
outputs=[image_overlay_jet,
|
136 |
-
image_overlay_hot]
|
137 |
-
)
|
138 |
-
|
139 |
-
gr.Markdown(f"""
|
140 |
-
Python {sys.version}
|
141 |
-
App {get_package_version()}
|
142 |
-
""")
|
143 |
-
|
144 |
-
demo.queue(default_concurrency_limit=5)
|
145 |
-
|
146 |
-
log.info(f"#アプリ起動完了({watch.stop():.3f}s)")
|
147 |
-
# https://www.gradio.app/docs/gradio/blocks#blocks-launch
|
148 |
-
demo.launch(
|
149 |
-
inbrowser=args.inbrowser,
|
150 |
-
share=args.share,
|
151 |
-
server_port=args.server_port,
|
152 |
-
max_file_size=args.max_file_size,
|
153 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/reporter.py
CHANGED
@@ -11,6 +11,7 @@
|
|
11 |
import json
|
12 |
from logging import Logger, getLogger
|
13 |
import logging.config
|
|
|
14 |
from typing import Optional
|
15 |
|
16 |
from . import PROGRAM_NAME
|
|
|
11 |
import json
|
12 |
from logging import Logger, getLogger
|
13 |
import logging.config
|
14 |
+
|
15 |
from typing import Optional
|
16 |
|
17 |
from . import PROGRAM_NAME
|
src/saliency.py
CHANGED
@@ -10,7 +10,7 @@ class SaliencyMap:
|
|
10 |
"""
|
11 |
顕著性マップを計算するクラス。
|
12 |
Example:
|
13 |
-
from
|
14 |
|
15 |
saliency = SaliencyMap("SpectralResidual")
|
16 |
success, saliencyMap = saliency.compute(image)
|
|
|
10 |
"""
|
11 |
顕著性マップを計算するクラス。
|
12 |
Example:
|
13 |
+
from src.saliency import SaliencyMap
|
14 |
|
15 |
saliency = SaliencyMap("SpectralResidual")
|
16 |
success, saliencyMap = saliency.compute(image)
|
src/utils.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""ユーティリティ"""
|
|
|
3 |
import time
|
4 |
|
5 |
|
@@ -7,37 +8,49 @@ def get_package_version() -> str:
|
|
7 |
"""
|
8 |
バージョン情報
|
9 |
"""
|
10 |
-
return '0.0.
|
11 |
|
12 |
|
|
|
13 |
class Stopwatch:
|
14 |
"""
|
15 |
-
|
16 |
Example:
|
17 |
from src.utils import Stopwatch
|
18 |
|
19 |
watch = Stopwatch.start_new()
|
20 |
-
|
21 |
-
print(f"{watch.
|
22 |
"""
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
self._elapsed = 0
|
27 |
|
28 |
@property
|
29 |
-
def elapsed(self):
|
30 |
"""
|
31 |
-
|
32 |
"""
|
|
|
|
|
|
|
|
|
33 |
return self._elapsed
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
def start(self) -> None:
|
36 |
"""
|
37 |
計測を開始します。
|
38 |
"""
|
39 |
self._start_time = time.perf_counter()
|
40 |
self._elapsed = 0
|
|
|
41 |
|
42 |
@classmethod
|
43 |
def start_new(cls):
|
@@ -48,10 +61,12 @@ class Stopwatch:
|
|
48 |
stopwatch.start()
|
49 |
return stopwatch
|
50 |
|
51 |
-
def stop(self):
|
52 |
"""
|
53 |
計測を終了します。
|
54 |
"""
|
55 |
-
|
56 |
-
|
|
|
|
|
57 |
return self._elapsed
|
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""ユーティリティ"""
|
3 |
+
from dataclasses import dataclass
|
4 |
import time
|
5 |
|
6 |
|
|
|
8 |
"""
|
9 |
バージョン情報
|
10 |
"""
|
11 |
+
return '0.0.7'
|
12 |
|
13 |
|
14 |
+
@dataclass
|
15 |
class Stopwatch:
|
16 |
"""
|
17 |
+
経過時間を計測するためのクラス。
|
18 |
Example:
|
19 |
from src.utils import Stopwatch
|
20 |
|
21 |
watch = Stopwatch.start_new()
|
22 |
+
### 計測する処理
|
23 |
+
print(f"{watch.elapsed:.3f}")
|
24 |
"""
|
25 |
+
_start_time: float = 0
|
26 |
+
_elapsed: float = 0
|
27 |
+
_is_running: bool = False
|
|
|
28 |
|
29 |
@property
|
30 |
+
def elapsed(self) -> float:
|
31 |
"""
|
32 |
+
経過時間を取得します。
|
33 |
"""
|
34 |
+
if self._is_running:
|
35 |
+
end_time = time.perf_counter()
|
36 |
+
self._elapsed = end_time - self._start_time
|
37 |
+
|
38 |
return self._elapsed
|
39 |
|
40 |
+
@property
|
41 |
+
def is_running(self) -> bool:
|
42 |
+
"""
|
43 |
+
実行中かどうかを取得します。
|
44 |
+
"""
|
45 |
+
return self._is_running
|
46 |
+
|
47 |
def start(self) -> None:
|
48 |
"""
|
49 |
計測を開始します。
|
50 |
"""
|
51 |
self._start_time = time.perf_counter()
|
52 |
self._elapsed = 0
|
53 |
+
self._is_running = True
|
54 |
|
55 |
@classmethod
|
56 |
def start_new(cls):
|
|
|
61 |
stopwatch.start()
|
62 |
return stopwatch
|
63 |
|
64 |
+
def stop(self) -> float:
|
65 |
"""
|
66 |
計測を終了します。
|
67 |
"""
|
68 |
+
if self._is_running:
|
69 |
+
end_time = time.perf_counter()
|
70 |
+
self._elapsed = end_time - self._start_time
|
71 |
+
self._is_running = False
|
72 |
return self._elapsed
|