HaochenGong commited on
Commit
b3e6fcf
·
1 Parent(s): 5700698
.idea/workspace.xml CHANGED
@@ -4,14 +4,25 @@
4
  <option name="autoReloadType" value="SELECTIVE" />
5
  </component>
6
  <component name="ChangeListManager">
7
- <list default="true" id="5e4481c0-7ba2-42e4-bbe6-4c36a0d36baa" name="Changes" comment="done!!!">
8
  <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
9
  <change beforePath="$PROJECT_DIR$/1.txt" beforeDir="false" afterPath="$PROJECT_DIR$/1.txt" afterDir="false" />
 
10
  <change beforePath="$PROJECT_DIR$/CDM/detect_compo/lib_ip/ip_draw.py" beforeDir="false" afterPath="$PROJECT_DIR$/CDM/detect_compo/lib_ip/ip_draw.py" afterDir="false" />
 
 
11
  <change beforePath="$PROJECT_DIR$/CDM/run_single.py" beforeDir="false" afterPath="$PROJECT_DIR$/CDM/run_single.py" afterDir="false" />
 
 
 
 
 
 
 
 
 
12
  <change beforePath="$PROJECT_DIR$/app.py" beforeDir="false" afterPath="$PROJECT_DIR$/app.py" afterDir="false" />
13
  <change beforePath="$PROJECT_DIR$/logs/app.log" beforeDir="false" afterPath="$PROJECT_DIR$/logs/app.log" afterDir="false" />
14
- <change beforePath="$PROJECT_DIR$/logs/app.log.2024-08-20" beforeDir="false" />
15
  </list>
16
  <option name="SHOW_DIALOG" value="false" />
17
  <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -40,22 +51,27 @@
40
  <option name="hideEmptyMiddlePackages" value="true" />
41
  <option name="showLibraryContents" value="true" />
42
  </component>
43
- <component name="PropertiesComponent">{
44
- &quot;keyToString&quot;: {
45
- &quot;DefaultHtmlFileTemplate&quot;: &quot;HTML File&quot;,
46
- &quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
47
- &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
48
- &quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
49
- &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
50
- &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
51
- &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
52
- &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
53
- &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
54
- &quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
 
55
  }
56
- }</component>
57
  <component name="RecentsManager">
 
 
 
58
  <key name="MoveFile.RECENT_KEYS">
 
59
  <recent name="$PROJECT_DIR$" />
60
  <recent name="$PROJECT_DIR$/web_design" />
61
  <recent name="$PROJECT_DIR$/google_drive_credentials" />
@@ -102,14 +118,7 @@
102
  <workItem from="1723386970626" duration="451000" />
103
  <workItem from="1723387453009" duration="27328000" />
104
  <workItem from="1723978405562" duration="51637000" />
105
- <workItem from="1725925225487" duration="3142000" />
106
- </task>
107
- <task id="LOCAL-00006" summary="dubug">
108
- <created>1723390353091</created>
109
- <option name="number" value="00006" />
110
- <option name="presentableId" value="LOCAL-00006" />
111
- <option name="project" value="LOCAL" />
112
- <updated>1723390353091</updated>
113
  </task>
114
  <task id="LOCAL-00007" summary="debug">
115
  <created>1723390589691</created>
@@ -447,7 +456,14 @@
447
  <option name="project" value="LOCAL" />
448
  <updated>1724164812860</updated>
449
  </task>
450
- <option name="localTasksCounter" value="55" />
 
 
 
 
 
 
 
451
  <servers />
452
  </component>
453
  <component name="TypeScriptGeneratedFilesManager">
@@ -470,9 +486,10 @@
470
  <MESSAGE value="js" />
471
  <MESSAGE value="test" />
472
  <MESSAGE value="done!!!" />
473
- <option name="LAST_COMMIT_MESSAGE" value="done!!!" />
 
474
  </component>
475
  <component name="com.intellij.coverage.CoverageDataManagerImpl">
476
- <SUITE FILE_PATH="coverage/Cpp4App_test$app.coverage" NAME="app Coverage Results" MODIFIED="1724321346655" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
477
  </component>
478
  </project>
 
4
  <option name="autoReloadType" value="SELECTIVE" />
5
  </component>
6
  <component name="ChangeListManager">
7
+ <list default="true" id="5e4481c0-7ba2-42e4-bbe6-4c36a0d36baa" name="Changes" comment="output img type">
8
  <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
9
  <change beforePath="$PROJECT_DIR$/1.txt" beforeDir="false" afterPath="$PROJECT_DIR$/1.txt" afterDir="false" />
10
+ <change beforePath="$PROJECT_DIR$/CDM/detect_classify/classification.py" beforeDir="false" afterPath="$PROJECT_DIR$/CDM/detect_classify/classification.py" afterDir="false" />
11
  <change beforePath="$PROJECT_DIR$/CDM/detect_compo/lib_ip/ip_draw.py" beforeDir="false" afterPath="$PROJECT_DIR$/CDM/detect_compo/lib_ip/ip_draw.py" afterDir="false" />
12
+ <change beforePath="$PROJECT_DIR$/CDM/detect_merge/Element.py" beforeDir="false" afterPath="$PROJECT_DIR$/CDM/detect_merge/Element.py" afterDir="false" />
13
+ <change beforePath="$PROJECT_DIR$/CDM/detect_merge/merge.py" beforeDir="false" afterPath="$PROJECT_DIR$/CDM/detect_merge/merge.py" afterDir="false" />
14
  <change beforePath="$PROJECT_DIR$/CDM/run_single.py" beforeDir="false" afterPath="$PROJECT_DIR$/CDM/run_single.py" afterDir="false" />
15
+ <change beforePath="$PROJECT_DIR$/SEM/get_text.py" beforeDir="false" afterPath="$PROJECT_DIR$/SEM/get_text.py" afterDir="false" />
16
+ <change beforePath="$PROJECT_DIR$/SEM/run_single_sem.py" beforeDir="false" afterPath="$PROJECT_DIR$/SEM/run_single_sem.py" afterDir="false" />
17
+ <change beforePath="$PROJECT_DIR$/SEM/txt/1/children.txt" beforeDir="false" afterPath="$PROJECT_DIR$/SEM/txt/1/children.txt" afterDir="false" />
18
+ <change beforePath="$PROJECT_DIR$/SEM/txt/1/data_types.txt" beforeDir="false" afterPath="$PROJECT_DIR$/SEM/txt/1/data_types.txt" afterDir="false" />
19
+ <change beforePath="$PROJECT_DIR$/SEM/txt/1/protect_information.txt" beforeDir="false" afterPath="$PROJECT_DIR$/SEM/txt/1/protect_information.txt" afterDir="false" />
20
+ <change beforePath="$PROJECT_DIR$/SEM/txt/1/share_information.txt" beforeDir="false" afterPath="$PROJECT_DIR$/SEM/txt/1/share_information.txt" afterDir="false" />
21
+ <change beforePath="$PROJECT_DIR$/SEM/txt/1/thrid_party.txt" beforeDir="false" afterPath="$PROJECT_DIR$/SEM/txt/1/thrid_party.txt" afterDir="false" />
22
+ <change beforePath="$PROJECT_DIR$/SEM/txt/1/update.txt" beforeDir="false" afterPath="$PROJECT_DIR$/SEM/txt/1/update.txt" afterDir="false" />
23
+ <change beforePath="$PROJECT_DIR$/SEM/txt/1/user_right.txt" beforeDir="false" afterPath="$PROJECT_DIR$/SEM/txt/1/user_right.txt" afterDir="false" />
24
  <change beforePath="$PROJECT_DIR$/app.py" beforeDir="false" afterPath="$PROJECT_DIR$/app.py" afterDir="false" />
25
  <change beforePath="$PROJECT_DIR$/logs/app.log" beforeDir="false" afterPath="$PROJECT_DIR$/logs/app.log" afterDir="false" />
 
26
  </list>
27
  <option name="SHOW_DIALOG" value="false" />
28
  <option name="HIGHLIGHT_CONFLICTS" value="true" />
 
51
  <option name="hideEmptyMiddlePackages" value="true" />
52
  <option name="showLibraryContents" value="true" />
53
  </component>
54
+ <component name="PropertiesComponent"><![CDATA[{
55
+ "keyToString": {
56
+ "DefaultHtmlFileTemplate": "HTML File",
57
+ "RunOnceActivity.OpenProjectViewOnStart": "true",
58
+ "RunOnceActivity.ShowReadmeOnStart": "true",
59
+ "WebServerToolWindowFactoryState": "false",
60
+ "last_opened_file_path": "/Users/hika/ANU/2024 s2/8800/Cpp4App_test/CDM/detect_merge",
61
+ "node.js.detected.package.eslint": "true",
62
+ "node.js.detected.package.tslint": "true",
63
+ "node.js.selected.package.eslint": "(autodetect)",
64
+ "node.js.selected.package.tslint": "(autodetect)",
65
+ "nodejs_package_manager_path": "npm",
66
+ "vue.rearranger.settings.migration": "true"
67
  }
68
+ }]]></component>
69
  <component name="RecentsManager">
70
+ <key name="CopyFile.RECENT_KEYS">
71
+ <recent name="$PROJECT_DIR$/CDM/detect_merge" />
72
+ </key>
73
  <key name="MoveFile.RECENT_KEYS">
74
+ <recent name="$PROJECT_DIR$/CDM/detect_merge" />
75
  <recent name="$PROJECT_DIR$" />
76
  <recent name="$PROJECT_DIR$/web_design" />
77
  <recent name="$PROJECT_DIR$/google_drive_credentials" />
 
118
  <workItem from="1723386970626" duration="451000" />
119
  <workItem from="1723387453009" duration="27328000" />
120
  <workItem from="1723978405562" duration="51637000" />
121
+ <workItem from="1725925225487" duration="133865000" />
 
 
 
 
 
 
 
122
  </task>
123
  <task id="LOCAL-00007" summary="debug">
124
  <created>1723390589691</created>
 
456
  <option name="project" value="LOCAL" />
457
  <updated>1724164812860</updated>
458
  </task>
459
+ <task id="LOCAL-00055" summary="output img type">
460
+ <created>1725928977864</created>
461
+ <option name="number" value="00055" />
462
+ <option name="presentableId" value="LOCAL-00055" />
463
+ <option name="project" value="LOCAL" />
464
+ <updated>1725928977865</updated>
465
+ </task>
466
+ <option name="localTasksCounter" value="56" />
467
  <servers />
468
  </component>
469
  <component name="TypeScriptGeneratedFilesManager">
 
486
  <MESSAGE value="js" />
487
  <MESSAGE value="test" />
488
  <MESSAGE value="done!!!" />
489
+ <MESSAGE value="output img type" />
490
+ <option name="LAST_COMMIT_MESSAGE" value="output img type" />
491
  </component>
492
  <component name="com.intellij.coverage.CoverageDataManagerImpl">
493
+ <SUITE FILE_PATH="coverage/Cpp4App_test$app.coverage" NAME="app Coverage Results" MODIFIED="1728910172560" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
494
  </component>
495
  </project>
1.txt CHANGED
@@ -46,50 +46,50 @@
46
  <link rel="apple-touch-icon" href="/sites/all/themes/mcdonalds/images/apple-touch-icon.png"/>
47
  <link href="//fonts.googleapis.com/css?family=Lato:400,300,700,900,100" rel="stylesheet" type="text/css">
48
  <style type="text/css" media="all">
49
- @import url("https://mcdonalds.com.au/modules/system/system.base.css?sihwea");
50
- @import url("https://mcdonalds.com.au/modules/system/system.menus.css?sihwea");
51
- @import url("https://mcdonalds.com.au/modules/system/system.messages.css?sihwea");
52
- @import url("https://mcdonalds.com.au/modules/system/system.theme.css?sihwea");
53
  </style>
54
  <style type="text/css" media="all">
55
- @import url("https://mcdonalds.com.au/sites/all/modules/blazy/css/blazy.css?sihwea");
56
- @import url("https://mcdonalds.com.au/sites/all/modules/blazy/css/components/blazy.filter.css?sihwea");
57
- @import url("https://mcdonalds.com.au/sites/all/modules/blazy/css/components/blazy.ratio.css?sihwea");
58
- @import url("https://mcdonalds.com.au/sites/all/modules/blazy/css/components/blazy.loading.css?sihwea");
59
  </style>
60
  <style type="text/css" media="all">
61
- @import url("https://mcdonalds.com.au/sites/all/modules/date/date_api/date.css?sihwea");
62
- @import url("https://mcdonalds.com.au/sites/all/modules/date/date_popup/themes/datepicker.1.7.css?sihwea");
63
- @import url("https://mcdonalds.com.au/modules/field/theme/field.css?sihwea");
64
- @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_afl_gather_round/css/mcd_afl_gather_round.css?sihwea");
65
- @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_fathers_day/css/mcd_fathers_day.css?sihwea");
66
- @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_mcfeast/css/mcd_mcfeast.css?sihwea");
67
- @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_mothers_day/css/mcd_mothers_day.css?sihwea");
68
- @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_nuggies/css/mcd_nuggies.css?sihwea");
69
- @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_product/css/mcd-product.css?sihwea");
70
- @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_sauce_trail_form/css/mcd_sauce_trail_form.css?sihwea");
71
- @import url("https://mcdonalds.com.au/modules/node/node.css?sihwea");
72
- @import url("https://mcdonalds.com.au/modules/search/search.css?sihwea");
73
- @import url("https://mcdonalds.com.au/modules/user/user.css?sihwea");
74
- @import url("https://mcdonalds.com.au/sites/all/modules/views/css/views.css?sihwea");
75
  </style>
76
  <style type="text/css" media="all">
77
- @import url("https://mcdonalds.com.au/sites/all/modules/ctools/css/ctools.css?sihwea");
78
- @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_lite_youtube_embed/css/lite-yt-embed.css?sihwea");
79
- @import url("https://mcdonalds.com.au/sites/all/modules/_patched/dismiss/css/dismiss.base.css?sihwea");
80
  </style>
81
  <style type="text/css" media="all">
82
- @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/bootstrap.min.css?sihwea");
83
- @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/flexslider.css?sihwea");
84
- @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/main.css?sihwea");
85
- @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/main2.css?sihwea");
86
- @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/theme.css?sihwea");
87
- @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/hamburgers.css?sihwea");
88
- @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/main-responsive.css?sihwea");
89
- @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/animate.css?sihwea");
90
  </style>
91
  <style type="text/css" media="all">
92
- @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/jquery.smartbanner.css?sihwea");
93
  </style>
94
  <style type="text/css" media="all">
95
  <!--/*--><![CDATA[/*><!--*/
@@ -99,35 +99,35 @@
99
  </style>
100
 
101
  <!--[if lte IE 8]>
102
- <link type="text/css" rel="stylesheet" href="https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/ie8.css?sihwea" media="all" />
103
  <![endif]-->
104
 
105
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/jquery-3.7.0.min.js?v=3.7.0"></script>
106
  <script type="text/javascript" src="https://mcdonalds.com.au/misc/jquery-extend-3.4.0.js?v=3.7.0"></script>
107
  <script type="text/javascript" src="https://mcdonalds.com.au/misc/jquery-html-prefilter-3.5.0-backport.js?v=3.7.0"></script>
108
  <script type="text/javascript" src="https://mcdonalds.com.au/misc/jquery.once.js?v=1.2"></script>
109
- <script type="text/javascript" src="https://mcdonalds.com.au/misc/drupal.js?sihwea"></script>
110
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/libraries/blazy/blazy.min.js?sihwea"></script>
111
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/jquery_update/js/jquery_browser.js?v=0.0.1"></script>
112
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/blazy/js/dblazy.min.js?v=7.x-1.2"></script>
113
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/blazy/js/bio.min.js?v=7.x-1.2"></script>
114
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/blazy/js/bio.media.min.js?v=7.x-1.2"></script>
115
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/blazy/js/blazy.load.min.js?v=7.x-1.2"></script>
116
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_afl_gather_round/js/mcd_afl_gather_round.js?sihwea"></script>
117
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_fathers_day/js/mcd_fathers_day.js?sihwea"></script>
118
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_mcfeast/js/mcd_mcfeast.js?sihwea"></script>
119
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_mothers_day/js/mcd_mothers_day.js?sihwea"></script>
120
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_nuggies/js/mcd_nuggies.js?sihwea"></script>
121
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_sauce_trail_form/js/mcd_sauce_trail_form.js?sihwea"></script>
122
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/lazy/lazy.js?sihwea"></script>
123
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_lite_youtube_embed/js/lite-yt-embed.js?sihwea"></script>
124
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/jquery.waypoints.min.js?sihwea"></script>
125
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/anime.min.js?sihwea"></script>
126
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/jquery.viewportchecker.min.js?sihwea"></script>
127
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/jquery_update/js/jquery_position.js?v=0.0.1"></script>
128
  <script type="text/javascript">
129
  <!--//--><![CDATA[//><!--
130
- jQuery.extend(Drupal.settings, {"basePath":"\/","pathPrefix":"","setHasJsCookie":0,"ajaxPageState":{"theme":"mcdonalds","theme_token":"y6eZI4B0jB5BaRXEIi4S5HrOr5sic9TL9cNwrVA6l6g","js":{"0":1,"sites\/all\/themes\/mcdonalds\/js\/plugins.js":1,"sites\/all\/themes\/mcdonalds\/js\/script.js":1,"sites\/all\/themes\/mcdonalds\/js\/jquery.smartbanner.js":1,"sites\/all\/themes\/mcdonalds\/js\/jquery-3.7.0.min.js":1,"misc\/jquery-extend-3.4.0.js":1,"misc\/jquery-html-prefilter-3.5.0-backport.js":1,"misc\/jquery.once.js":1,"misc\/drupal.js":1,"sites\/all\/libraries\/blazy\/blazy.min.js":1,"sites\/all\/modules\/jquery_update\/js\/jquery_browser.js":1,"sites\/all\/modules\/blazy\/js\/dblazy.min.js":1,"sites\/all\/modules\/blazy\/js\/bio.min.js":1,"sites\/all\/modules\/blazy\/js\/bio.media.min.js":1,"sites\/all\/modules\/blazy\/js\/blazy.load.min.js":1,"sites\/all\/modules\/mcd\/mcd_afl_gather_round\/js\/mcd_afl_gather_round.js":1,"sites\/all\/modules\/mcd\/mcd_fathers_day\/js\/mcd_fathers_day.js":1,"sites\/all\/modules\/mcd\/mcd_mcfeast\/js\/mcd_mcfeast.js":1,"sites\/all\/modules\/mcd\/mcd_mothers_day\/js\/mcd_mothers_day.js":1,"sites\/all\/modules\/mcd\/mcd_nuggies\/js\/mcd_nuggies.js":1,"sites\/all\/modules\/mcd\/mcd_sauce_trail_form\/js\/mcd_sauce_trail_form.js":1,"sites\/all\/modules\/lazy\/lazy.js":1,"sites\/all\/modules\/mcd\/mcd_lite_youtube_embed\/js\/lite-yt-embed.js":1,"sites\/all\/themes\/mcdonalds\/js\/jquery.waypoints.min.js":1,"sites\/all\/themes\/mcdonalds\/js\/anime.min.js":1,"sites\/all\/themes\/mcdonalds\/js\/jquery.viewportchecker.min.js":1,"sites\/all\/modules\/jquery_update\/js\/jquery_position.js":1},"css":{"modules\/system\/system.base.css":1,"modules\/system\/system.menus.css":1,"modules\/system\/system.messages.css":1,"modules\/system\/system.theme.css":1,"sites\/all\/modules\/blazy\/css\/blazy.css":1,"sites\/all\/modules\/blazy\/css\/components\/blazy.filter.css":1,"sites\/all\/modules\/blazy\/css\/components\/blazy.ratio.css":1,"sites\/all\/modules\/blazy\/css\/components\/blazy.loading.css":1,"sites\/all\/modules\/date\/date_api\/date.css":1,"sites\/all\/modules\/date\/date_popup\/themes\/datepicker.1.7.css":1,"modules\/field\/theme\/field.css":1,"sites\/all\/modules\/mcd\/mcd_afl_gather_round\/css\/mcd_afl_gather_round.css":1,"sites\/all\/modules\/mcd\/mcd_fathers_day\/css\/mcd_fathers_day.css":1,"sites\/all\/modules\/mcd\/mcd_mcfeast\/css\/mcd_mcfeast.css":1,"sites\/all\/modules\/mcd\/mcd_mothers_day\/css\/mcd_mothers_day.css":1,"sites\/all\/modules\/mcd\/mcd_nuggies\/css\/mcd_nuggies.css":1,"sites\/all\/modules\/mcd\/mcd_product\/css\/mcd-product.css":1,"sites\/all\/modules\/mcd\/mcd_sauce_trail_form\/css\/mcd_sauce_trail_form.css":1,"modules\/node\/node.css":1,"modules\/search\/search.css":1,"modules\/user\/user.css":1,"sites\/all\/modules\/views\/css\/views.css":1,"sites\/all\/modules\/ctools\/css\/ctools.css":1,"sites\/all\/modules\/mcd\/mcd_lite_youtube_embed\/css\/lite-yt-embed.css":1,"sites\/all\/modules\/_patched\/dismiss\/css\/dismiss.base.css":1,"sites\/all\/themes\/mcdonalds\/css\/bootstrap.min.css":1,"sites\/all\/themes\/mcdonalds\/css\/flexslider.css":1,"sites\/all\/themes\/mcdonalds\/css\/main.css":1,"sites\/all\/themes\/mcdonalds\/css\/main2.css":1,"sites\/all\/themes\/mcdonalds\/css\/theme.css":1,"sites\/all\/themes\/mcdonalds\/css\/hamburgers.css":1,"sites\/all\/themes\/mcdonalds\/css\/main-responsive.css":1,"sites\/all\/themes\/mcdonalds\/css\/animate.css":1,"sites\/all\/themes\/mcdonalds\/css\/jquery.smartbanner.css":1,"0":1,"sites\/all\/themes\/mcdonalds\/css\/ie8.css":1}},"dismiss":{"fadeout":"2000"},"mcd":{"current_url":"https:\/\/mcdonalds.com.au\/privacy-policy","theme_url":"\/sites\/all\/themes\/mcdonalds","pane_visible_time":{"night":"18:00-23:59","other":"00:01-17:59","morning":"23:59-00:00"},"pane_visible_weather":{"cold":"\u003C25","hot":"\u003E25"}},"maccasapp_id":"other","blazy":{"loadInvisible":false,"offset":100,"saveViewportOffsetDelay":50,"validateDelay":25,"container":""},"blazyIo":{"enabled":false,"disconnect":false,"rootMargin":"0px","threshold":[0]},"lazy":{"errorClass":"b-error","loadInvisible":false,"offset":100,"saveViewportOffsetDelay":50,"selector":".b-lazy","src":"data-src","successClass":"b-loaded","validateDelay":25}});
131
  //--><!]]>
132
  </script>
133
  <!--[if lt IE 9]>
@@ -316,6 +316,8 @@ jQuery.extend(Drupal.settings, {"basePath":"\/","pathPrefix":"","setHasJsCookie"
316
  <li class="last expanded"><span class="nolink" tabindex="0">Faves</span><ul class="menu"><li class="first leaf"><a href="/menu/happy-meal">Happy Meal®</a></li>
317
  <li class="leaf"><a href="/menu/maccas-bundle-range">Bundle Range</a></li>
318
  <li class="leaf"><a href="/the-mcsmart-meal">The McSmart™ Meal</a></li>
 
 
319
  <li class="last leaf"><a href="https://mcdonalds.com.au/loose-change-menu">Loose Change Menu®</a></li>
320
  </ul></li>
321
  </ul> </div>
@@ -967,8 +969,8 @@ jQuery.extend(Drupal.settings, {"basePath":"\/","pathPrefix":"","setHasJsCookie"
967
 
968
  //--><!]]>
969
  </script>
970
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/plugins.js?sihwea"></script>
971
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/script.js?sihwea"></script>
972
- <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/jquery.smartbanner.js?sihwea"></script>
973
  </body>
974
  </html>
 
46
  <link rel="apple-touch-icon" href="/sites/all/themes/mcdonalds/images/apple-touch-icon.png"/>
47
  <link href="//fonts.googleapis.com/css?family=Lato:400,300,700,900,100" rel="stylesheet" type="text/css">
48
  <style type="text/css" media="all">
49
+ @import url("https://mcdonalds.com.au/modules/system/system.base.css?skt6sp");
50
+ @import url("https://mcdonalds.com.au/modules/system/system.menus.css?skt6sp");
51
+ @import url("https://mcdonalds.com.au/modules/system/system.messages.css?skt6sp");
52
+ @import url("https://mcdonalds.com.au/modules/system/system.theme.css?skt6sp");
53
  </style>
54
  <style type="text/css" media="all">
55
+ @import url("https://mcdonalds.com.au/sites/all/modules/blazy/css/blazy.css?skt6sp");
56
+ @import url("https://mcdonalds.com.au/sites/all/modules/blazy/css/components/blazy.filter.css?skt6sp");
57
+ @import url("https://mcdonalds.com.au/sites/all/modules/blazy/css/components/blazy.ratio.css?skt6sp");
58
+ @import url("https://mcdonalds.com.au/sites/all/modules/blazy/css/components/blazy.loading.css?skt6sp");
59
  </style>
60
  <style type="text/css" media="all">
61
+ @import url("https://mcdonalds.com.au/sites/all/modules/date/date_api/date.css?skt6sp");
62
+ @import url("https://mcdonalds.com.au/sites/all/modules/date/date_popup/themes/datepicker.1.7.css?skt6sp");
63
+ @import url("https://mcdonalds.com.au/modules/field/theme/field.css?skt6sp");
64
+ @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_afl_gather_round/css/mcd_afl_gather_round.css?skt6sp");
65
+ @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_fathers_day/css/mcd_fathers_day.css?skt6sp");
66
+ @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_mcfeast/css/mcd_mcfeast.css?skt6sp");
67
+ @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_mothers_day/css/mcd_mothers_day.css?skt6sp");
68
+ @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_nuggies/css/mcd_nuggies.css?skt6sp");
69
+ @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_product/css/mcd-product.css?skt6sp");
70
+ @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_sauce_trail_form/css/mcd_sauce_trail_form.css?skt6sp");
71
+ @import url("https://mcdonalds.com.au/modules/node/node.css?skt6sp");
72
+ @import url("https://mcdonalds.com.au/modules/search/search.css?skt6sp");
73
+ @import url("https://mcdonalds.com.au/modules/user/user.css?skt6sp");
74
+ @import url("https://mcdonalds.com.au/sites/all/modules/views/css/views.css?skt6sp");
75
  </style>
76
  <style type="text/css" media="all">
77
+ @import url("https://mcdonalds.com.au/sites/all/modules/ctools/css/ctools.css?skt6sp");
78
+ @import url("https://mcdonalds.com.au/sites/all/modules/mcd/mcd_lite_youtube_embed/css/lite-yt-embed.css?skt6sp");
79
+ @import url("https://mcdonalds.com.au/sites/all/modules/_patched/dismiss/css/dismiss.base.css?skt6sp");
80
  </style>
81
  <style type="text/css" media="all">
82
+ @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/bootstrap.min.css?skt6sp");
83
+ @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/flexslider.css?skt6sp");
84
+ @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/main.css?skt6sp");
85
+ @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/main2.css?skt6sp");
86
+ @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/theme.css?skt6sp");
87
+ @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/hamburgers.css?skt6sp");
88
+ @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/main-responsive.css?skt6sp");
89
+ @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/animate.css?skt6sp");
90
  </style>
91
  <style type="text/css" media="all">
92
+ @import url("https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/jquery.smartbanner.css?skt6sp");
93
  </style>
94
  <style type="text/css" media="all">
95
  <!--/*--><![CDATA[/*><!--*/
 
99
  </style>
100
 
101
  <!--[if lte IE 8]>
102
+ <link type="text/css" rel="stylesheet" href="https://mcdonalds.com.au/sites/all/themes/mcdonalds/css/ie8.css?skt6sp" media="all" />
103
  <![endif]-->
104
 
105
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/jquery-3.7.0.min.js?v=3.7.0"></script>
106
  <script type="text/javascript" src="https://mcdonalds.com.au/misc/jquery-extend-3.4.0.js?v=3.7.0"></script>
107
  <script type="text/javascript" src="https://mcdonalds.com.au/misc/jquery-html-prefilter-3.5.0-backport.js?v=3.7.0"></script>
108
  <script type="text/javascript" src="https://mcdonalds.com.au/misc/jquery.once.js?v=1.2"></script>
109
+ <script type="text/javascript" src="https://mcdonalds.com.au/misc/drupal.js?skt6sp"></script>
110
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/libraries/blazy/blazy.min.js?skt6sp"></script>
111
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/jquery_update/js/jquery_browser.js?v=0.0.1"></script>
112
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/blazy/js/dblazy.min.js?v=7.x-1.2"></script>
113
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/blazy/js/bio.min.js?v=7.x-1.2"></script>
114
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/blazy/js/bio.media.min.js?v=7.x-1.2"></script>
115
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/blazy/js/blazy.load.min.js?v=7.x-1.2"></script>
116
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_afl_gather_round/js/mcd_afl_gather_round.js?skt6sp"></script>
117
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_fathers_day/js/mcd_fathers_day.js?skt6sp"></script>
118
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_mcfeast/js/mcd_mcfeast.js?skt6sp"></script>
119
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_mothers_day/js/mcd_mothers_day.js?skt6sp"></script>
120
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_nuggies/js/mcd_nuggies.js?skt6sp"></script>
121
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_sauce_trail_form/js/mcd_sauce_trail_form.js?skt6sp"></script>
122
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/lazy/lazy.js?skt6sp"></script>
123
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/mcd/mcd_lite_youtube_embed/js/lite-yt-embed.js?skt6sp"></script>
124
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/jquery.waypoints.min.js?skt6sp"></script>
125
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/anime.min.js?skt6sp"></script>
126
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/jquery.viewportchecker.min.js?skt6sp"></script>
127
  <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/modules/jquery_update/js/jquery_position.js?v=0.0.1"></script>
128
  <script type="text/javascript">
129
  <!--//--><![CDATA[//><!--
130
+ jQuery.extend(Drupal.settings, {"basePath":"\/","pathPrefix":"","setHasJsCookie":0,"ajaxPageState":{"theme":"mcdonalds","theme_token":"tNQ2h_NAOR1F1de6CgnHG1rTQUSN7Ibn6OkUBfYRgyM","js":{"0":1,"sites\/all\/themes\/mcdonalds\/js\/plugins.js":1,"sites\/all\/themes\/mcdonalds\/js\/script.js":1,"sites\/all\/themes\/mcdonalds\/js\/jquery.smartbanner.js":1,"sites\/all\/themes\/mcdonalds\/js\/jquery-3.7.0.min.js":1,"misc\/jquery-extend-3.4.0.js":1,"misc\/jquery-html-prefilter-3.5.0-backport.js":1,"misc\/jquery.once.js":1,"misc\/drupal.js":1,"sites\/all\/libraries\/blazy\/blazy.min.js":1,"sites\/all\/modules\/jquery_update\/js\/jquery_browser.js":1,"sites\/all\/modules\/blazy\/js\/dblazy.min.js":1,"sites\/all\/modules\/blazy\/js\/bio.min.js":1,"sites\/all\/modules\/blazy\/js\/bio.media.min.js":1,"sites\/all\/modules\/blazy\/js\/blazy.load.min.js":1,"sites\/all\/modules\/mcd\/mcd_afl_gather_round\/js\/mcd_afl_gather_round.js":1,"sites\/all\/modules\/mcd\/mcd_fathers_day\/js\/mcd_fathers_day.js":1,"sites\/all\/modules\/mcd\/mcd_mcfeast\/js\/mcd_mcfeast.js":1,"sites\/all\/modules\/mcd\/mcd_mothers_day\/js\/mcd_mothers_day.js":1,"sites\/all\/modules\/mcd\/mcd_nuggies\/js\/mcd_nuggies.js":1,"sites\/all\/modules\/mcd\/mcd_sauce_trail_form\/js\/mcd_sauce_trail_form.js":1,"sites\/all\/modules\/lazy\/lazy.js":1,"sites\/all\/modules\/mcd\/mcd_lite_youtube_embed\/js\/lite-yt-embed.js":1,"sites\/all\/themes\/mcdonalds\/js\/jquery.waypoints.min.js":1,"sites\/all\/themes\/mcdonalds\/js\/anime.min.js":1,"sites\/all\/themes\/mcdonalds\/js\/jquery.viewportchecker.min.js":1,"sites\/all\/modules\/jquery_update\/js\/jquery_position.js":1},"css":{"modules\/system\/system.base.css":1,"modules\/system\/system.menus.css":1,"modules\/system\/system.messages.css":1,"modules\/system\/system.theme.css":1,"sites\/all\/modules\/blazy\/css\/blazy.css":1,"sites\/all\/modules\/blazy\/css\/components\/blazy.filter.css":1,"sites\/all\/modules\/blazy\/css\/components\/blazy.ratio.css":1,"sites\/all\/modules\/blazy\/css\/components\/blazy.loading.css":1,"sites\/all\/modules\/date\/date_api\/date.css":1,"sites\/all\/modules\/date\/date_popup\/themes\/datepicker.1.7.css":1,"modules\/field\/theme\/field.css":1,"sites\/all\/modules\/mcd\/mcd_afl_gather_round\/css\/mcd_afl_gather_round.css":1,"sites\/all\/modules\/mcd\/mcd_fathers_day\/css\/mcd_fathers_day.css":1,"sites\/all\/modules\/mcd\/mcd_mcfeast\/css\/mcd_mcfeast.css":1,"sites\/all\/modules\/mcd\/mcd_mothers_day\/css\/mcd_mothers_day.css":1,"sites\/all\/modules\/mcd\/mcd_nuggies\/css\/mcd_nuggies.css":1,"sites\/all\/modules\/mcd\/mcd_product\/css\/mcd-product.css":1,"sites\/all\/modules\/mcd\/mcd_sauce_trail_form\/css\/mcd_sauce_trail_form.css":1,"modules\/node\/node.css":1,"modules\/search\/search.css":1,"modules\/user\/user.css":1,"sites\/all\/modules\/views\/css\/views.css":1,"sites\/all\/modules\/ctools\/css\/ctools.css":1,"sites\/all\/modules\/mcd\/mcd_lite_youtube_embed\/css\/lite-yt-embed.css":1,"sites\/all\/modules\/_patched\/dismiss\/css\/dismiss.base.css":1,"sites\/all\/themes\/mcdonalds\/css\/bootstrap.min.css":1,"sites\/all\/themes\/mcdonalds\/css\/flexslider.css":1,"sites\/all\/themes\/mcdonalds\/css\/main.css":1,"sites\/all\/themes\/mcdonalds\/css\/main2.css":1,"sites\/all\/themes\/mcdonalds\/css\/theme.css":1,"sites\/all\/themes\/mcdonalds\/css\/hamburgers.css":1,"sites\/all\/themes\/mcdonalds\/css\/main-responsive.css":1,"sites\/all\/themes\/mcdonalds\/css\/animate.css":1,"sites\/all\/themes\/mcdonalds\/css\/jquery.smartbanner.css":1,"0":1,"sites\/all\/themes\/mcdonalds\/css\/ie8.css":1}},"dismiss":{"fadeout":"2000"},"mcd":{"current_url":"https:\/\/mcdonalds.com.au\/privacy-policy","theme_url":"\/sites\/all\/themes\/mcdonalds","pane_visible_time":{"night":"18:00-23:59","other":"00:01-17:59","morning":"23:59-00:00"},"pane_visible_weather":{"cold":"\u003C25","hot":"\u003E25"}},"maccasapp_id":"other","blazy":{"loadInvisible":false,"offset":100,"saveViewportOffsetDelay":50,"validateDelay":25,"container":""},"blazyIo":{"enabled":false,"disconnect":false,"rootMargin":"0px","threshold":[0]},"lazy":{"errorClass":"b-error","loadInvisible":false,"offset":100,"saveViewportOffsetDelay":50,"selector":".b-lazy","src":"data-src","successClass":"b-loaded","validateDelay":25}});
131
  //--><!]]>
132
  </script>
133
  <!--[if lt IE 9]>
 
316
  <li class="last expanded"><span class="nolink" tabindex="0">Faves</span><ul class="menu"><li class="first leaf"><a href="/menu/happy-meal">Happy Meal®</a></li>
317
  <li class="leaf"><a href="/menu/maccas-bundle-range">Bundle Range</a></li>
318
  <li class="leaf"><a href="/the-mcsmart-meal">The McSmart™ Meal</a></li>
319
+ <li class="leaf"><a href="/menu/maccas-mega-meal">Macca&#039;s® Mega Meal</a></li>
320
+ <li class="leaf"><a href="/menu/grimace-meal">The Grimace Meal</a></li>
321
  <li class="last leaf"><a href="https://mcdonalds.com.au/loose-change-menu">Loose Change Menu®</a></li>
322
  </ul></li>
323
  </ul> </div>
 
969
 
970
  //--><!]]>
971
  </script>
972
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/plugins.js?skt6sp"></script>
973
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/script.js?skt6sp"></script>
974
+ <script type="text/javascript" src="https://mcdonalds.com.au/sites/all/themes/mcdonalds/js/jquery.smartbanner.js?skt6sp"></script>
975
  </body>
976
  </html>
CDM/detect_classify/classification.py CHANGED
@@ -34,6 +34,33 @@ keyword_list = {'Name':['name', 'first name', 'last name', 'full name', 'real na
34
  'Profile':['profile', 'account'],
35
  'Gender':['gender']}
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  def get_data_type(sentence, keywords, use_gpt=True):
38
 
39
  sent_data_type = "others"
@@ -57,7 +84,7 @@ def get_data_type(sentence, keywords, use_gpt=True):
57
 
58
  response = openai.ChatCompletion.create(
59
  # engine="text-davinci-002",
60
- model="gpt-3.5-turbo",
61
  messages=[
62
  # {"role": "system", "content": "You are a helpful assistant."},
63
  {"role": "user", "content": prompt}
@@ -184,85 +211,153 @@ def compo_classification(input_img, output_root, segment_root, merge_json, outpu
184
 
185
  classification_start_time = time.process_time()
186
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  for compo in compos:
 
188
 
189
- # comp_grey = grey[compo.row_min:compo.row_max, compo.col_min:compo.col_max]
190
- #
191
- # comp_crop = cv2.resize(comp_grey, (32, 32))
192
- #
193
- # comp_crop = comp_crop.reshape(1, 1, 32, 32)
194
- #
195
- # comp_tensor = torch.tensor(comp_crop)
196
- # comp_tensor = comp_tensor.permute(0, 1, 3, 2)
197
- #
198
- # model = get_clf_model()
199
- # pred_label = model(comp_tensor)
200
- #
201
- # if str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0]) in label_dic.keys():
202
- # compo.label = label_dic[str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0])]
203
- # elements.append(compo)
204
- # else:
205
- # compo.label = str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0])
206
 
 
 
207
  if clf_model == "ResNet18":
208
-
209
- comp_grey = grey[compo.row_min:compo.row_max, compo.col_min:compo.col_max]
210
-
211
  comp_crop = cv2.resize(comp_grey, (32, 32))
 
 
 
212
 
 
 
 
213
  comp_crop = comp_crop.reshape(1, 1, 32, 32)
214
-
215
  comp_tensor = torch.tensor(comp_crop)
216
  comp_tensor = comp_tensor.permute(0, 1, 3, 2)
217
-
218
- model = get_clf_model(clf_model)
219
- pred_label = model(comp_tensor)
220
-
221
- if str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0]) in label_dic.keys():
222
- compo.label = label_dic[str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0])]
223
- elements.append(compo)
224
- else:
225
- compo.label = str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0])
226
-
227
  elif clf_model == "ViT":
228
-
229
- comp_grey = grey[compo.row_min:compo.row_max, compo.col_min:compo.col_max]
230
-
231
- comp_crop = cv2.resize(comp_grey, (224, 224))
232
-
233
- # Convert the image to tensor
234
  comp_tensor = torch.from_numpy(comp_crop)
235
-
236
- # Reshape and repeat along the channel dimension to convert to RGB
237
  comp_tensor = comp_tensor.view(1, 224, 224).repeat(3, 1, 1)
238
-
239
- # comp_tensor = comp_tensor.permute(0, 2, 1)
240
-
241
- comp_tensor = comp_tensor.unsqueeze(0) # add a batch dimension
242
-
243
- model = get_clf_model(clf_model)
244
- # pred_label = model(comp_tensor)
245
-
246
- # Forward pass through the model
247
- with torch.no_grad():
248
  output = model(comp_tensor)
 
249
 
250
- # Get the predicted label
 
 
 
 
251
  _, predicted = torch.max(output.logits, 1)
 
252
 
253
- # print("predicted_label: ", predicted.cpu().numpy())
 
 
 
 
 
254
 
255
- if str(predicted.cpu().numpy()[0]) in label_dic.keys():
256
- compo.label = label_dic[str(predicted.cpu().numpy()[0])]
257
- elements.append(compo)
258
- else:
259
- compo.label = str(predicted.cpu().numpy()[0])
260
 
261
- else:
262
- print("clf_model has to be ResNet18 or ViT")
 
 
 
 
 
 
 
263
 
264
  time_cost_ic = time.process_time() - classification_start_time
265
  print("time cost for icon classification: %2.2f s" % time_cost_ic)
 
266
  # ic_time_cost_all.append(time_cost_ic)
267
 
268
  # --------- end classification ----------
@@ -306,34 +401,13 @@ def compo_classification(input_img, output_root, segment_root, merge_json, outpu
306
 
307
  time_cost_ts = time.process_time() - text_selection_time
308
  print("time cost for text selection: %2.2f s" % time_cost_ts)
309
- # ts_time_cost_all.append(time_cost_ts)
310
-
311
- # ---------- end -------------------------------
312
-
313
- full_size_org, full_size_grey = pre.read_img(input_img)
314
- ratio = full_size_org.shape[0]/org.shape[0]
315
-
316
- show = False
317
- wait_key = 0
318
-
319
- reassign_ids(elements)
320
- board = merge.show_elements(full_size_org, elements, ratio, show=show, win_name='elements after merging', wait_key=wait_key, line=3)
321
- board_one_element = merge.show_one_element(full_size_org, elements, ratio, show=show, win_name='elements after merging', wait_key=wait_key, line=3)
322
-
323
- classification_root = pjoin(output_root, 'classification')
324
 
325
- # save all merged elements, clips and blank background
326
- name = input_img.replace('\\', '/').split('/')[-1][:-4]
327
- components = merge.save_elements(pjoin(classification_root, name + '.json'), elements, full_size_org.shape, ratio)
328
- cv2.imwrite(pjoin(classification_root, name + '.jpg'), board)
329
 
330
- print("len(board_one_element): ", len(board_one_element))
331
 
332
- for i in range(len(elements)):
333
- e_name = str(int(elements[i].id) + 1)
334
- cv2.imwrite(pjoin(classification_root + '/GUI', name + '-' + e_name + '.jpg'), board_one_element[i])
335
 
336
- print('[Classification Completed] Input: %s Output: %s' % (input_img, pjoin(classification_root, name + '.jpg')))
337
 
338
  # ---------- matching result -----------
339
 
@@ -350,7 +424,7 @@ def compo_classification(input_img, output_root, segment_root, merge_json, outpu
350
 
351
  for item in elements:
352
  complete_path = pjoin(segment_root, app_id, 'classified_sentences', item.label + '.txt')
353
- print("complete_path: ", complete_path)
354
 
355
  if exists(complete_path):
356
 
@@ -377,4 +451,83 @@ def compo_classification(input_img, output_root, segment_root, merge_json, outpu
377
  output_data = pd.concat([output_data, pd.DataFrame([{'screenshot': 's' + str(index), 'id': item.id + 1,
378
  'label': item.label, 'index': "None",
379
  'text': "No information!", 'sentences': "None"}])])
380
- return time_cost_ic, time_cost_ts, output_data, board
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  'Profile':['profile', 'account'],
35
  'Gender':['gender']}
36
 
37
+
38
+ def summarize_segment(segment, label, word_limit=20):
39
+ openai.api_key = os.environ.get('openai_key')
40
+
41
+ # 在提示中明确要求缩略后的段落字数不超过给定的字数
42
+ prompt = (
43
+ f"Extract key information from this paragraph related to the topic '{label}' "
44
+ f"in no more than {word_limit} words: \"{str(segment)}\". Without using phrases like 'Key information'. "
45
+
46
+ )
47
+
48
+ response = openai.ChatCompletion.create(
49
+ model="gpt-4o-mini",
50
+ messages=[
51
+ {"role": "user", "content": prompt}
52
+ ],
53
+ max_tokens=400, # 可以根据需要调整,确保能生成适当的长度
54
+ n=1,
55
+ stop=None,
56
+ temperature=0,
57
+ )
58
+
59
+ shortened_segment = response.choices[0].message['content'].strip()
60
+
61
+ return shortened_segment
62
+
63
+
64
  def get_data_type(sentence, keywords, use_gpt=True):
65
 
66
  sent_data_type = "others"
 
84
 
85
  response = openai.ChatCompletion.create(
86
  # engine="text-davinci-002",
87
+ model="gpt-4o-mini",
88
  messages=[
89
  # {"role": "system", "content": "You are a helpful assistant."},
90
  {"role": "user", "content": prompt}
 
211
 
212
  classification_start_time = time.process_time()
213
 
214
+ model = get_clf_model(clf_model)
215
+
216
+ # for compo in compos:
217
+ #
218
+ # # comp_grey = grey[compo.row_min:compo.row_max, compo.col_min:compo.col_max]
219
+ # #
220
+ # # comp_crop = cv2.resize(comp_grey, (32, 32))
221
+ # #
222
+ # # comp_crop = comp_crop.reshape(1, 1, 32, 32)
223
+ # #
224
+ # # comp_tensor = torch.tensor(comp_crop)
225
+ # # comp_tensor = comp_tensor.permute(0, 1, 3, 2)
226
+ # #
227
+ # # model = get_clf_model()
228
+ # # pred_label = model(comp_tensor)
229
+ # #
230
+ # # if str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0]) in label_dic.keys():
231
+ # # compo.label = label_dic[str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0])]
232
+ # # elements.append(compo)
233
+ # # else:
234
+ # # compo.label = str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0])
235
+ #
236
+ # if clf_model == "ResNet18":
237
+ #
238
+ # comp_grey = grey[compo.row_min:compo.row_max, compo.col_min:compo.col_max]
239
+ #
240
+ # comp_crop = cv2.resize(comp_grey, (32, 32))
241
+ #
242
+ # comp_crop = comp_crop.reshape(1, 1, 32, 32)
243
+ #
244
+ # comp_tensor = torch.tensor(comp_crop)
245
+ # comp_tensor = comp_tensor.permute(0, 1, 3, 2)
246
+ #
247
+ # # model = get_clf_model(clf_model)
248
+ # pred_label = model(comp_tensor)
249
+ #
250
+ # if str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0]) in label_dic.keys():
251
+ # compo.label = label_dic[str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0])]
252
+ # elements.append(compo)
253
+ # else:
254
+ # compo.label = str(np.argmax(pred_label.cpu().data.numpy(), axis=1)[0])
255
+ #
256
+ # elif clf_model == "ViT":
257
+ #
258
+ # comp_grey = grey[compo.row_min:compo.row_max, compo.col_min:compo.col_max]
259
+ #
260
+ # comp_crop = cv2.resize(comp_grey, (224, 224))
261
+ #
262
+ # # Convert the image to tensor
263
+ # comp_tensor = torch.from_numpy(comp_crop)
264
+ #
265
+ # # Reshape and repeat along the channel dimension to convert to RGB
266
+ # comp_tensor = comp_tensor.view(1, 224, 224).repeat(3, 1, 1)
267
+ #
268
+ # # comp_tensor = comp_tensor.permute(0, 2, 1)
269
+ #
270
+ # comp_tensor = comp_tensor.unsqueeze(0) # add a batch dimension
271
+ #
272
+ # # model = get_clf_model(clf_model)
273
+ # # pred_label = model(comp_tensor)
274
+ #
275
+ # # Forward pass through the model
276
+ # with torch.no_grad():
277
+ # output = model(comp_tensor)
278
+ #
279
+ # # Get the predicted label
280
+ # _, predicted = torch.max(output.logits, 1)
281
+ #
282
+ # # print("predicted_label: ", predicted.cpu().numpy())
283
+ #
284
+ # if str(predicted.cpu().numpy()[0]) in label_dic.keys():
285
+ # compo.label = label_dic[str(predicted.cpu().numpy()[0])]
286
+ # elements.append(compo)
287
+ # else:
288
+ # compo.label = str(predicted.cpu().numpy()[0])
289
+ #
290
+ # else:
291
+ # print("clf_model has to be ResNet18 or ViT")
292
+
293
  for compo in compos:
294
+ compo_start_time = time.process_time()
295
 
296
+ # 计时预处理部分
297
+ preprocess_start = time.process_time()
298
+ comp_grey = grey[compo.row_min:compo.row_max, compo.col_min:compo.col_max]
299
+ preprocess_time = time.process_time() - preprocess_start
 
 
 
 
 
 
 
 
 
 
 
 
 
300
 
301
+ # 计时图像调整部分
302
+ resize_start = time.process_time()
303
  if clf_model == "ResNet18":
 
 
 
304
  comp_crop = cv2.resize(comp_grey, (32, 32))
305
+ elif clf_model == "ViT":
306
+ comp_crop = cv2.resize(comp_grey, (224, 224))
307
+ resize_time = time.process_time() - resize_start
308
 
309
+ # 计时张量转换部分
310
+ tensor_start = time.process_time()
311
+ if clf_model == "ResNet18":
312
  comp_crop = comp_crop.reshape(1, 1, 32, 32)
 
313
  comp_tensor = torch.tensor(comp_crop)
314
  comp_tensor = comp_tensor.permute(0, 1, 3, 2)
 
 
 
 
 
 
 
 
 
 
315
  elif clf_model == "ViT":
 
 
 
 
 
 
316
  comp_tensor = torch.from_numpy(comp_crop)
 
 
317
  comp_tensor = comp_tensor.view(1, 224, 224).repeat(3, 1, 1)
318
+ comp_tensor = comp_tensor.unsqueeze(0)
319
+ tensor_time = time.process_time() - tensor_start
320
+
321
+ # 计时模型推理部分
322
+ inference_start = time.process_time()
323
+ with torch.no_grad():
324
+ if clf_model == "ResNet18":
325
+ pred_label = model(comp_tensor)
326
+ output = pred_label
327
+ elif clf_model == "ViT":
328
  output = model(comp_tensor)
329
+ inference_time = time.process_time() - inference_start
330
 
331
+ # 计时后处理部分
332
+ postprocess_start = time.process_time()
333
+ if clf_model == "ResNet18":
334
+ predicted = np.argmax(output.cpu().data.numpy(), axis=1)[0]
335
+ elif clf_model == "ViT":
336
  _, predicted = torch.max(output.logits, 1)
337
+ predicted = predicted.cpu().numpy()[0]
338
 
339
+ if str(predicted) in label_dic.keys():
340
+ compo.label = label_dic[str(predicted)]
341
+ elements.append(compo)
342
+ else:
343
+ compo.label = str(predicted)
344
+ postprocess_time = time.process_time() - postprocess_start
345
 
346
+ compo_total_time = time.process_time() - compo_start_time
 
 
 
 
347
 
348
+ # 输出每个部分的耗时
349
+ print("==============================================")
350
+ print(f"Component processing time: {compo_total_time:.4f}s")
351
+ print(f" Preprocessing time: {preprocess_time:.4f}s")
352
+ print(f" Resize time: {resize_time:.4f}s")
353
+ print(f" Tensor conversion time: {tensor_time:.4f}s")
354
+ print(f" Inference time: {inference_time:.4f}s")
355
+ print(f" Post-processing time: {postprocess_time:.4f}s\n")
356
+ print("==============================================")
357
 
358
  time_cost_ic = time.process_time() - classification_start_time
359
  print("time cost for icon classification: %2.2f s" % time_cost_ic)
360
+ print("time cost for each icon classification: %2.2f s" % (time_cost_ic/len(compos)))
361
  # ic_time_cost_all.append(time_cost_ic)
362
 
363
  # --------- end classification ----------
 
401
 
402
  time_cost_ts = time.process_time() - text_selection_time
403
  print("time cost for text selection: %2.2f s" % time_cost_ts)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
 
405
+ classification_cost = time.process_time() - classification_start_time
 
 
 
406
 
407
+ # ts_time_cost_all.append(time_cost_ts)
408
 
409
+ # ---------- end -------------------------------
 
 
410
 
 
411
 
412
  # ---------- matching result -----------
413
 
 
424
 
425
  for item in elements:
426
  complete_path = pjoin(segment_root, app_id, 'classified_sentences', item.label + '.txt')
427
+ # print("complete_path: ", complete_path)
428
 
429
  if exists(complete_path):
430
 
 
451
  output_data = pd.concat([output_data, pd.DataFrame([{'screenshot': 's' + str(index), 'id': item.id + 1,
452
  'label': item.label, 'index': "None",
453
  'text': "No information!", 'sentences': "None"}])])
454
+
455
+ # -----------------openai缩略text---------------------------
456
+
457
+ short_text_time_start = time.process_time()
458
+
459
+ short_output_data = output_data[['label', 'text']].copy()
460
+ short_output_data = short_output_data.rename(columns={'text': 'segment'})
461
+ retries = 3
462
+ summarized_data = [] # List to hold summarized rows
463
+ for index, row in short_output_data.iterrows():
464
+ seg = row['segment']
465
+ label = row['label']
466
+ if seg == "No information!":
467
+ shortened_seg = seg
468
+ else:
469
+ for i in range(retries):
470
+ try:
471
+ shortened_seg = summarize_segment(seg, label)
472
+ # print(seg)
473
+ # print("--------------------")
474
+ # print(shortened_seg)
475
+ break
476
+ except openai.error.RateLimitError as e:
477
+ if "overloaded" in str(e):
478
+ print("error")
479
+ sleep_time = 2 * (2 ** i) + 0.1
480
+ # sleep_time = 3
481
+ time.sleep(sleep_time)
482
+ except Exception as e:
483
+ # If you wish, you can print or log the exception details here without raising it
484
+ print(e)
485
+ else:
486
+ # This part will be executed if the for loop doesn't hit 'break'
487
+ shortened_seg = seg
488
+
489
+ summarized_data.append({'label': row['label'], 'segment': shortened_seg})
490
+
491
+ short_text_time_cost = time.process_time() - short_text_time_start
492
+ print("缩短policy总共花费了: %2.2f s" % short_text_time_cost)
493
+
494
+ # -------------------------------------------------------
495
+
496
+ full_size_org, full_size_grey = pre.read_img(input_img)
497
+ ratio = full_size_org.shape[0]/org.shape[0]
498
+
499
+ show = False
500
+ wait_key = 0
501
+
502
+ reassign_ids(elements)
503
+ board = merge.show_elements(full_size_org, elements, ratio, show=show, win_name='elements after merging', wait_key=wait_key, line=3)
504
+
505
+ draw_pic_start = time.process_time()
506
+
507
+ board_one_element = merge.show_one_element_class(full_size_org, elements, ratio, show=show, win_name='elements after merging', wait_key=wait_key, line=3, summarized_data=summarized_data)
508
+
509
+ draw_pic_cost = time.process_time() - draw_pic_start
510
+ print("生成所有的展示图片花费: %2.2f s" % draw_pic_cost)
511
+ print("平均生成一张图片花费: %2.2f s" % (draw_pic_cost/len(board_one_element)))
512
+
513
+ classification_root = pjoin(output_root, 'classification')
514
+
515
+ # save all merged elements, clips and blank background
516
+ name = input_img.replace('\\', '/').split('/')[-1][:-4]
517
+ components = merge.save_elements(pjoin(classification_root, name + '.json'), elements, full_size_org.shape, ratio)
518
+ cv2.imwrite(pjoin(classification_root, name + '.jpg'), board)
519
+
520
+ print("一共图片张数: ", len(board_one_element))
521
+
522
+ for i in range(len(board_one_element)):
523
+ e_name = str(int(elements[i].id) + 1)
524
+ cv2.imwrite(pjoin(classification_root + '/GUI', name + '-' + e_name + '.jpg'), board_one_element[i])
525
+
526
+ print("生成图片展示总花费: %2.2f s" % (time.process_time()-short_text_time_start))
527
+
528
+ # print('[Classification Completed] Input: %s Output: %s' % (input_img, pjoin(classification_root, name + '.jpg')))
529
+
530
+
531
+
532
+
533
+ return time_cost_ic, time_cost_ts, output_data, board_one_element,classification_cost
CDM/detect_compo/lib_ip/ip_draw.py CHANGED
@@ -49,6 +49,9 @@ def draw_bounding_box_class_by_category(org, components, color_map=C.COLOR, line
49
  output_path = pjoin(output_root, f"{category}.jpg")
50
  cv2.imwrite(output_path, board)
51
 
 
 
 
52
 
53
  def draw_bounding_box_class(org, components, color_map=C.COLOR, line=2, show=False, write_path=None, name='board'):
54
  """
 
49
  output_path = pjoin(output_root, f"{category}.jpg")
50
  cv2.imwrite(output_path, board)
51
 
52
+ # 返回所有分类对应的图像字典
53
+ return boards_by_category
54
+
55
 
56
  def draw_bounding_box_class(org, components, color_map=C.COLOR, line=2, show=False, write_path=None, name='board'):
57
  """
CDM/detect_merge/Element.py CHANGED
@@ -1,5 +1,9 @@
 
 
1
  import numpy as np
2
  import cv2
 
 
3
 
4
 
5
  class Element:
@@ -16,6 +20,30 @@ class Element:
16
  self.children = [] # list of elements
17
  self.label = None
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  def init_bound(self):
20
  self.width = self.col_max - self.col_min
21
  self.height = self.row_max - self.row_min
@@ -25,7 +53,7 @@ class Element:
25
  return self.col_min, self.row_min, self.col_max, self.row_max
26
 
27
  def wrap_info(self):
28
- info = {'id':self.id, 'class': self.category, 'height': self.height, 'width': self.width,
29
  'position': {'column_min': self.col_min, 'row_min': self.row_min, 'column_max': self.col_max,
30
  'row_max': self.row_max}, 'label': self.label}
31
  if self.text_content is not None:
@@ -48,7 +76,8 @@ class Element:
48
  def element_merge(self, element_b, new_element=False, new_category=None, new_id=None):
49
  col_min_a, row_min_a, col_max_a, row_max_a = self.put_bbox()
50
  col_min_b, row_min_b, col_max_b, row_max_b = element_b.put_bbox()
51
- new_corner = (min(col_min_a, col_min_b), min(row_min_a, row_min_b), max(col_max_a, col_max_b), max(row_max_a, row_max_b))
 
52
  if element_b.text_content is not None:
53
  self.text_content = element_b.text_content if self.text_content is None else self.text_content + '\n' + element_b.text_content
54
  if new_element:
@@ -95,19 +124,550 @@ class Element:
95
  return 1
96
  return 2
97
 
98
- def visualize_element(self, img, color=(0, 255, 0), line=1, show=False, ratio=1):
99
- loc = self.put_bbox()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
 
 
101
  if ratio != 1:
102
  loc = [int(x * ratio) for x in loc]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
- # cv2.rectangle(img, loc[:2], loc[2:], color, line)
105
- cv2.rectangle(img, (loc[0], loc[1]), (loc[2], loc[3]), color, line)
106
- cv2.putText(img, str(int(self.id) + 1), (int(ratio*(self.col_min - 10)), int(ratio*(self.row_max + 10))), cv2.FONT_HERSHEY_SIMPLEX, 1,
107
- color, line)
108
- # for child in self.children:
109
- # child.visualize_element(img, color=(255, 0, 255), line=line)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  if show:
111
  cv2.imshow('element', img)
112
  cv2.waitKey(0)
113
  cv2.destroyWindow('element')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+
3
  import numpy as np
4
  import cv2
5
+ import pandas as pd
6
+ from PIL import Image, ImageDraw, ImageFont
7
 
8
 
9
  class Element:
 
20
  self.children = [] # list of elements
21
  self.label = None
22
 
23
+ def __str__(self):
24
+ return (f"Element(id={self.id}, category={self.category}, corner=({self.col_min}, {self.row_min}, "
25
+ f"{self.col_max}, {self.row_max}), width={self.width}, height={self.height}, area={self.area}, "
26
+ f"text_content={self.text_content}, label={self.label}, parent_id={self.parent_id}, "
27
+ f"children_count={len(self.children)})")
28
+
29
+ def __eq__(self, other):
30
+ if not isinstance(other, Element):
31
+ return False
32
+ return (self.id == other.id and
33
+ self.category == other.category and
34
+ self.col_min == other.col_min and
35
+ self.row_min == other.row_min and
36
+ self.col_max == other.col_max and
37
+ self.row_max == other.row_max and
38
+ self.text_content == other.text_content and
39
+ self.label == other.label)
40
+
41
+ def center(self):
42
+ # 计算中心点
43
+ center_x = (self.col_min + self.col_max) / 2
44
+ center_y = (self.row_min + self.row_max) / 2
45
+ return (center_x, center_y)
46
+
47
  def init_bound(self):
48
  self.width = self.col_max - self.col_min
49
  self.height = self.row_max - self.row_min
 
53
  return self.col_min, self.row_min, self.col_max, self.row_max
54
 
55
  def wrap_info(self):
56
+ info = {'id': self.id, 'class': self.category, 'height': self.height, 'width': self.width,
57
  'position': {'column_min': self.col_min, 'row_min': self.row_min, 'column_max': self.col_max,
58
  'row_max': self.row_max}, 'label': self.label}
59
  if self.text_content is not None:
 
76
  def element_merge(self, element_b, new_element=False, new_category=None, new_id=None):
77
  col_min_a, row_min_a, col_max_a, row_max_a = self.put_bbox()
78
  col_min_b, row_min_b, col_max_b, row_max_b = element_b.put_bbox()
79
+ new_corner = (
80
+ min(col_min_a, col_min_b), min(row_min_a, row_min_b), max(col_max_a, col_max_b), max(row_max_a, row_max_b))
81
  if element_b.text_content is not None:
82
  self.text_content = element_b.text_content if self.text_content is None else self.text_content + '\n' + element_b.text_content
83
  if new_element:
 
124
  return 1
125
  return 2
126
 
127
+ # def visualize_element(self, img, color=(0, 255, 0), line=3, show=False, ratio=1, expand_size=5, corner_radius=20):
128
+ # loc = self.put_bbox()
129
+ #
130
+ # if ratio != 1:
131
+ # loc = [int(x * ratio) for x in loc]
132
+ #
133
+ # # 调整线条粗细,根据缩放比例
134
+ # adjusted_thickness = int(line * ratio)
135
+ # if adjusted_thickness < 1:
136
+ # adjusted_thickness = 1 # 确保最小粗细为1
137
+ #
138
+ # # cv2.rectangle(img, loc[:2], loc[2:], color, line)
139
+ # # cv2.rectangle(img, (loc[0], loc[1]), (loc[2], loc[3]), color, line)
140
+ # # 标号
141
+ # # cv2.putText(img, str(int(self.id) + 1), (int(ratio*(self.col_min - 10)), int(ratio*(self.row_max + 10))),
142
+ # # cv2.FONT_HERSHEY_SIMPLEX, 1, color, line)
143
+ #
144
+ # # 扩展边框,在原始坐标的基础上增加 expand_size
145
+ # loc[0] -= expand_size # 左
146
+ # loc[1] -= expand_size + 2 # 上
147
+ # loc[2] += expand_size + 10 # 右
148
+ # loc[3] += expand_size + 2 # 下
149
+ #
150
+ # # 确保圆角半径不会超过矩形的宽或高的一半
151
+ # corner_radius = min(corner_radius, (loc[2] - loc[0]) // 2, (loc[3] - loc[1]) // 2)
152
+ #
153
+ # # 绘制圆角矩形
154
+ # def draw_rounded_rectangle(image, top_left, bottom_right, color, thickness, radius):
155
+ # x1, y1 = top_left
156
+ # x2, y2 = bottom_right
157
+ #
158
+ # # 计算各条边线的起点和终点
159
+ # points = [
160
+ # ((x1 + radius, y1), (x2 - radius, y1)), # 上边
161
+ # ((x1 + radius, y2), (x2 - radius, y2)), # 下边
162
+ # ((x1, y1 + radius), (x1, y2 - radius)), # 左边
163
+ # ((x2, y1 + radius), (x2, y2 - radius)) # 右边
164
+ # ]
165
+ #
166
+ # # 画四分之一圆角
167
+ # cv2.ellipse(image, (x1 + radius, y1 + radius), (radius, radius), 180, 0, 90, color, thickness) # 左上角
168
+ # cv2.ellipse(image, (x2 - radius, y1 + radius), (radius, radius), 270, 0, 90, color, thickness) # 右上角
169
+ # cv2.ellipse(image, (x1 + radius, y2 - radius), (radius, radius), 90, 0, 90, color, thickness) # 左下角
170
+ # cv2.ellipse(image, (x2 - radius, y2 - radius), (radius, radius), 0, 0, 90, color, thickness) # 右下角
171
+ #
172
+ # # 画四条直线连接四分之一圆角
173
+ # for point_start, point_end in points:
174
+ # cv2.line(image, point_start, point_end, color, thickness)
175
+ #
176
+ # # 绘制圆角矩形
177
+ # draw_rounded_rectangle(img, (loc[0], loc[1]), (loc[2], loc[3]), color, adjusted_thickness, corner_radius)
178
+ #
179
+ # # for child in self.children:
180
+ # # child.visualize_element(img, color=(255, 0, 255), line=line)
181
+ # if show:
182
+ # cv2.imshow('element', img)
183
+ # cv2.waitKey(0)
184
+ # cv2.destroyWindow('element')
185
 
186
+ def adjust_loc(self, ratio=1, expand_size=5):
187
+ loc = list(self.put_bbox())
188
  if ratio != 1:
189
  loc = [int(x * ratio) for x in loc]
190
+ # 扩展框的边界
191
+ loc[0] -= expand_size # 左扩展
192
+ loc[1] -= expand_size + 2 # 上扩展
193
+ loc[2] += expand_size + 10 # 右扩展
194
+ loc[3] += expand_size + 2 # 下扩展
195
+ return loc
196
+
197
+ def draw_and_expand_rounded_rectangle(self, img, loc, color=(0, 255, 0), thickness=-1, expand_size=5,
198
+ corner_radius=20, ):
199
+ """
200
+ 通用的绘制带扩展边框的圆角矩形的方法。
201
+
202
+ 参数:
203
+ - img: 输入图像
204
+ - loc: 矩形的左上角和右下角坐标 (x1, y1, x2, y2)
205
+ - color: 矩形颜色
206
+ - line: 矩形边框线条的粗细
207
+ - expand_size: 扩展的边框大小
208
+ - corner_radius: 圆角的半径
209
+ - thickness: 线条粗细(-1 为填充)
210
+ """
211
+
212
+ # 确保圆角半径不会超过矩形的宽或高的一半
213
+ corner_radius = min(corner_radius, (loc[2] - loc[0]) // 2, (loc[3] - loc[1]) // 2)
214
+
215
+ # 绘制带扩展的圆角矩形
216
+ x1, y1 = loc[0], loc[1]
217
+ x2, y2 = loc[2], loc[3]
218
+
219
+ x1 = int(x1)
220
+ y1 = int(y1)
221
+ x2 = int(x2)
222
+ y2 = int(y2)
223
+
224
+ # Step 1: 处理填充
225
+ if thickness == -1:
226
+ # 填充模式 - 先绘制没有圆角的矩形部分
227
+ cv2.rectangle(img, (x1 + corner_radius, y1), (x2 - corner_radius, y2), color, cv2.FILLED) # 上下边部分
228
+ cv2.rectangle(img, (x1, y1 + corner_radius), (x2, y2 - corner_radius), color, cv2.FILLED) # 左右边部分
229
 
230
+ # Step 2: 处理圆角
231
+ # 画四分之一圆角
232
+ cv2.ellipse(img, (x1 + corner_radius, y1 + corner_radius), (corner_radius, corner_radius), 180, 0, 90, color,
233
+ thickness) # 左上角
234
+ cv2.ellipse(img, (x2 - corner_radius, y1 + corner_radius), (corner_radius, corner_radius), 270, 0, 90, color,
235
+ thickness) # 右上角
236
+ cv2.ellipse(img, (x1 + corner_radius, y2 - corner_radius), (corner_radius, corner_radius), 90, 0, 90, color,
237
+ thickness) # 左下角
238
+ cv2.ellipse(img, (x2 - corner_radius, y2 - corner_radius), (corner_radius, corner_radius), 0, 0, 90, color,
239
+ thickness) # 右下角
240
+
241
+ # Step 3: 处理边框
242
+ if thickness > 0:
243
+ # 绘制矩形四条边框,连接四个圆角
244
+ cv2.line(img, (x1 + corner_radius, y1), (x2 - corner_radius, y1), color, thickness) # 上边
245
+ cv2.line(img, (x1 + corner_radius, y2), (x2 - corner_radius, y2), color, thickness) # 下边
246
+ cv2.line(img, (x1, y1 + corner_radius), (x1, y2 - corner_radius), color, thickness) # 左边
247
+ cv2.line(img, (x2, y1 + corner_radius), (x2, y2 - corner_radius), color, thickness) # 右边
248
+
249
+ def visualize_element(self, img, color=(0, 255, 0), line=3, show=False, ratio=1, expand_size=5, corner_radius=20,
250
+ loc=None):
251
+ # 调整线条粗细,根据缩放比例
252
+ loc = self.adjust_loc(ratio=ratio, expand_size=expand_size)
253
+ if loc is None:
254
+ loc = [0, 0, 0, 0]
255
+ adjusted_thickness = int(line * ratio)
256
+ if adjusted_thickness < 1:
257
+ adjusted_thickness = 1 # 确保最小粗细为1
258
+
259
+ # 调用通用的绘制带扩展的圆角矩形方法
260
+ self.draw_and_expand_rounded_rectangle(img, loc, color, adjusted_thickness, expand_size, corner_radius)
261
+
262
+ # 显示图像(可选)
263
  if show:
264
  cv2.imshow('element', img)
265
  cv2.waitKey(0)
266
  cv2.destroyWindow('element')
267
+
268
+ def calculate_text_height(self, font_title, font_text, title, text, bubble_width, inner_padding):
269
+ """
270
+ 计算文本内容的高度,包括标题和正文
271
+ """
272
+ # 创建临时 PIL 图像用于计算文本高度
273
+ temp_img = Image.new("RGB", (bubble_width, 500), (255, 255, 255))
274
+ draw = ImageDraw.Draw(temp_img)
275
+
276
+ # 计算标题的高度
277
+ title_height = draw.textbbox((0, 0), title, font=font_title)[3] - \
278
+ draw.textbbox((0, 0), title, font=font_title)[1]
279
+
280
+ # 处理正文的自动换行
281
+ words = text.split(' ')
282
+ current_line = ""
283
+ lines = []
284
+ max_text_width = bubble_width - 2 * inner_padding
285
+
286
+ for word in words:
287
+ test_line = current_line + word + " "
288
+ text_bbox = draw.textbbox((0, 0), test_line, font=font_text)
289
+ text_width = text_bbox[2] - text_bbox[0]
290
+
291
+ if text_width < max_text_width:
292
+ current_line = test_line
293
+ else:
294
+ lines.append(current_line)
295
+ current_line = word + " "
296
+
297
+ # 添加最后一行
298
+ lines.append(current_line)
299
+
300
+ # 计算正文高度
301
+ text_height = len(lines) * (draw.textbbox((0, 0), lines[0], font=font_text)[3] -
302
+ draw.textbbox((0, 0), lines[0], font=font_text)[1]) + len(lines) * 5
303
+
304
+ # 计算总高度(标题 + 正文 + 内边距)
305
+ total_height = title_height + text_height + 2 * inner_padding + 50
306
+
307
+ return total_height
308
+
309
+ def write_text(self, img, bubble_top_left, font_title, font_text, title, text, bubble_width, inner_padding):
310
+ """
311
+ 在对话框内绘制标题和正文内容
312
+ """
313
+ # 确保文本和对话框边缘有内边距
314
+ text_area_top_left = (bubble_top_left[0] + inner_padding, bubble_top_left[1] + inner_padding - 15)
315
+
316
+ # 将 OpenCV 图像转换为 PIL 图像
317
+ img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
318
+
319
+ # 创建 ImageDraw 对象用于绘制文字
320
+ draw = ImageDraw.Draw(img_pil)
321
+
322
+ # 绘制标题
323
+ draw.text((text_area_top_left[0], text_area_top_left[1]), title, font=font_title, fill=(255, 255, 255))
324
+
325
+ # 处理正文自动换行
326
+ text_start_y = text_area_top_left[1] + font_title.size + 50 # 标题下面再留些空间给正文
327
+ max_text_width = bubble_width - 2 * inner_padding
328
+ lines = []
329
+ words = text.split(' ')
330
+ current_line = ""
331
+
332
+ for word in words:
333
+ # 检查当前行的宽度
334
+ test_line = current_line + word + " "
335
+ text_bbox = draw.textbbox((0, 0), test_line, font=font_text)
336
+ text_width = text_bbox[2] - text_bbox[0]
337
+
338
+ if text_width < max_text_width:
339
+ current_line = test_line
340
+ else:
341
+ # 当前行内容超出对话框宽度,换行
342
+ lines.append(current_line)
343
+ current_line = word + " "
344
+
345
+ # 添加最后一行
346
+ lines.append(current_line)
347
+
348
+ # 绘制每一行正文
349
+ for line in lines:
350
+ draw.text((text_area_top_left[0], text_start_y), line, font=font_text, fill=(255, 255, 255))
351
+ text_start_y += font_text.size + 5
352
+
353
+ # 将 PIL 图像转换回 OpenCV 图像(直接修改 img)
354
+ img[:] = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
355
+
356
+ def process_img(self, img, elements, texts, color=(0, 255, 0), line=3, alpha=0.7, expand_size=5,
357
+ corner_radius=20, show=False, ratio=1, padding=50, triangle_height=0, inner_padding=100,
358
+ font_path_title="CDM/detect_merge/title.ttf", font_path_text="CDM/detect_merge/text.ttf",
359
+ font_size_title=70, font_size_text=50):
360
+
361
+ # --------------画所有边框+黑色半透明处理剩余部分----------------------
362
+
363
+ black_block_start = time.process_time()
364
+
365
+ # 创建一个全黑遮罩(用于透明处理)
366
+ mask = np.zeros_like(img, dtype=np.uint8)
367
+
368
+ # 遍历每个元素并绘制圆角矩形,排除这些区域
369
+ for element in elements:
370
+ loc = element.adjust_loc(ratio=ratio, expand_size=expand_size)
371
+ # 调用通用的绘制带扩展的圆角矩形方法,在遮罩上扣除这些区域
372
+ self.draw_and_expand_rounded_rectangle(mask, loc, (255, 255, 255), -1, expand_size, corner_radius)
373
+
374
+ # 创建一个全黑的图像,用于制作黑色遮罩
375
+ overlay = np.zeros_like(img, dtype=np.uint8)
376
+ overlay[:] = (0, 0, 0) # 这是一个全黑的遮罩
377
+
378
+ # 将 overlay 和 img 混合,但根据 mask 的黑色区域应用透明效果,白色区域保持原样
379
+ img_with_overlay = cv2.addWeighted(img, 1 - alpha, overlay, alpha, 0) # 将黑色透明度应用到整个图像
380
+
381
+ # 使用 mask 保留元素区域的原始图像
382
+ result = cv2.bitwise_and(img, mask) # 仅���留元素区域(白色部分)
383
+ result += cv2.bitwise_and(img_with_overlay, cv2.bitwise_not(mask)) # 将黑色透明遮罩应用到非元素区域(黑色部分)
384
+
385
+ # 将结果应用到 img 上
386
+ img[:, :, :] = result
387
+
388
+ # 为每个元素再绘制圆角矩形边框
389
+ for element in elements:
390
+ loc = element.adjust_loc(ratio=ratio, expand_size=expand_size)
391
+ element.visualize_element(img, color=color, line=line, show=show, ratio=ratio, loc=loc)
392
+
393
+ black_block_cost = time.process_time() - black_block_start
394
+
395
+ # print("绘制带黑色遮罩的框选component的圆角block花费:%2.2f s" % black_block_cost)
396
+
397
+ # -----------------------绘制信息部分----------------------------------
398
+
399
+ write_text_in_block = time.process_time()
400
+
401
+ # 获取图像的宽度和高度
402
+ img_height, img_width = img.shape[:2]
403
+
404
+ # 获取标题和正文的显示信息
405
+ title = "· " + elements[0].label
406
+ df = pd.DataFrame(texts)
407
+ df_unique = df.drop_duplicates(subset='label', keep='first')
408
+ text = df_unique[df_unique['label'] == elements[0].label]['segment'].values[0]
409
+ text = text[0].upper() + text[1:]
410
+
411
+ # 加载字体
412
+ font_title = ImageFont.truetype(font_path_title, font_size_title)
413
+ font_text = ImageFont.truetype(font_path_text, font_size_text)
414
+
415
+ # 计算所有元素的调整后位置
416
+ locs = [e.adjust_loc(ratio=ratio, expand_size=expand_size) for e in elements]
417
+
418
+ # 获取所有元素的上边界(y1)和下边界(y2)
419
+ # 并添加图片的上边界(0)和下边界(img_height)作为特殊的"元素"
420
+ y_positions = []
421
+
422
+ for loc in locs:
423
+ y_positions.append((loc[1], 'element_top')) # 元素的上边界
424
+ y_positions.append((loc[3], 'element_bottom')) # 元素的下边界
425
+
426
+ # 添加图片的上边界和下边界
427
+ y_positions.append((0, 'image_top'))
428
+ y_positions.append((img_height, 'image_bottom'))
429
+
430
+ # 按 Y 坐标排序
431
+ y_positions.sort(key=lambda x: x[0])
432
+
433
+ # 找到所有的垂直空白区域
434
+ gaps = []
435
+
436
+ for i in range(len(y_positions) - 1):
437
+ y1, label1 = y_positions[i]
438
+ y2, label2 = y_positions[i + 1]
439
+
440
+ # 如果两个位置之间有空隙
441
+ if y2 > y1:
442
+ gap_height = y2 - y1
443
+ gap = {
444
+ 'start': y1,
445
+ 'end': y2,
446
+ 'height': gap_height,
447
+ 'above': label1,
448
+ 'below': label2
449
+ }
450
+ gaps.append(gap)
451
+
452
+ # 找到高度最大的空白区域
453
+ largest_gap = max(gaps, key=lambda x: x['height'])
454
+
455
+ # 判断最大的空白区域是否在元素和图片边界之间,还是在元素之间
456
+ is_between_element_and_border = False
457
+ is_between_elements = False
458
+
459
+ if largest_gap['above'] == 'image_top' or largest_gap['below'] == 'image_bottom':
460
+ is_between_element_and_border = True
461
+ elif largest_gap['above'] == 'element_bottom' and largest_gap['below'] == 'element_top':
462
+ is_between_elements = True
463
+
464
+ # 计算文本框的宽度
465
+ bubble_width = img_width - 2 * padding
466
+
467
+ # 计算文本框的高度
468
+ bubble_height = self.calculate_text_height(font_title, font_text, title, text, bubble_width, inner_padding)
469
+
470
+ # 确保文本框的高度不超过最大空白区域的高度减去两倍的内边距
471
+ max_bubble_height = largest_gap['height'] - 2 * padding
472
+ if bubble_height > max_bubble_height:
473
+ bubble_height = max_bubble_height
474
+
475
+ # 根据判断结果确定文本框的位置
476
+ if is_between_element_and_border:
477
+ # 文本框靠近对应的元素
478
+
479
+ if largest_gap['above'] == 'image_top':
480
+ # 空白区域在顶部,文本框在第一个元素的上方
481
+ ref_element = min(elements, key=lambda e: e.adjust_loc(ratio=ratio, expand_size=expand_size)[1])
482
+ loc = ref_element.adjust_loc(ratio=ratio, expand_size=expand_size)
483
+ y1 = loc[1]
484
+
485
+ bubble_top = y1 - triangle_height - padding - bubble_height
486
+ bubble_left = padding
487
+ elif largest_gap['below'] == 'image_bottom':
488
+ # 空白区域在底部,文本框在最后一个元素的下方
489
+ ref_element = max(elements, key=lambda e: e.adjust_loc(ratio=ratio, expand_size=expand_size)[3])
490
+ loc = ref_element.adjust_loc(ratio=ratio, expand_size=expand_size)
491
+ y2 = loc[3]
492
+
493
+ bubble_top = y2 + triangle_height + padding
494
+ bubble_left = padding
495
+
496
+ bubble_top_left = (bubble_left, bubble_top)
497
+ bubble_bottom_right = (bubble_left + bubble_width, bubble_top + bubble_height)
498
+
499
+ elif is_between_elements:
500
+ # 文本框在元素之间,垂直居中放置在最大空白区域内
501
+ gap_start = largest_gap['start']
502
+ gap_end = largest_gap['end']
503
+
504
+ bubble_top = gap_start + (gap_end - gap_start - bubble_height) / 2
505
+ bubble_left = padding
506
+
507
+ bubble_top_left = (bubble_left, bubble_top)
508
+ bubble_bottom_right = (bubble_left + bubble_width, bubble_top + bubble_height)
509
+
510
+ else:
511
+ # 如果没有符合条件的空白区域,默认将文本框放在图片的顶部
512
+ bubble_top_left = (padding, padding)
513
+ bubble_bottom_right = (bubble_top_left[0] + bubble_width, bubble_top_left[1] + bubble_height)
514
+
515
+ # 确保文本框不会超出图片的顶部或底部边界
516
+ if bubble_top_left[1] < 0:
517
+ bubble_top_left = (bubble_top_left[0], padding)
518
+ bubble_bottom_right = (bubble_bottom_right[0], bubble_top_left[1] + bubble_height)
519
+ elif bubble_bottom_right[1] > img_height:
520
+ bubble_bottom_right = (bubble_bottom_right[0], img_height - padding)
521
+ bubble_top_left = (bubble_top_left[0], bubble_bottom_right[1] - bubble_height)
522
+
523
+ # 绘制圆角矩形作为对话框
524
+ self.draw_and_expand_rounded_rectangle(
525
+ img,
526
+ [bubble_top_left[0], bubble_top_left[1], bubble_bottom_right[0], bubble_bottom_right[1]],
527
+ color,
528
+ corner_radius=50
529
+ )
530
+
531
+ # 对话框内写入文本
532
+ self.write_text(img, bubble_top_left, font_title, font_text, title, text, bubble_width, inner_padding)
533
+
534
+ # # 计算所有元素的调整后位置
535
+ # locs = [e.adjust_loc(ratio=ratio, expand_size=expand_size) for e in elements]
536
+ #
537
+ # # 计算元素组的包围框
538
+ # min_y1 = min(loc[1] for loc in locs)
539
+ # max_y2 = max(loc[3] for loc in locs)
540
+ #
541
+ # # 计算元素组到图片上下边界的距离
542
+ # top_distance_group = min_y1 # 元素组上边到图片上边界的距离
543
+ # bottom_distance_group = img_height - max_y2 # 元素组下边到图片下边界的距离
544
+ #
545
+ # if top_distance_group > bottom_distance_group:
546
+ # # 如果元素组上方空间更大,选择最靠近上边界的元素
547
+ # ref_element = min(elements, key=lambda e: e.adjust_loc(ratio=ratio, expand_size=expand_size)[1])
548
+ # else:
549
+ # # 否则,选择最靠近下边界的元素
550
+ # ref_element = max(elements, key=lambda e: e.adjust_loc(ratio=ratio, expand_size=expand_size)[3])
551
+ #
552
+ # # 使用参考元素进行后续操作
553
+ # loc = ref_element.adjust_loc(ratio=ratio, expand_size=expand_size)
554
+ # # 计算每个扩展后边界到图片边界的距离
555
+ # left_distance = loc[0] # 左边到图像左边界的距离
556
+ # right_distance = img_width - loc[2] # 右边到图像右边界的距离
557
+ # top_distance = loc[1] # 上边到图像上边界的距离
558
+ # bottom_distance = img_height - loc[3] # 下边到图像下边界的距离
559
+ #
560
+ # # 存储每个边界的距离
561
+ # distances = {
562
+ # 'left': left_distance,
563
+ # 'right': right_distance,
564
+ # 'top': top_distance,
565
+ # 'bottom': bottom_distance
566
+ # }
567
+ #
568
+ # # 计算对话框宽度(接近 img 的宽度,但稍微小于 img 宽度)
569
+ # bubble_width = img_width - 2 * padding
570
+ # x1, y1, x2, y2 = loc
571
+ #
572
+ # # 计算文本框的高度
573
+ # bubble_height = self.calculate_text_height(font_title, font_text, title, text, bubble_width, inner_padding)
574
+ #
575
+ # # 根据元素位置绘制对话框
576
+ # if distances['top'] > distances['bottom']:
577
+ # # 对话框的位置:在元素上方
578
+ # bubble_top_left = (padding, y1 - triangle_height - padding - bubble_height)
579
+ # bubble_bottom_right = (bubble_width + padding, y1 - triangle_height - padding)
580
+ # else:
581
+ # # 对话框的位置:在元素下方
582
+ # bubble_top_left = (padding, y2 + triangle_height + padding)
583
+ # bubble_bottom_right = (bubble_width + padding, y2 + triangle_height + padding + bubble_height)
584
+ #
585
+ # # 绘制圆角矩形作为对话框
586
+ # self.draw_and_expand_rounded_rectangle(
587
+ # img,
588
+ # [bubble_top_left[0], bubble_top_left[1], bubble_bottom_right[0], bubble_bottom_right[1]],
589
+ # color,
590
+ # corner_radius=50
591
+ # )
592
+ #
593
+ # # 对话框内写入文本
594
+ # self.write_text(img, bubble_top_left, font_title, font_text, title, text, bubble_width, inner_padding)
595
+
596
+ write_in_block_cost = time.process_time() - write_text_in_block
597
+
598
+ # print("绘制文本展示block+写入文字花费时间:%2.2f s" % write_in_block_cost)
599
+
600
+
601
+
602
+
603
+
604
+ # =====================================================
605
+
606
+
607
+
608
+
609
+
610
+ # # 如果这张图只有一个element
611
+ # if len(elements) == 1:
612
+ # loc = elements[0].adjust_loc(ratio=ratio, expand_size=expand_size)
613
+ # # 计算每个扩展后边界到图片边界的距离
614
+ # left_distance = loc[0] # 左边到图像左边界的距离
615
+ # right_distance = img_width - loc[2] # 右边到图像右边界的距离
616
+ # top_distance = loc[1] # 上边到图像上边界的距离
617
+ # bottom_distance = img_height - loc[3] # 下边到图像下边界的距离
618
+ #
619
+ # # 存储每个边界的距离
620
+ # distances = {
621
+ # 'left': left_distance,
622
+ # 'right': right_distance,
623
+ # 'top': top_distance,
624
+ # 'bottom': bottom_distance
625
+ # }
626
+ #
627
+ # # 计算对话框宽度(接近 img 的宽度,但稍微小于 img 宽度)
628
+ # bubble_width = img_width - 2 * padding
629
+ # x1, y1, x2, y2 = loc
630
+ #
631
+ # # 计算文本框的高度
632
+ # bubble_height = self.calculate_text_height(font_title, font_text, title, text, bubble_width, inner_padding)
633
+ #
634
+ # # 根据元素位置绘制对话框
635
+ # if distances['top'] > distances['bottom']:
636
+ # # 对话框的位置:在元素上方
637
+ # bubble_top_left = (padding, y1 - triangle_height - padding - bubble_height)
638
+ # bubble_bottom_right = (bubble_width + padding, y1 - triangle_height - padding)
639
+ # # # 三角形的底边中心位置 (等边三角形)
640
+ # # triangle_base_y = bubble_bottom_right[1]
641
+ # # triangle_center_x = (x1 + x2) // 2
642
+ # # # 三角形顶点朝下
643
+ # # triangle_tip_y = triangle_base_y + (triangle_height - 10)
644
+ # else:
645
+ # # 对话框的位置:在元素下方
646
+ # bubble_top_left = (padding, y2 + triangle_height + padding)
647
+ # bubble_bottom_right = (bubble_width + padding, y2 + triangle_height + padding + bubble_height)
648
+ # # # 三角形的底边中心位置 (等边三角形)
649
+ # # triangle_base_y = bubble_top_left[1]
650
+ # # triangle_center_x = (x1 + x2) // 2
651
+ # # # 三角形顶点朝上
652
+ # # triangle_tip_y = triangle_base_y - (triangle_height - 10)
653
+ #
654
+ # # # 三角形底边长度等于高度,所以底边是 [triangle_height] 的两倍
655
+ # # half_base = triangle_height // 2 + 5
656
+ # #
657
+ # # # 绘制等边三角形
658
+ # # triangle_points = np.array([
659
+ # # [triangle_center_x - half_base, triangle_base_y], # 三角形左边点
660
+ # # [triangle_center_x + half_base, triangle_base_y], # 三角形右边点
661
+ # # [triangle_center_x, triangle_tip_y] # 三角形顶点
662
+ # # ])
663
+ # # cv2.fillPoly(img, [triangle_points], color)
664
+ #
665
+ # # 绘制圆角矩形作为对话框
666
+ # self.draw_and_expand_rounded_rectangle(img,
667
+ # [bubble_top_left[0], bubble_top_left[1], bubble_bottom_right[0],
668
+ # bubble_bottom_right[1]], color, corner_radius=50)
669
+ #
670
+ # # 对话框内写入文本
671
+ # self.write_text(img, bubble_top_left, font_title, font_text, title, text, bubble_width, inner_padding)
672
+ #
673
+ # # else:
CDM/detect_merge/merge.py CHANGED
@@ -1,4 +1,7 @@
 
1
  import json
 
 
2
  import cv2
3
  import numpy as np
4
  from os.path import join as pjoin
@@ -13,6 +16,13 @@ import torch
13
 
14
  import CDM.detect_compo.lib_ip.ip_preprocessing as pre
15
 
 
 
 
 
 
 
 
16
  # ----------------- load pre-trained classification model ----------------
17
 
18
  # model = models.resnet18().to('cpu')
@@ -77,6 +87,35 @@ def show_one_element(org_img, eles, ratio, show=False, win_name='element', wait_
77
  return all_img
78
 
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  def save_elements(output_file, elements, img_shape, ratio=1):
81
  components = {'compos': [], 'img_shape': img_shape}
82
  for i, ele in enumerate(elements):
@@ -356,6 +395,6 @@ def merge(img_path, compo_path, text_path, merge_root=None, is_paragraph=False,
356
  name = img_path.replace('\\', '/').split('/')[-1][:-4]
357
  components = save_elements(pjoin(merge_root, name + '.json'), elements, img_resize.shape)
358
  cv2.imwrite(pjoin(merge_root, name + '.jpg'), board)
359
- print('[Merge Completed] Input: %s Output: %s' % (img_path, pjoin(merge_root, name + '.jpg')))
360
  return board, components
361
  # return this_ic_time, this_ts_time
 
1
+ import copy
2
  import json
3
+ import math
4
+
5
  import cv2
6
  import numpy as np
7
  from os.path import join as pjoin
 
16
 
17
  import CDM.detect_compo.lib_ip.ip_preprocessing as pre
18
 
19
+ ColorMap = {'Name': (51, 199, 255), 'Birthday': (255, 174, 200), 'Address': (173, 103, 247), 'Phone': (19, 127, 9),
20
+ 'Email': (0, 205, 255), 'Contacts': (255, 174, 0), 'Location': (255, 195, 0), 'Photos': (133, 46, 182),
21
+ 'Voices': (182, 255, 0), 'Financial info': (164, 19, 19), 'IP': (5, 226, 206), 'Cookies': (13, 131, 202),
22
+ 'Social media': (164, 25, 166), 'Profile': (95, 146, 44), 'Gender': (252, 81, 81)}
23
+
24
+
25
+
26
  # ----------------- load pre-trained classification model ----------------
27
 
28
  # model = models.resnet18().to('cpu')
 
87
  return all_img
88
 
89
 
90
+ def show_one_element_class(org_img, eles, ratio, summarized_data, show=False, win_name='element', wait_key=0, shown_resize=None, line=3):
91
+ all_img = []
92
+ eles_copy = copy.copy(eles)
93
+ for ele in eles:
94
+ if any(ele is ele_copy for ele_copy in eles_copy):
95
+ ele_group = [ele]
96
+ img = org_img.copy()
97
+ color = ColorMap[ele.label]
98
+ # ele.visualize_element(img=img, color=color, line=line, ratio=ratio)
99
+ for ele0 in eles:
100
+ if ele0 != ele and ele.label == ele0.label:
101
+ ele_group.append(ele0)
102
+ eles_copy.remove(ele0)
103
+ ele.process_img(img=img, elements=ele_group, texts=summarized_data, color=color, ratio=ratio, line=line)
104
+
105
+ img_resize = img
106
+ all_img.append(img_resize)
107
+ if shown_resize is not None:
108
+ img_resize = cv2.resize(img, shown_resize)
109
+ if show:
110
+ cv2.imshow(win_name, img_resize)
111
+ cv2.waitKey(wait_key)
112
+ if wait_key == 0:
113
+ cv2.destroyWindow(win_name)
114
+ else:
115
+ continue
116
+ return all_img
117
+
118
+
119
  def save_elements(output_file, elements, img_shape, ratio=1):
120
  components = {'compos': [], 'img_shape': img_shape}
121
  for i, ele in enumerate(elements):
 
395
  name = img_path.replace('\\', '/').split('/')[-1][:-4]
396
  components = save_elements(pjoin(merge_root, name + '.json'), elements, img_resize.shape)
397
  cv2.imwrite(pjoin(merge_root, name + '.jpg'), board)
398
+ # print('[Merge Completed] Input: %s Output: %s' % (img_path, pjoin(merge_root, name + '.jpg')))
399
  return board, components
400
  # return this_ic_time, this_ts_time
CDM/run_single.py CHANGED
@@ -12,27 +12,27 @@ import CDM.detect_classify.classification as clf
12
  import pandas as pd
13
  import openai
14
 
15
- def summarize_segment(segment):
16
- openai.api_key = os.environ.get('openai_key')
17
-
18
- prompt = f"Shorten this paragraph: \"{str(segment)}\"."
19
-
20
- response = openai.ChatCompletion.create(
21
- # engine="text-davinci-002",
22
- model="gpt-3.5-turbo",
23
- messages=[
24
- # {"role": "system", "content": "You are a helpful assistant."},
25
- {"role": "user", "content": prompt}
26
- ],
27
- max_tokens=400,
28
- n=1,
29
- stop=None,
30
- temperature=0,
31
- )
32
-
33
- shortened_segment = response.choices[0].message['content']
34
-
35
- return shortened_segment
36
 
37
  def resize_height_by_longest_edge(img_path, resize_length=800):
38
  org = cv2.imread(img_path)
@@ -47,6 +47,7 @@ def run_single_img(input_img, output_root, segment_root):
47
  # output_root = "./result_classification"
48
  # segment_root = '../scrutinizing_alexa/txt'
49
 
 
50
  if os.path.exists(output_root):
51
  shutil.rmtree(output_root)
52
  os.makedirs(output_root)
@@ -111,6 +112,8 @@ def run_single_img(input_img, output_root, segment_root):
111
  resize_by_height=resized_height, show=False)
112
  cd_time_cost_all.append(this_cd_time_cost)
113
 
 
 
114
  if is_merge:
115
  import CDM.detect_merge.merge as merge
116
 
@@ -127,7 +130,7 @@ def run_single_img(input_img, output_root, segment_root):
127
  merge_path = pjoin(output_root, 'merge', str(index) + '.json')
128
  merge_json = json.load(open(merge_path, 'r'))
129
  os.makedirs(pjoin(output_root, 'classification', 'GUI'), exist_ok=True)
130
- this_time_cost_ic, this_time_cost_ts, output_data, output_board = clf.compo_classification(input_img, output_root,
131
  segment_root, merge_json,
132
  output_data,
133
  resize_by_height=resize_by_height, clf_model="ViT")
@@ -137,7 +140,9 @@ def run_single_img(input_img, output_root, segment_root):
137
 
138
  this_img_time_cost = time.process_time() - this_img_start_time
139
  img_time_cost_all.append(this_img_time_cost)
140
- print("time cost for this image: %2.2f s" % this_img_time_cost)
 
 
141
 
142
  if os.path.isfile(output_root + '/output.csv'):
143
  output_data.to_csv(output_root + '/output.csv', index=False, mode='a', header=False)
@@ -155,8 +160,8 @@ def run_single_img(input_img, output_root, segment_root):
155
  # print("average text selection processing time cost for this app: %2.2f s" % avg_ts_time_cost)
156
  # print("average screenshot processing time cost for this app: %2.2f s" % avg_time_cost)
157
 
158
- short_output_data = output_data[['id', 'label', 'text']].copy()
159
- short_output_data = short_output_data.rename(columns={'text': 'segment'})
160
 
161
  # summarize segments:
162
 
@@ -182,34 +187,34 @@ def run_single_img(input_img, output_root, segment_root):
182
  #
183
  # short_output_data.loc[index, 'segment'] = shortened_seg
184
 
185
- original_output = []
186
- retries = 3
187
- summarized_data = [] # List to hold summarized rows
188
- for index, row in short_output_data.iterrows():
189
- seg = row['segment']
190
- for i in range(retries):
191
- try:
192
- shortened_seg = summarize_segment(seg)
193
- break
194
- except openai.error.RateLimitError as e:
195
- if "overloaded" in str(e):
196
-
197
- sleep_time = 2 * (2 ** i) + 0.1
198
- # sleep_time = 3
199
- time.sleep(sleep_time)
200
- except Exception as e:
201
- # If you wish, you can print or log the exception details here without raising it
202
- print(e)
203
- else:
204
- # This part will be executed if the for loop doesn't hit 'break'
205
- shortened_seg = seg
206
-
207
- summarized_data.append({'id': row['id'], 'label': row['label'], 'segment': shortened_seg})
208
- original_output.append({'id': row['id'], 'label': row['label'], 'segment': seg[0].upper() + seg[1:]})
209
-
210
- summarized_output_data = pd.DataFrame(summarized_data)
211
- original_output_data = pd.DataFrame(original_output)
212
-
213
- return output_board, summarized_output_data, original_output_data
214
 
215
 
 
12
  import pandas as pd
13
  import openai
14
 
15
+ # def summarize_segment(segment):
16
+ # openai.api_key = os.environ.get('openai_key')
17
+ #
18
+ # prompt = f"Shorten this paragraph: \"{str(segment)}\"."
19
+ #
20
+ # response = openai.ChatCompletion.create(
21
+ # # engine="text-davinci-002",
22
+ # model="gpt-3.5-turbo",
23
+ # messages=[
24
+ # # {"role": "system", "content": "You are a helpful assistant."},
25
+ # {"role": "user", "content": prompt}
26
+ # ],
27
+ # max_tokens=400,
28
+ # n=1,
29
+ # stop=None,
30
+ # temperature=0,
31
+ # )
32
+ #
33
+ # shortened_segment = response.choices[0].message['content']
34
+ #
35
+ # return shortened_segment
36
 
37
  def resize_height_by_longest_edge(img_path, resize_length=800):
38
  org = cv2.imread(img_path)
 
47
  # output_root = "./result_classification"
48
  # segment_root = '../scrutinizing_alexa/txt'
49
 
50
+ global output_boards
51
  if os.path.exists(output_root):
52
  shutil.rmtree(output_root)
53
  os.makedirs(output_root)
 
112
  resize_by_height=resized_height, show=False)
113
  cd_time_cost_all.append(this_cd_time_cost)
114
 
115
+ detection_cost = time.process_time() - this_img_start_time
116
+
117
  if is_merge:
118
  import CDM.detect_merge.merge as merge
119
 
 
130
  merge_path = pjoin(output_root, 'merge', str(index) + '.json')
131
  merge_json = json.load(open(merge_path, 'r'))
132
  os.makedirs(pjoin(output_root, 'classification', 'GUI'), exist_ok=True)
133
+ this_time_cost_ic, this_time_cost_ts, output_data, output_boards, classification_cost = clf.compo_classification(input_img, output_root,
134
  segment_root, merge_json,
135
  output_data,
136
  resize_by_height=resize_by_height, clf_model="ViT")
 
140
 
141
  this_img_time_cost = time.process_time() - this_img_start_time
142
  img_time_cost_all.append(this_img_time_cost)
143
+ # print("time cost for this image: %2.2f s" % this_img_time_cost)
144
+
145
+ print("检测+分类共花费: %2.2f s" % (classification_cost + detection_cost))
146
 
147
  if os.path.isfile(output_root + '/output.csv'):
148
  output_data.to_csv(output_root + '/output.csv', index=False, mode='a', header=False)
 
160
  # print("average text selection processing time cost for this app: %2.2f s" % avg_ts_time_cost)
161
  # print("average screenshot processing time cost for this app: %2.2f s" % avg_time_cost)
162
 
163
+ # short_output_data = output_data[['id', 'label', 'text']].copy()
164
+ # short_output_data = short_output_data.rename(columns={'text': 'segment'})
165
 
166
  # summarize segments:
167
 
 
187
  #
188
  # short_output_data.loc[index, 'segment'] = shortened_seg
189
 
190
+ # original_output = []
191
+ # retries = 3
192
+ # summarized_data = [] # List to hold summarized rows
193
+ # for index, row in short_output_data.iterrows():
194
+ # seg = row['segment']
195
+ # for i in range(retries):
196
+ # try:
197
+ # shortened_seg = summarize_segment(seg)
198
+ # break
199
+ # except openai.error.RateLimitError as e:
200
+ # if "overloaded" in str(e):
201
+ #
202
+ # sleep_time = 2 * (2 ** i) + 0.1
203
+ # # sleep_time = 3
204
+ # time.sleep(sleep_time)
205
+ # except Exception as e:
206
+ # # If you wish, you can print or log the exception details here without raising it
207
+ # print(e)
208
+ # else:
209
+ # # This part will be executed if the for loop doesn't hit 'break'
210
+ # shortened_seg = seg
211
+ #
212
+ # summarized_data.append({'id': row['id'], 'label': row['label'], 'segment': shortened_seg})
213
+ # original_output.append({'id': row['id'], 'label': row['label'], 'segment': seg[0].upper() + seg[1:]})
214
+ #
215
+ # summarized_output_data = pd.DataFrame(summarized_data)
216
+ # original_output_data = pd.DataFrame(original_output)
217
+
218
+ return output_boards
219
 
220
 
SEM/get_text.py CHANGED
@@ -22,7 +22,21 @@ mark_txt = {'0':"/data_types.txt",
22
  '14':"/thrid_party.txt",
23
  '15':"/data_types.txt"}
24
 
25
- def write_text(title_list, pathName):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  type = 0
27
  security = 0
28
  right = 0
@@ -32,10 +46,26 @@ def write_text(title_list, pathName):
32
  retention = 0
33
  useData = 0
34
  clean_title_list = []
 
35
  for title in title_list:
36
  if title.text != "•":
37
  clean_title_list.append(title)
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  # print("title list:"+str(clean_title_list))
40
 
41
  lastMark = ""
@@ -163,6 +193,41 @@ def write_text(title_list, pathName):
163
  g.write("\n")
164
  g.close()
165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  return type,security,right,specialArea,specialGroup,update,retention,useData
167
 
168
  def write_text_without_label(text, pathName):
 
22
  '14':"/thrid_party.txt",
23
  '15':"/data_types.txt"}
24
 
25
+ def process_content_outside_heading(content, pathName):
26
+ # 将内容转换为文本并进行预处理
27
+ soup = BeautifulSoup(content, 'html.parser')
28
+ text_content = soup.get_text(separator=' ', strip=True)
29
+ # 如果内容不为空,进行分类或其他处理
30
+ if text_content:
31
+ # 您可以在这里使用与标题相同的分类器进行分类
32
+ mark = clf.predict(tf.transform([text_content]))
33
+ # 将处理后的内容写入对应的文件
34
+ with open('./SEM/txt/'+pathName[:-5]+mark_txt.get(mark[0]), "a", encoding='utf-8') as f:
35
+ f.write(text_content)
36
+ f.write("\n")
37
+
38
+
39
+ def write_text(title_list, pathName, soup):
40
  type = 0
41
  security = 0
42
  right = 0
 
46
  retention = 0
47
  useData = 0
48
  clean_title_list = []
49
+
50
  for title in title_list:
51
  if title.text != "•":
52
  clean_title_list.append(title)
53
 
54
+
55
+ # # 处理第一个标题之前的内容
56
+ # if clean_title_list:
57
+ # first_title = clean_title_list[0]
58
+ # content_before_first_title = []
59
+ # for element in first_title.find_previous_siblings():
60
+ # content_before_first_title.insert(0, element) # 逆序插入,保持顺序
61
+ # content_before_first_title = ''.join([str(elem) for elem in content_before_first_title])
62
+ # # 处理标题外的内容
63
+ # process_content_outside_heading(content_before_first_title, pathName)
64
+
65
+
66
+
67
+
68
+
69
  # print("title list:"+str(clean_title_list))
70
 
71
  lastMark = ""
 
193
  g.write("\n")
194
  g.close()
195
 
196
+ # 处理标题之外的段落
197
+ remaining_soup = soup # 保留整个页面的 soup 结构
198
+
199
+ # 遍历标题列表,移除已经处理的标题和标题下的段落
200
+ for title in clean_title_list:
201
+ title.extract() # 移除每个标题及其下的段落
202
+
203
+ # 剩下的文本内容未被标题覆盖,进行同样的分类处理
204
+ removeUnneccessaryElements(remaining_soup)
205
+ remaining_segments = makeCoarseSegments(remaining_soup)
206
+ for seg in remaining_segments:
207
+ seg_clean = ' '.join(seg.split())
208
+ if len(seg_clean) != 0:
209
+ try:
210
+ mark = clf.predict(tf.transform([seg_clean]))
211
+ with open('./SEM/txt/' + pathName[:-5] + mark_txt.get(mark[0]), "a", encoding='utf-8') as f:
212
+ f.write(seg_clean)
213
+ f.write("\n")
214
+ f.close()
215
+ except Exception as e:
216
+ continue
217
+
218
+ # # 处理最后一个标题之后的内容
219
+ # if clean_title_list:
220
+ # last_title = clean_title_list[-1]
221
+ # content_after_last_title = []
222
+ # for element in last_title.next_siblings:
223
+ # content_after_last_title.append(element)
224
+ # content_after_last_title = ''.join([str(elem) for elem in content_after_last_title])
225
+ # # 处理标题外的内容
226
+ # process_content_outside_heading(content_after_last_title, pathName)
227
+
228
+
229
+
230
+
231
  return type,security,right,specialArea,specialGroup,update,retention,useData
232
 
233
  def write_text_without_label(text, pathName):
SEM/run_single_sem.py CHANGED
@@ -28,18 +28,18 @@ def run_single_pp(file):
28
  pathName = "1.html"
29
 
30
  label = find_title_Label(file)
31
- print("label: ", label)
32
- print("The current file is:" + pathName)
33
 
34
  # if pathName != '20.html':
35
  # continue
36
 
37
  para_start_time = time.process_time()
38
  soup = BeautifulSoup(open(file,encoding='utf-8'), features="html.parser")
39
- print("soup.contents: ", soup.contents)
40
  title_list = soup.find_all(label)
41
  # cleaning_txt()
42
- print("title_list: ", title_list)
43
 
44
  if not os.path.exists(result_root + pathName[:-5]):
45
  os.mkdir(result_root + pathName[:-5])
@@ -53,7 +53,7 @@ def run_single_pp(file):
53
  f.write(seg)
54
  f.write("\n")
55
  else:
56
- write_text(title_list, pathName)
57
  print("Paragraph level processing time: %2.2f s" % (time.process_time() - para_start_time))
58
 
59
  for t in title_list:
 
28
  pathName = "1.html"
29
 
30
  label = find_title_Label(file)
31
+ # print("label: ", label)
32
+ # print("The current file is:" + pathName)
33
 
34
  # if pathName != '20.html':
35
  # continue
36
 
37
  para_start_time = time.process_time()
38
  soup = BeautifulSoup(open(file,encoding='utf-8'), features="html.parser")
39
+ # print("soup.contents: ", soup.contents)
40
  title_list = soup.find_all(label)
41
  # cleaning_txt()
42
+ # print("title_list: ", title_list)
43
 
44
  if not os.path.exists(result_root + pathName[:-5]):
45
  os.mkdir(result_root + pathName[:-5])
 
53
  f.write(seg)
54
  f.write("\n")
55
  else:
56
+ write_text(title_list, pathName, soup)
57
  print("Paragraph level processing time: %2.2f s" % (time.process_time() - para_start_time))
58
 
59
  for t in title_list:
SEM/txt/1/children.txt CHANGED
@@ -1 +1,2 @@
1
  McDonald's is very sensitive to privacy issues. We are proud of our long-time commitment to our customers. McDonald’s does not intend to collect personal information from any person under the age of 18 years without the consent of a parent or legal guardian. We urge parents to regularly monitor and supervise their children's online activities.
 
 
1
  McDonald's is very sensitive to privacy issues. We are proud of our long-time commitment to our customers. McDonald’s does not intend to collect personal information from any person under the age of 18 years without the consent of a parent or legal guardian. We urge parents to regularly monitor and supervise their children's online activities.
2
+ McDonald's is very sensitive to privacy issues. We are proud of our long-time commitment to our customers. McDonald’s does not intend to collect personal information from any person under the age of 18 years without the consent of a parent or legal guardian. We urge parents to regularly monitor and supervise their children's online activities.
SEM/txt/1/data_types.txt CHANGED
@@ -35,3 +35,65 @@ You are in control of any personal information you provide to us. If, at any tim
35
  Your personal information may be stored in different locations depending upon the reason for which you originally submitted the information. If you make an inquiry in relation to your personal information, the more information you can provide us about when you originally submitted your personal information, the quicker McDonald's will be able to retrieve your personal information. McDonald’s may require you to verify your identity by asking you to provide certain information about yourself and provide us with a declaration witnessed and signed by a Justice of Peace. Once your identity is verified, we will work to provide you with your requested information.
36
  If you request, we will take all reasonable steps to delete your personal information, except where it is required for legal and compliance reasons. Deletion of information may result in McDonald's being unable to facilitate or provide you with information about certain transactions (including the uploading of, access to, and receipt of, content on a Website or App, and purchase transactions undertaken on a Website or App), other content, services or product information, upcoming promotions, competitions or event information, and/or provide certain content, products or services.
37
  We are not responsible for removing your personal information from the lists of any third party who has previously been provided your information in accordance with this privacy policy.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  Your personal information may be stored in different locations depending upon the reason for which you originally submitted the information. If you make an inquiry in relation to your personal information, the more information you can provide us about when you originally submitted your personal information, the quicker McDonald's will be able to retrieve your personal information. McDonald’s may require you to verify your identity by asking you to provide certain information about yourself and provide us with a declaration witnessed and signed by a Justice of Peace. Once your identity is verified, we will work to provide you with your requested information.
36
  If you request, we will take all reasonable steps to delete your personal information, except where it is required for legal and compliance reasons. Deletion of information may result in McDonald's being unable to facilitate or provide you with information about certain transactions (including the uploading of, access to, and receipt of, content on a Website or App, and purchase transactions undertaken on a Website or App), other content, services or product information, upcoming promotions, competitions or event information, and/or provide certain content, products or services.
37
  We are not responsible for removing your personal information from the lists of any third party who has previously been provided your information in accordance with this privacy policy.
38
+ McDonald's Australia Limited ABN 43 008 496 928 (McDonald’s) and each of its independently owned franchisees ('McDonald’s Franchisees”) (collectively referred to as “McDonald’s”, “we”, “us” or “our”) are committed to respecting your personal information. Our privacy policy sets out how we collect, use, store and disclose your personal information. When you use our Websites, Apps, or provide your personal information to us, you consent to your personal information being collected, held, used and disclosed as set out in our privacy policy.
39
+ Information we collect and hold.
40
+ (collectively referred to as “Collection Channels”).
41
+ Personal information that McDonald’s collects and holds may include your name, email address, delivery address, date of birth, phone number, payment method, social media handles, images, audio and video of you, and other identifying information you choose to provide via a particular Collection Channel.
42
+ We also collect personal or anonymous information about you from other sources and sometimes combine that information with other information collected from you or from third parties for the purposes disclosed in this privacy policy.
43
+ McDonald’s will only collect or monitor any personal information about you as provided in this privacy policy.
44
+ Mobile platforms such as iOS and Android may define certain types of information or data that our Apps cannot access without your consent. Each platform has its own permissions system for obtaining your consent. For example, the iOS platform may alert you the first time an App wants your permission to access certain types of data (e.g. location services) and will provide you the option to consent to that request. Android devices may notify you of the permissions that an App seeks before you first use the App and your subsequent use of the App constitutes your consent. You can manage your platform level permissions via the Settings section on your device. For more information, please contact your device provider or refer to the user manual for your device.
45
+ You may contact McDonald’s with any queries via email: privacy@au.mcd.com or at McDonald's Australia Limited (Attention: McDonald's Privacy Officer), PO Box 392 Pennant Hills NSW 2120 Australia.
46
+ We may use tracking technologies to collect personal information about you when you use and access a Website or App, including cookies, internet tags or web beacons, and navigational data collection (e.g. log files, server logs, and clickstream data). For example, we may collect information about the date, time and duration of visits and which pages of a Website or App are most commonly accessed. This browsing information is generally not linked to your identity, except where you access a Website or App via links in a message we have sent or where we are able to identify the device or user accessing a Website or App.
47
+ We may combine your anonymous information, browsing information or other information collected through tracking technologies with your personal information collected via our Collection Channels in order to understand and remember your preferences and interests. By accessing a Website or App via links and/or by accessing a Website or App where you have identified yourself, you consent to the collection of this information.
48
+ McDonald's shares personal information with the global McDonald’s Family and our service providers for the purposes described in this privacy policy.
49
+ McDonald’s recognises the trust with which you provide personal information, and except as stated in this privacy policy or any particular Privacy Collection Statement, your information will not be used or disclosed for any other purposes without your consent. However, McDonald's reserves the right to use or disclose any information, including personal information, as needed to satisfy any law, regulation or legal request, to protect the rights or property of McDonald's, any member of the McDonald's Family, or any member of the public, to protect the integrity of a Website or App, to fulfil your requests, or to cooperate in any law enforcement investigation or an investigation on a matter of public safety.
50
+ McDonald’s provides areas on Websites, Apps and various social media platforms where you can upload user-generated content, post or provide information about yourself, communicate with other users, provide reviews for content, products and/or services or interact with or vote on particular content. This information may be publicly posted on a Website, App or social media platforms and/or shared with others, including social media platforms and other public forums in which you choose to participate. This information may become publicly available and may be read, collected and used by others outside of a McDonald’s Website or App. McDonald’s is not responsible for the conduct of others who may read, collect and use this information.
51
+ In some cases, McDonald’s may disclose your personal information to overseas recipients, including but not limited to recipients in the United States of America, Japan, Malaysia and Singapore.
52
+ Your personal information may be stored in different locations depending upon the reason for which you originally submitted the information. If you make an inquiry in relation to your personal information, the more information you can provide us about when you originally submitted your personal information, the quicker McDonald's will be able to retrieve your personal information. McDonald’s may require you to verify your identity by asking you to provide certain information about yourself and provide us with a declaration witnessed and signed by a Justice of Peace. Once your identity is verified, we will work to provide you with your requested information.
53
+ If you request, we will take all reasonable steps to delete your personal information, except where it is required for legal and compliance reasons. Deletion of information may result in McDonald's being unable to facilitate or provide you with information about certain transactions (including the uploading of, access to, and receipt of, content on a Website or App, and purchase transactions undertaken on a Website or App), other content, services or product information, upcoming promotions, competitions or event information, and/or provide certain content, products or services.
54
+ All Websites and Apps operated by McDonald's in Australia will adhere to this privacy policy. The policies on the Websites and Apps of some other members of the McDonald's Family may vary because of local customs, practices or laws.
55
+ Many McDonald's restaurants are owned and operated by independent franchisees. Some franchisees also operate websites and are required to follow this privacy policy.
56
+ If you are concerned that there may have been a breach of this privacy policy by a franchisee, please contact the relevant franchisee entity or McDonald’s restaurant directly.
57
+ If McDonald’s merges with, is acquired by another company, or sells all or a portion of its assets, your personal information may be disclosed to our advisers and any prospective purchaser’s adviser and may be among the assets transferred. However, your personal information will always remain subject to this privacy policy.
58
+ Mail: McDonald's Privacy Officer.
59
+ McDonald's Australia Limited.
60
+ PO Box 392
61
+ Pennant Hills NSW 2120
62
+ Australia.
63
+ Email: privacy@au.mcd.com.
64
+ Telephone: (02) 9875 6666
65
+ Fax: (02) 98756568
66
+ Please allow 14 days for this request to be processed. If you do not receive a satisfactory response from McDonald’s to your query, problem or complaint within 30 calendar days, you may refer your query, problem or complaint to the Office of the Australian Information Commissioner via the contact details listed at https://www.oaic.gov.au/about-us/contact-us/.
67
+ Apple and the Apple logo are trade marks of Apple Inc., registered in the U.S. and other countries. App Store is a service mark of Apple Inc., registered in the U.S. and other countries. Google Play and the Google Play logo are trade marks of Google LLC.
68
+ McDonald’s Australia acknowledges the Aboriginal and Torres Strait Islander peoples as the first inhabitants and the Traditional Custodians of the lands where we live, learn and work.
69
+ McDonald’s collects personal information about you in a number of ways, including when you: use our mobile and tablet apps, including the MyMacca’s app (“Apps”); and.
70
+ McDonald’s collects personal information about you in a number of ways, including when you: interact with us and provide personal information by any other means, including either physically or electronically; and.
71
+ McDonald’s collects personal information about you in a number of ways, including when you: are present at or outside our restaurants, including images, video and audio from CCTV, other cameras (including body cameras), and other security and recording systems.
72
+ When you use one of our Websites or Apps, we may also collect personal information about you in the following general categories: Location information: If you permit an App to access location services in your settings, then we collect your device location to deliver your order or to send you alerts.
73
+ When you use one of our Websites or Apps, we may also collect personal information about you in the following general categories: Transaction information: We collect your transaction details when you place an order via a Website or App, including the products you have ordered, the date and time of your order, the amount charged and your loyalty entitlements.
74
+ When you use one of our Websites or Apps, we may also collect personal information about you in the following general categories: Usage and preferences: We collect information about how you interact with our Websites or Apps, including the pages you visit, your preferences and the settings that you choose. We do this through cookies and other similar technology.
75
+ When you use one of our Websites or Apps, we may also collect personal information about you in the following general categories: Device information: We collect information about your device, such as the hardware model, operating system, preferred language, unique device identifier and mobile network.
76
+ When you use one of our Websites or Apps, we may also collect personal information about you in the following general categories: Other information: We also collect and log information such as your IP address, access dates and times, browser type and pages visited when you interact with a Website or App.
77
+ We also collect personal information about you from third parties, including when: you choose to create an account or register for a product or service via a Website or App using a social media platform (e.g. Facebook, Instagram).
78
+ McDonald’s may collect your personal information via our Collection Channels when you: purchase a product or make a booking through a Website or App.
79
+ McDonald’s may collect your personal information via our Collection Channels when you: participate in any offers, marketing activities (including competitions), loyalty or rewards program or promotional activities.
80
+ McDonald’s may collect your personal information via our Collection Channels when you: contact us or provide us with personal information directly via any medium including a Website or App, SMS or other message service and email, social media platforms, mail, telephone or in person.
81
+ McDonald’s may collect your personal information via our Collection Channels when you: interact with a Website or App for a specific purpose.
82
+ McDonald’s may collect your personal information via our Collection Channels when you: browse a Website or App generally.
83
+ McDonald’s may collect your personal information via our Collection Channels when you: sign-up to, or register an account via any Collection Channel.
84
+ McDonald’s may collect your personal information via our Collection Channels when you: are present at or outside a McDonald’s restaurant and are captured via our security and recording systems (including in car parks, drive thru areas, restaurant entrances or exits and publicly accessible areas); or.
85
+ McDonald’s may collect your personal information via our Collection Channels when you: apply for employment with McDonald’s.
86
+ We collect, hold, use and disclose your personal information for our primary purposes, including: for the purposes stated on a particular Collection Channel or Privacy Collection Statement.
87
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to maintain and improve the functionality of a Website or App.
88
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to manage your orders or facilitate payment, for example, when you use our App the drive thru screen and kiosk will display your name and crew members will greet you by name.
89
+ We collect, hold, use and disclose your personal information for our primary purposes, including: in the case of images and video/audio from our security and recording systems used in and around our restaurants, for security, safety, compliance, and operational purposes.
90
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to provide you with information about your transactions and loyalty entitlements.
91
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to provide marketing materials and information about our products and services, events, special offers, competitions and/or promotions, or to request your feedback for promotional purposes.
92
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to respond to customer enquiries or complaints.
93
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to manage your employment or process your application for employment with McDonald’s (including McDonald’s franchisees), to provide employee assistance programs and facilitate effective employment practices.
94
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to obtain opinions or comments about products and/or services and to conduct other market research and development (including to record statistical data for marketing analysis).
95
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to enter you into and administer promotions/competitions.
96
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to provide, maintain and improve our products and services.
97
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to customise a Website or App based on your preferences.
98
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to allow you to use a Website or App.
99
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to share with your social media communities, to the extent allowed by you.
SEM/txt/1/protect_information.txt CHANGED
@@ -1,2 +1,4 @@
1
  McDonald’s will endeavour to take all reasonable technical, organisation and physical steps to protect your personal information. This includes utilisation of online systems with password protection, secure servers using encryption technology and secure servers that are protected in controlled facilities.
2
  All McDonald's employees and service providers are obliged to respect the confidentiality and security of any personal information held by McDonald's. However, McDonald’s cannot guarantee the security of your personal information and will not be held responsible for events arising from unauthorised access to personal information beyond McDonald's reasonable control.
 
 
 
1
  McDonald’s will endeavour to take all reasonable technical, organisation and physical steps to protect your personal information. This includes utilisation of online systems with password protection, secure servers using encryption technology and secure servers that are protected in controlled facilities.
2
  All McDonald's employees and service providers are obliged to respect the confidentiality and security of any personal information held by McDonald's. However, McDonald’s cannot guarantee the security of your personal information and will not be held responsible for events arising from unauthorised access to personal information beyond McDonald's reasonable control.
3
+ McDonald’s will endeavour to take all reasonable technical, organisation and physical steps to protect your personal information. This includes utilisation of online systems with password protection, secure servers using encryption technology and secure servers that are protected in controlled facilities.
4
+ All McDonald's employees and service providers are obliged to respect the confidentiality and security of any personal information held by McDonald's. However, McDonald’s cannot guarantee the security of your personal information and will not be held responsible for events arising from unauthorised access to personal information beyond McDonald's reasonable control.
SEM/txt/1/share_information.txt CHANGED
@@ -1,3 +1,10 @@
1
  McDonald's shares personal information with the global McDonald’s Family and our service providers for the purposes described in this privacy policy.
2
  McDonald’s recognises the trust with which you provide personal information, and except as stated in this privacy policy or any particular Privacy Collection Statement, your information will not be used or disclosed for any other purposes without your consent. However, McDonald's reserves the right to use or disclose any information, including personal information, as needed to satisfy any law, regulation or legal request, to protect the rights or property of McDonald's, any member of the McDonald's Family, or any member of the public, to protect the integrity of a Website or App, to fulfil your requests, or to cooperate in any law enforcement investigation or an investigation on a matter of public safety.
3
  In some cases, McDonald’s may disclose your personal information to overseas recipients, including but not limited to recipients in the United States of America, Japan, Malaysia and Singapore.
 
 
 
 
 
 
 
 
1
  McDonald's shares personal information with the global McDonald’s Family and our service providers for the purposes described in this privacy policy.
2
  McDonald’s recognises the trust with which you provide personal information, and except as stated in this privacy policy or any particular Privacy Collection Statement, your information will not be used or disclosed for any other purposes without your consent. However, McDonald's reserves the right to use or disclose any information, including personal information, as needed to satisfy any law, regulation or legal request, to protect the rights or property of McDonald's, any member of the McDonald's Family, or any member of the public, to protect the integrity of a Website or App, to fulfil your requests, or to cooperate in any law enforcement investigation or an investigation on a matter of public safety.
3
  In some cases, McDonald’s may disclose your personal information to overseas recipients, including but not limited to recipients in the United States of America, Japan, Malaysia and Singapore.
4
+ We may still send you transaction and administrative information.
5
+ We are not responsible for removing your personal information from the lists of any third party who has previously been provided your information in accordance with this privacy policy.
6
+ We also collect personal information about you from third parties, including when: you have consented to a third party disclosing your personal information to us (e.g. when you enter a competition or promotion run by a third party for us); and.
7
+ We also collect personal information about you from third parties, including when: it is otherwise lawful for a third party to disclose your personal information to us.
8
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to fulfil obligations in respect of any sale and purchase contract and/or any other contract between you and McDonald’s.
9
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to send you any technical, administrative or legal notices important to our Websites and Apps.
10
+ We collect, hold, use and disclose your personal information for our primary purposes, including: to share with trusted third parties including professional service providers, our related bodies corporate, our franchisees, our suppliers and our promotional partners and other trusted third parties (and their directors, servants and agents) and agencies (McDonald’s Family); and.
SEM/txt/1/thrid_party.txt CHANGED
@@ -4,3 +4,6 @@ All Websites and Apps operated by McDonald's in Australia will adhere to this pr
4
  Many McDonald's restaurants are owned and operated by independent franchisees. Some franchisees also operate websites and are required to follow this privacy policy.
5
  McDonald’s do not control the use or disclosure of personal information and may not have access to the personal information held by McDonald’s franchisees. McDonald’s franchisees are each independently responsible for ensuring that your personal information collected by them is handled in accordance with this Privacy Policy and the Australian Privacy Principles.
6
  If you are concerned that there may have been a breach of this privacy policy by a franchisee, please contact the relevant franchisee entity or McDonald’s restaurant directly.
 
 
 
 
4
  Many McDonald's restaurants are owned and operated by independent franchisees. Some franchisees also operate websites and are required to follow this privacy policy.
5
  McDonald’s do not control the use or disclosure of personal information and may not have access to the personal information held by McDonald’s franchisees. McDonald’s franchisees are each independently responsible for ensuring that your personal information collected by them is handled in accordance with this Privacy Policy and the Australian Privacy Principles.
6
  If you are concerned that there may have been a breach of this privacy policy by a franchisee, please contact the relevant franchisee entity or McDonald’s restaurant directly.
7
+ Our Websites or Apps contain links to sites operated by third parties. We are not responsible for the privacy practices of, or any content on, those sites linked to our Websites and Apps. If you visit one of these linked websites, we encourage you to review their privacy and other policies.
8
+ We may use third party advertisements on our Websites and Apps. All third party advertising, if paid for, is paid for by the relevant third party advertisers. Third party advertisements are not recommendations or endorsements by McDonald’s or any of its affiliates. To the extent permitted by law, McDonald’s is not responsible for the content (including representations) of any third party advertisement on a Website or App. Cookies may be associated with these advertisements to enable the advertiser to track the number of anonymous users responding to the campaign.
9
+ McDonald’s collects personal information about you in a number of ways, including when you: use our websites (including mcdonalds.com.au), social media pages, and internal websites or intranet (“Website”).
SEM/txt/1/update.txt CHANGED
@@ -1,2 +1,3 @@
1
  From time to time, it may be necessary for McDonald's to change this privacy policy without notice. We will post any changes to this privacy policy on our Websites and Apps. Rest assured, however, that any changes will not be retroactively applied and will not alter how we handle previously collected personal information.
2
  If McDonald’s merges with, is acquired by another company, or sells all or a portion of its assets, your personal information may be disclosed to our advisers and any prospective purchaser’s adviser and may be among the assets transferred. However, your personal information will always remain subject to this privacy policy.
 
 
1
  From time to time, it may be necessary for McDonald's to change this privacy policy without notice. We will post any changes to this privacy policy on our Websites and Apps. Rest assured, however, that any changes will not be retroactively applied and will not alter how we handle previously collected personal information.
2
  If McDonald’s merges with, is acquired by another company, or sells all or a portion of its assets, your personal information may be disclosed to our advisers and any prospective purchaser’s adviser and may be among the assets transferred. However, your personal information will always remain subject to this privacy policy.
3
+ From time to time, it may be necessary for McDonald's to change this privacy policy without notice. We will post any changes to this privacy policy on our Websites and Apps. Rest assured, however, that any changes will not be retroactively applied and will not alter how we handle previously collected personal information.
SEM/txt/1/user_right.txt CHANGED
@@ -1 +1,8 @@
1
  McDonald’s provides areas on Websites, Apps and various social media platforms where you can upload user-generated content, post or provide information about yourself, communicate with other users, provide reviews for content, products and/or services or interact with or vote on particular content. This information may be publicly posted on a Website, App or social media platforms and/or shared with others, including social media platforms and other public forums in which you choose to participate. This information may become publicly available and may be read, collected and used by others outside of a McDonald’s Website or App. McDonald’s is not responsible for the conduct of others who may read, collect and use this information.
 
 
 
 
 
 
 
 
1
  McDonald’s provides areas on Websites, Apps and various social media platforms where you can upload user-generated content, post or provide information about yourself, communicate with other users, provide reviews for content, products and/or services or interact with or vote on particular content. This information may be publicly posted on a Website, App or social media platforms and/or shared with others, including social media platforms and other public forums in which you choose to participate. This information may become publicly available and may be read, collected and used by others outside of a McDonald’s Website or App. McDonald’s is not responsible for the conduct of others who may read, collect and use this information.
2
+ You don’t have to provide any personal information to us. However, if you do not do so, this may affect or completely restrict your ability to use our products and services, including our Websites or App, our ability to provide you with relevant content, prizes, products and services, or our ability to process your queries and employment applications.
3
+ If you would like to opt out of receiving advertising communications from us, the McDonald’s Family and our trusted third parties, you can unsubscribe.
4
+ If you no longer wish to receive any communications from McDonald’s via an App, you can delete the App from your device.
5
+ You are in control of any personal information you provide to us. If, at any time, you would like to access, review, correct and/or delete the personal information we have about you, or if you would like to change your contact preferences, you can let us know via the contact details listed below. Please allow 30 days for this request to be processed.
6
+ McDonald’s do not control the use or disclosure of personal information and may not have access to the personal information held by McDonald’s franchisees. McDonald’s franchisees are each independently responsible for ensuring that your personal information collected by them is handled in accordance with this Privacy Policy and the Australian Privacy Principles.
7
+ If you have any questions about our privacy policy, or any problems or complaints about how we have collected, used, stored, handled and/or disclosed your personal information, please contact us at.
8
+ When you use one of our Websites or Apps, we may also collect personal information about you in the following general categories: Employee information: If you are a job applicant, an employee in one of our restaurants or our corporate offices, or a former employee, and use a Website or App, we collect information about the training modules you have completed, the forms you have submitted, personal information you have provided, the approvals you have given or received, and other similar information related to your job.
app.py CHANGED
@@ -26,6 +26,12 @@ from google.oauth2 import service_account
26
  from googleapiclient.discovery import build
27
  from googleapiclient.http import MediaFileUpload
28
 
 
 
 
 
 
 
29
  title = "Cpp4App_test"
30
  description = "Automated Contextual Privacy Policies Generation for Mobile Apps"
31
 
@@ -149,21 +155,27 @@ def write_and_read():
149
  with open('myfile.txt', 'r') as f:
150
  data = f.read()
151
 
152
- print("this is data: ", data)
153
 
154
  return data
155
 
156
  def run_demo(img_root, output_root, segment_root, file):
157
- print(type(file))
158
 
159
  # file_content = file.read().decode('utf-8')
160
  run_single_pp(file)
161
 
162
- output_board, output_data, complete_result = run_single_img(img_root, output_root, segment_root)
163
 
164
- return output_board, output_data, complete_result
 
 
 
 
165
 
166
  def inference(img, html):
 
 
167
 
168
  write_and_read()
169
 
@@ -195,31 +207,65 @@ def inference(img, html):
195
  # with open(pp_root, 'w', encoding='utf-8') as file: # Open the destination file in text mode
196
  # file.write(html) # Write the HTML content to the destination file
197
 
198
- try:
199
- response = requests.get(html)
200
- response.raise_for_status() # Will raise an exception if the status is an error
201
- input_text = response.text
202
- except requests.HTTPError:
203
- input_text = ""
204
- # print("input_text: ", input_text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  with open(pp_root, 'w', encoding='utf-8') as file:
206
  file.write(input_text)
207
 
208
  soup = BeautifulSoup(open(pp_root, encoding='utf-8'), features="html.parser")
209
  # print("pp_root soup: ", soup.contents)
210
 
211
- output_board, output_data, complete_result = run_demo(img_root, output_root, segment_root, pp_root)
212
-
213
 
214
- # 确保 output_board 是图像对象
215
- print(f"output_board type: {type(output_board)}") # 检查类型
216
- if isinstance(output_board, tuple):
217
- # 如果是 tuple,转换为 NumPy 数组或其他图像格式
218
- output_board = np.array(output_board)
219
 
220
  # print(output_data)
221
 
222
- return output_board, output_data, complete_result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
 
224
  # inputs = [
225
  # gr.inputs.Image(type="pil", label="Image Upload"),
@@ -325,7 +371,7 @@ def new_example_inference_3():
325
  # def toggle_dataframe_callback():
326
  # complete_result_dataframe.visible = not complete_result_dataframe.visible
327
 
328
- with gr.Blocks(css="""
329
  button[class*="btn"] {
330
  all: unset; /* 移除所有样式 */
331
  display: inline-block; /* 确保按钮仍然是块元素 */
@@ -339,55 +385,31 @@ with gr.Blocks(css="""
339
  border-radius: 5px !important;
340
  text-align: center;
341
  }
342
-
343
  .icon-buttons {
344
  display: none;
345
  }
346
-
347
- .img label{
348
- display: none;
349
- }
350
-
351
- .title {
352
- font-size: 80px !important;
353
- font-weight: bolder;
354
- margin-top: 50px;
355
- }
356
-
357
- .title_msg1 {
358
- font-size: 60px !important;
359
- margin-top: 10px;
360
- font-weight: bolder;
361
- }
362
-
363
- .title_msg2 {
364
- font-weight: bolder;
365
- }
366
-
367
- .title_img img {
368
- border-radius: 0px !important;
369
- cursor: default;
370
- }
371
-
372
- .title_img {
373
- border-radius: 0px !important;
374
  }
375
 
376
- .eg_title h1{
377
- font-size: 50px !important;
378
- font-weight: bolder;
379
- margin-top: 120px !important;
380
  }
381
-
382
- .eg_msg {
383
- font-weight: bolder;
384
- margin-left: 10px;
385
- margin-top: 10px;
386
- margin-bottom: 20px;
 
387
  }
388
-
389
  .eg_img {
390
- width: 80%; /* 调整图片大小 */
391
  padding: 0;
392
  display: block;
393
  margin: 0 auto; /* 图片居中 */
@@ -396,54 +418,43 @@ with gr.Blocks(css="""
396
  background-size: cover !important;
397
  background-position: center !important;
398
  background-repeat: no-repeat !important;
399
- padding-bottom: 169% !important;
400
  }
401
-
402
  .eg_img:hover {
403
  border-color: rgb(117, 209, 255) !important; /* 悬停时边框颜色 */
404
  border-width: 2px !important; /* 悬停时边框粗细 */
405
  }
406
-
407
  .eg1 {
408
  background-image: url('https://buyanghc.github.io/eg1.jpg') !important;
409
  }
410
-
411
  .eg2 {
412
  background-image: url('https://buyanghc.github.io/eg2.jpg') !important;
413
  }
414
-
415
  .eg3 {
416
  background-image: url('https://buyanghc.github.io/eg3.jpg') !important;
417
  }
418
-
419
  .eg_img_msg {
420
  text-align: center; /* 文本居中 */
421
- margin-top: 10px;
422
  }
423
 
424
- .example_imgs {
425
- display: flex;
426
- gap: 60px; /* 调整列之间的间距 */
427
- margin-bottom: 120px;
428
- width: 100%;
429
- }
430
-
431
- .col {
432
- height: 100%;
433
- }
434
-
435
- .work_title h1{
436
- font-size: 50px !important;
437
- font-weight: bolder;
438
- text-align: left;
439
  }
440
 
441
  .btn-container {
 
442
  display: flex;
443
- justify-content: flex-end; /* 按钮容器中的内容右对齐 */
444
  gap: 45px; /* 按钮之间的间距 */
 
 
445
  }
446
-
447
  .btn {
448
  width: 150px;
449
  height: 45px;
@@ -451,110 +462,96 @@ with gr.Blocks(css="""
451
  transition: border-color 0.3s ease, color 0.3s ease, background-color 0.3s ease !important;
452
  border-radius: 5px;
453
  }
454
-
455
  .btn_run {
456
  color: white !important;
457
  background-color: rgb(40, 40, 40) !important;
458
  }
459
-
460
  .btn_reset {
461
  background-color: rgb(234, 234, 234) !important;
462
  }
463
-
464
  .btn:hover{
465
  color: white !important;
466
  background-color: rgb(117, 209, 255) !important;
467
  border: white !important;
468
  }
469
 
470
- .work_head{
471
- margin-bottom: 80px;
 
 
 
 
 
472
  }
473
 
474
- .work2{
475
- margin-top: 70px;
476
- margin-bottom: 300px;
477
  display: flex;
478
- justify-content: center; /* 垂直方向居中 */
479
- align-items: center;
480
- }
481
-
482
- .work_msg{
483
- margin-bottom: 10px;
484
- }
485
-
486
- .image_show{
487
- width: 100%;
488
- height: calc(100vw * 0.6);
489
- }
490
-
491
- .point{
492
- all: unset;
493
- width: 50%;
494
- height: auto;
495
- border-radius: 0px !important;
496
- cursor: default !important;
497
- border: none !important;
498
  }
499
-
500
- """) as demo:
501
 
502
- # 创建标题和旁边的图片
503
- with gr.Row():
504
- with gr.Column(scale=1):
505
- gr.Markdown("<h1 style='font-size: 80px; font-weight: border;'>Cpp4App</h1>", elem_classes="title")
506
- gr.Markdown("<h2>Automated Contextual Privacy Policies Generation </h2>", elem_classes="title_msg1")
507
- gr.Markdown("<h2>for Mobile Apps.</h2>",elem_classes="title_msg2")
508
 
 
509
  with gr.Column(scale=1):
510
- gr.Image("images/head.jpg", elem_classes="title_img img")
511
-
512
- with gr.Column():
513
- gr.Markdown("<h1 style='font-size: 80px; font-weight: border;'>· EXAMPLES</h1>", elem_classes="eg_title")
514
- gr.Markdown("<h2>Click to run the example !</h2>", elem_classes="eg_msg")
515
-
516
- with gr.Row(elem_classes="example_imgs"):
517
- with gr.Column(scale=1, elem_classes="col"):
518
- eg1_img = gr.Button("", elem_classes="eg_img eg1")
519
- gr.Markdown("<h2>· WhatsApp</h2>", elem_classes="eg_img_msg")
520
-
521
- with gr.Column(scale=1, elem_classes="col"):
522
- eg2_img = gr.Button("", elem_classes="eg_img eg2")
523
- gr.Markdown("<h2>· Snap</h2>", elem_classes="eg_img_msg")
524
 
525
- with gr.Column(scale=1, elem_classes="col"):
526
- eg3_img = gr.Button("", elem_classes="eg_img eg3")
527
- gr.Markdown("<h2>· Mcdonald's</h2>", elem_classes="eg_img_msg")
528
 
529
- with gr.Row(elem_classes="work_head"):
530
- with gr.Column(scale=8):
531
- gr.Markdown("<h1 style='font-size: 80px; font-weight: bold;'>· WORKSPACE</h1>", elem_classes="work_title")
532
 
533
- with gr.Column(scale=4):
534
- with gr.Row(elem_classes="btn-container"):
535
- run_btn = gr.Button("RUN", elem_classes="btn btn_run")
536
- reset_btn = gr.Button("RESET", elem_classes="btn btn_reset")
537
 
538
  with gr.Column():
539
- gr.Markdown("<h2>Step 1 : Input privacy policy URL</h2>", elem_classes="work_msg")
540
- text_input = gr.Textbox(label="URL Input for the Privacy Policy of the App", elem_classes="url")
541
 
542
  with gr.Row(elem_classes="work2"):
543
- with gr.Column(scale=6):
544
- gr.Markdown("<h2>Step 2 : Upload the screenshot</h2>", elem_classes="work_msg")
 
 
 
545
  image_input = gr.Image(type="pil", label="Screenshot Upload", elem_classes="image_show")
 
 
 
 
 
 
 
546
 
547
- with gr.Column(scale=1):
548
- gr.Image("images/point.png", elem_classes="point img")
 
549
 
550
- with gr.Column(scale=6):
551
- gr.Markdown("<h2>Output :</h2>", elem_classes="work_msg")
552
- result_image = gr.Image(type="pil", label="Result Screenshot", elem_classes="image_show")
 
553
 
 
 
 
 
 
 
 
554
 
555
 
556
  run_btn.click(inference, inputs=[image_input, text_input], outputs=[result_image])
557
  reset_btn.click(lambda: [None, None, None, None, None, None], inputs=[], outputs=[image_input, text_input, result_image])
 
 
 
 
 
558
  # example_button.click(example_inference, inputs=[], outputs=[image_input, text_input, result_image, result_dataframe])
559
  eg1_img.click(new_example_inference_1,
560
  inputs=[],
 
26
  from googleapiclient.discovery import build
27
  from googleapiclient.http import MediaFileUpload
28
 
29
+ from dotenv import load_dotenv
30
+ import os
31
+
32
+ # 加载 .env 文件中的环境变量
33
+ load_dotenv()
34
+
35
  title = "Cpp4App_test"
36
  description = "Automated Contextual Privacy Policies Generation for Mobile Apps"
37
 
 
155
  with open('myfile.txt', 'r') as f:
156
  data = f.read()
157
 
158
+ # print("this is data: ", data)
159
 
160
  return data
161
 
162
  def run_demo(img_root, output_root, segment_root, file):
163
+ # print(type(file))
164
 
165
  # file_content = file.read().decode('utf-8')
166
  run_single_pp(file)
167
 
168
+ output_boards = run_single_img(img_root, output_root, segment_root)
169
 
170
+ return output_boards
171
+
172
+ # 定义全局变量存储图集和当前显示的图片索引
173
+ image_list = []
174
+ current_image_index = 0
175
 
176
  def inference(img, html):
177
+ start = time.process_time()
178
+ global output_boards, current_image_index # 让output_boards成为全局变量
179
 
180
  write_and_read()
181
 
 
207
  # with open(pp_root, 'w', encoding='utf-8') as file: # Open the destination file in text mode
208
  # file.write(html) # Write the HTML content to the destination file
209
 
210
+ # 使用网址命名html文件
211
+ html_folder = "./html_files"
212
+ if not os.path.exists(html_folder):
213
+ os.makedirs(html_folder)
214
+
215
+ # 使用网址创建合法的文件名
216
+ html_filename = os.path.join(html_folder, html.replace("://", "_").replace("/", "_") + ".html")
217
+
218
+ # 如果html文件不存在则下载并保存
219
+ if not os.path.exists(html_filename):
220
+ try:
221
+ response = requests.get(html)
222
+ response.raise_for_status() # Will raise an exception if the status is an error
223
+ input_text = response.text
224
+ # 将HTML内容保存到文件
225
+ with open(html_filename, 'w', encoding='utf-8') as file:
226
+ file.write(input_text)
227
+ except requests.HTTPError:
228
+ input_text = ""
229
+ else:
230
+ # 如果文件存在,则直接读取
231
+ with open(html_filename, 'r', encoding='utf-8') as file:
232
+ input_text = file.read()
233
+
234
  with open(pp_root, 'w', encoding='utf-8') as file:
235
  file.write(input_text)
236
 
237
  soup = BeautifulSoup(open(pp_root, encoding='utf-8'), features="html.parser")
238
  # print("pp_root soup: ", soup.contents)
239
 
240
+ output_boards = run_demo(img_root, output_root, segment_root, pp_root)
 
241
 
242
+ for i in range(len(output_boards)):
243
+ # 确保 output_board 是图像对象
244
+ if isinstance(output_boards[i], tuple):
245
+ # 如果是 tuple,转换为 NumPy 数组或其他图像格式
246
+ output_boards[i] = np.array(output_boards[i])
247
 
248
  # print(output_data)
249
 
250
+ current_image_index = 0 # 每次运行inference后重置图片索引
251
+
252
+ total = time.process_time() - start
253
+ print(f"total processing time of this screenshot: {total:.2f}s")
254
+ return output_boards[current_image_index] # 返回图集中的第一张图像
255
+
256
+ # 向左切换图片
257
+ def previous_image():
258
+ global current_image_index
259
+ if current_image_index > 0:
260
+ current_image_index -= 1
261
+ return output_boards[current_image_index]
262
+
263
+ # 向右切换图片
264
+ def next_image():
265
+ global current_image_index
266
+ if current_image_index < len(output_boards) - 1:
267
+ current_image_index += 1
268
+ return output_boards[current_image_index]
269
 
270
  # inputs = [
271
  # gr.inputs.Image(type="pil", label="Image Upload"),
 
371
  # def toggle_dataframe_callback():
372
  # complete_result_dataframe.visible = not complete_result_dataframe.visible
373
 
374
+ with gr.Blocks(css='''
375
  button[class*="btn"] {
376
  all: unset; /* 移除所有样式 */
377
  display: inline-block; /* 确保按钮仍然是块元素 */
 
385
  border-radius: 5px !important;
386
  text-align: center;
387
  }
388
+
389
  .icon-buttons {
390
  display: none;
391
  }
392
+
393
+ body {
394
+ display: flex;
395
+ justify-content: center;
396
+ margin: 0; /* 去除默认的 body 外边距 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
397
  }
398
 
399
+ h1, h2{
400
+ width: 100%;
 
 
401
  }
402
+
403
+ .example_imgs {
404
+ width: 100%;
405
+ display: flex;
406
+ justify-content: flex-start; /* 图片居左对齐 */
407
+ align-items: flex-start; /* 垂直居中对齐 */
408
+ gap: 20px; /* 控制图片之间的间距 */
409
  }
410
+
411
  .eg_img {
412
+ width: 40%; /* 调整图片大小 */
413
  padding: 0;
414
  display: block;
415
  margin: 0 auto; /* 图片居中 */
 
418
  background-size: cover !important;
419
  background-position: center !important;
420
  background-repeat: no-repeat !important;
421
+ padding-bottom: 80% !important;
422
  }
423
+
424
  .eg_img:hover {
425
  border-color: rgb(117, 209, 255) !important; /* 悬停时边框颜色 */
426
  border-width: 2px !important; /* 悬停时边框粗细 */
427
  }
428
+
429
  .eg1 {
430
  background-image: url('https://buyanghc.github.io/eg1.jpg') !important;
431
  }
432
+
433
  .eg2 {
434
  background-image: url('https://buyanghc.github.io/eg2.jpg') !important;
435
  }
436
+
437
  .eg3 {
438
  background-image: url('https://buyanghc.github.io/eg3.jpg') !important;
439
  }
440
+
441
  .eg_img_msg {
442
  text-align: center; /* 文本居中 */
 
443
  }
444
 
445
+ .col{
446
+ width: 20% !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
447
  }
448
 
449
  .btn-container {
450
+ width: 100%
451
  display: flex;
452
+ justify-content: center; /* 按钮容器中的内容右对齐 */
453
  gap: 45px; /* 按钮之间的间距 */
454
+ margin-top: 15px;
455
+ margin-bottom: 15px;
456
  }
457
+
458
  .btn {
459
  width: 150px;
460
  height: 45px;
 
462
  transition: border-color 0.3s ease, color 0.3s ease, background-color 0.3s ease !important;
463
  border-radius: 5px;
464
  }
465
+
466
  .btn_run {
467
  color: white !important;
468
  background-color: rgb(40, 40, 40) !important;
469
  }
470
+
471
  .btn_reset {
472
  background-color: rgb(234, 234, 234) !important;
473
  }
474
+
475
  .btn:hover{
476
  color: white !important;
477
  background-color: rgb(117, 209, 255) !important;
478
  border: white !important;
479
  }
480
 
481
+ .change_btn{
482
+ width: 55px !important;
483
+ height: 25px !important;
484
+ border-radius: 50% !important;
485
+ background-color: rgb(234, 234, 234) !important;
486
+ padding: 0 !important;
487
+ margin: 0 !important;
488
  }
489
 
490
+ .btn-container2 {
491
+ width: 40%;
 
492
  display: flex;
493
+ justify-content: flex-end; /* 按钮容器的内容右对齐 */
494
+ gap: 20px; /* 按钮之间的间距 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
  }
 
 
496
 
497
+ ''') as demo:
 
 
 
 
 
498
 
499
+ with gr.Row():
500
  with gr.Column(scale=1):
501
+ gr.Markdown("<h1 style='font-size: 50px; font-weight: border; text-align: center;'>Cpp4App</h1>", elem_classes="title")
502
+ gr.Markdown("<p style='text-align: center;'>Automated Contextual Privacy Policies Generation for Mobile Apps.</p>", elem_classes="title_msg1")
503
+ gr.Markdown("<p style='text-align: center; margin-top: -15px;'>[Usage] Upload the screenshot and privacy policy URL link, then click 'RUN' button.</p>", elem_classes="title_msg1")
 
 
 
 
 
 
 
 
 
 
 
504
 
505
+ # with gr.Column(scale=1):
506
+ # gr.Image("images/head.jpg", elem_classes="title_img img")
 
507
 
 
 
 
508
 
509
+ with gr.Row(elem_classes="btn-container"):
510
+ run_btn = gr.Button("RUN", elem_classes="btn btn_run")
511
+ reset_btn = gr.Button("RESET", elem_classes="btn btn_reset")
 
512
 
513
  with gr.Column():
 
 
514
 
515
  with gr.Row(elem_classes="work2"):
516
+ with gr.Column(elem_classes="col_big", scale=1):
517
+ gr.Markdown("<p style='font-weight: bold; font-size: 18px;'>Step 1 : Input privacy policy URL ⬇️</p>", elem_classes="work_msg")
518
+ text_input = gr.Textbox(label="URL Input for the Privacy Policy of the App", elem_classes="url")
519
+ with gr.Column(elem_classes="col_big", scale=1):
520
+ gr.Markdown("<p style='font-weight: bold; font-size: 18px;'>Step 2 : Upload the screenshot ⬇️</p>", elem_classes="work_msg")
521
  image_input = gr.Image(type="pil", label="Screenshot Upload", elem_classes="image_show")
522
+ with gr.Column(elem_classes="col_big", scale=1):
523
+ with gr.Row():
524
+ gr.Markdown("<p style='width: 60%; font-weight: bold; font-size: 18px;'>Output 🌟:</p>", elem_classes="work_msg")
525
+ with gr.Row(elem_classes="btn-container2"):
526
+ previous_button = gr.Button("<", elem_classes="change_btn")
527
+ next_button = gr.Button(">", elem_classes="change_btn")
528
+ result_image = gr.Image(type="pil", label="Result Screenshot", elem_classes="image_show")
529
 
530
+ with gr.Column():
531
+ gr.Markdown("<h2 style='font-size: 18px; font-weight: border;'>You can try with three examples we provided:</h2>", elem_classes="eg_title")
532
+ gr.Markdown("<p>· Click the picture to run.</p>", elem_classes="eg_msg")
533
 
534
+ with gr.Row(elem_classes="example_imgs"):
535
+ with gr.Column(elem_classes="col"):
536
+ eg1_img = gr.Button("", elem_classes="eg_img eg1")
537
+ gr.Markdown("<h2 style='font-size: 18px; font-weight: border;'>· WhatsApp</h2>", elem_classes="eg_img_msg")
538
 
539
+ with gr.Column(elem_classes="col"):
540
+ eg2_img = gr.Button("", elem_classes="eg_img eg2")
541
+ gr.Markdown("<h2 style='font-size: 18px; font-weight: border;'>· Snap</h2>", elem_classes="eg_img_msg")
542
+
543
+ with gr.Column(elem_classes="col"):
544
+ eg3_img = gr.Button("", elem_classes="eg_img eg3")
545
+ gr.Markdown("<h2 style='font-size: 18px; font-weight: border;'>· Mcdonald's</h2>", elem_classes="eg_img_msg")
546
 
547
 
548
  run_btn.click(inference, inputs=[image_input, text_input], outputs=[result_image])
549
  reset_btn.click(lambda: [None, None, None, None, None, None], inputs=[], outputs=[image_input, text_input, result_image])
550
+
551
+ # 点击左右切换按钮时切换显示的图片
552
+ previous_button.click(previous_image, outputs=result_image)
553
+ next_button.click(next_image, outputs=result_image)
554
+
555
  # example_button.click(example_inference, inputs=[], outputs=[image_input, text_input, result_image, result_dataframe])
556
  eg1_img.click(new_example_inference_1,
557
  inputs=[],
logs/app.log CHANGED
@@ -1,2 +0,0 @@
1
- 2024-08-30 07:10:40 - INFO - Memory usage: 92.3% (Total: 34359738368, Used: 3372806144, Free: 22478848)
2
- 2024-08-30 07:10:40 - INFO - Disk usage: 6.2% (Total: 994662584320, Used: 20487077888, Free: 308522999808)