@@ -71,21 +71,127 @@ def get_path_list(self, dir_path):
71
71
for a in all_files ]
72
72
return all_paths
73
73
74
+
75
+ def select_highest_entropy_image (self ):
76
+ """
77
+ Return filename of active image with highest entropy among
78
+ active images *after* the current image, or None if unavailable.
79
+ """
80
+ active_images_path = os .path .join (self .parent .proj_location , "active_images.txt" )
81
+ uncertainty_dir = os .path .join (self .parent .proj_location , "uncertainty" )
82
+
83
+ if not (os .path .isfile (active_images_path ) and os .path .isdir (uncertainty_dir )):
84
+ return None
85
+
86
+ # Get active images set
87
+ with open (active_images_path , "r" ) as f :
88
+ active_images = {line .strip () for line in f if line .strip ()}
89
+
90
+ # Determine current image position
91
+ current_fname = os .path .basename (self .image_path )
92
+ try :
93
+ current_idx = self .all_fnames .index (current_fname )
94
+ except ValueError :
95
+ return None # safety fallback
96
+
97
+ # Only consider images after current
98
+ future_images = set (self .all_fnames [current_idx + 1 :])
99
+ candidate_images = active_images .intersection (future_images )
100
+
101
+ # Gather entropy scores for candidates
102
+ entropy_scores = {}
103
+ for fname in candidate_images :
104
+ score_file = os .path .join (uncertainty_dir , fname + ".txt" )
105
+ if os .path .isfile (score_file ):
106
+ try :
107
+ with open (score_file , "r" ) as f_score :
108
+ entropy = float (f_score .read ().strip ())
109
+ entropy_scores [fname ] = entropy
110
+ except Exception :
111
+ continue
112
+
113
+ if not entropy_scores :
114
+ return None
115
+
116
+ return max (entropy_scores , key = entropy_scores .get )
117
+
118
+
119
+ def prefill_next_active_image (self ):
120
+ """
121
+ Check if next even-index image (after current) is active and replace with highest entropy image.
122
+ """
123
+ current_idx = self .all_fnames .index (os .path .basename (self .image_path ))
124
+ next_idx = current_idx + 1
125
+ if next_idx >= len (self .all_fnames ):
126
+ return # no next image
127
+
128
+ # Check if next image is in active list
129
+ active_images_path = os .path .join (self .parent .proj_location , "active_images.txt" )
130
+ if not os .path .isfile (active_images_path ):
131
+ return
132
+
133
+ with open (active_images_path , "r" ) as f :
134
+ active_images = {line .strip () for line in f if line .strip ()}
135
+
136
+ next_image_name = self .all_fnames [next_idx ]
137
+ if next_image_name not in active_images :
138
+ return # next image is not active → no replacement
139
+
140
+ # Select best future active image
141
+ next_entropy_fname = self .select_highest_entropy_image ()
142
+ if not next_entropy_fname :
143
+ return
144
+
145
+ # Replace only if different
146
+ if self .all_fnames [next_idx ] != next_entropy_fname :
147
+ print (f"Prefill active: replacing { self .all_fnames [next_idx ]} → { next_entropy_fname } " )
148
+ self .all_fnames [next_idx ] = next_entropy_fname
149
+
150
+ # Save updated list to project file
151
+ import json
152
+ project_file = self .parent .proj_file_path
153
+ with open (project_file , 'r' ) as f :
154
+ project_data = json .load (f )
155
+ project_data ['file_names' ] = self .all_fnames
156
+ with open (project_file , 'w' ) as f :
157
+ json .dump (project_data , f , indent = 4 )
158
+
159
+
74
160
def show_next_image (self ):
75
161
self .next_image_button .setEnabled (False )
76
162
self .next_image_button .setText ('Loading..' )
77
- self .next_image_button .setEnabled (False )
78
163
QtWidgets .QApplication .processEvents ()
164
+
165
+ # normal next
79
166
dir_path , _ = os .path .split (self .image_path )
80
167
all_paths = self .get_path_list (dir_path )
81
168
cur_idx = all_paths .index (self .image_path )
82
- next_idx = cur_idx + 1
83
- if next_idx >= len (all_paths ):
84
- next_idx = 0
85
- self .image_path = all_paths [next_idx ]
169
+ next_idx = (cur_idx + 1 ) % len (all_paths )
170
+ next_fname = os .path .basename (all_paths [next_idx ])
171
+
172
+ # if next image is active, use highest entropy image instead
173
+ next_entropy_fname = None
174
+ active_images_path = os .path .join (self .parent .proj_location , "active_images.txt" )
175
+ if os .path .isfile (active_images_path ):
176
+ with open (active_images_path , "r" ) as f :
177
+ active_images = {line .strip () for line in f if line .strip ()}
178
+ if next_fname in active_images :
179
+ next_entropy_fname = self .select_highest_entropy_image ()
180
+
181
+ if next_entropy_fname :
182
+ next_image_path = os .path .join (dir_path , next_entropy_fname )
183
+ else :
184
+ next_image_path = all_paths [next_idx ]
185
+
186
+ # update current image
187
+ self .image_path = next_image_path
86
188
self .file_change .emit (self .image_path )
87
189
self .update_nav_label ()
88
190
191
+ # prefill future active slot
192
+ self .prefill_next_active_image ()
193
+
194
+
89
195
def show_prev_image (self ):
90
196
dir_path , _ = os .path .split (self .image_path )
91
197
all_paths = self .get_path_list (dir_path )
0 commit comments