@@ -88,6 +88,92 @@ fn get_user_range(prompt: &str) -> Result<std::ops::Range<i64>> {
8888 }
8989}
9090
91+ // 计算图像的平滑度得分,得分越低表示图像相邻像素颜色差异越小,图像越平滑,越可能是正确结果
92+ fn calculate_smoothness_score ( image : & RgbImage ) -> f64 {
93+ let ( width, height) = image. dimensions ( ) ;
94+ if width < 2 || height < 2 {
95+ return f64:: MAX ;
96+ }
97+
98+ let mut total_diff: u64 = 0 ;
99+
100+ // 遍历几乎所有像素,计算其与右侧和下方像素的差异
101+ for y in 0 ..height - 1 {
102+ for x in 0 ..width - 1 {
103+ let p1 = image. get_pixel ( x, y) ;
104+ let p2 = image. get_pixel ( x + 1 , y) ; // 右侧像素
105+ let p3 = image. get_pixel ( x, y + 1 ) ; // 下方像素
106+
107+ // 计算RGB通道的绝对差值之和
108+ let diff_h = ( p1[ 0 ] as i16 - p2[ 0 ] as i16 ) . abs ( ) as u32 +
109+ ( p1[ 1 ] as i16 - p2[ 1 ] as i16 ) . abs ( ) as u32 +
110+ ( p1[ 2 ] as i16 - p2[ 2 ] as i16 ) . abs ( ) as u32 ;
111+
112+ let diff_v = ( p1[ 0 ] as i16 - p3[ 0 ] as i16 ) . abs ( ) as u32 +
113+ ( p1[ 1 ] as i16 - p3[ 1 ] as i16 ) . abs ( ) as u32 +
114+ ( p1[ 2 ] as i16 - p3[ 2 ] as i16 ) . abs ( ) as u32 ;
115+
116+ total_diff += ( diff_h + diff_v) as u64 ;
117+ }
118+ }
119+
120+ // 将总差异标准化,避免图像尺寸影响得分
121+ let num_comparisons = ( width - 1 ) * ( height - 1 ) * 2 ;
122+ if num_comparisons == 0 {
123+ return f64:: MAX ;
124+ }
125+ total_diff as f64 / num_comparisons as f64
126+ }
127+
128+ // 分析输出目录中的所有图像,并根据平滑度得分排序,列出最可能的结果
129+ fn analyze_results ( output_dir : & Path ) -> Result < ( ) > {
130+ let entries = fs:: read_dir ( output_dir)
131+ . with_context ( || format ! ( "❌ 无法读取分析目录: {:?}" , output_dir) ) ?
132+ . filter_map ( Result :: ok)
133+ . filter ( |e| e. path ( ) . extension ( ) . and_then ( |s| s. to_str ( ) ) == Some ( "png" ) )
134+ . collect :: < Vec < _ > > ( ) ;
135+
136+ if entries. is_empty ( ) {
137+ println ! ( "🤷♀️ 在输出目录中未找到任何 .png 文件进行分析" ) ;
138+ return Ok ( ( ) ) ;
139+ }
140+
141+ let bar_style = ProgressStyle :: default_bar ( )
142+ . template ( "{spinner:.cyan} [{elapsed_precise}] [{bar:40.yellow/red}] {pos}/{len} ({percent}%) 分析中: {msg}" )
143+ . unwrap ( )
144+ . progress_chars ( "=> " ) ;
145+ let bar = ProgressBar :: new ( entries. len ( ) as u64 ) . with_style ( bar_style) ;
146+
147+ let mut scored_images: Vec < ( PathBuf , f64 ) > = entries
148+ . par_iter ( )
149+ . progress_with ( bar)
150+ . filter_map ( |entry| {
151+ let path = entry. path ( ) ;
152+ if let Ok ( image) = image:: open ( & path) {
153+ let score = calculate_smoothness_score ( & image. to_rgb8 ( ) ) ;
154+ Some ( ( path, score) )
155+ } else {
156+ None
157+ }
158+ } )
159+ . collect ( ) ;
160+
161+ // 根据平滑度进行升序排序,得分越低越好
162+ scored_images. sort_by ( |a, b| a. 1 . partial_cmp ( & b. 1 ) . unwrap_or ( std:: cmp:: Ordering :: Equal ) ) ;
163+
164+ println ! ( "\n 🔍 分析完成,以下是可能性最高的 5 个结果 (得分越低越可能是正确结果):" ) ;
165+ println ! ( "---------------------------------------------------------------------------------" ) ;
166+
167+ for ( path, score) in scored_images. iter ( ) . take ( 5 ) {
168+ if let Some ( filename) = path. file_name ( ) . and_then ( |s| s. to_str ( ) ) {
169+ println ! ( " - 📄 文件: {:<25} | 📉 得分: {:.2}" , filename, score) ;
170+ }
171+ }
172+ println ! ( "---------------------------------------------------------------------------------" ) ;
173+
174+ Ok ( ( ) )
175+ }
176+
91177fn main ( ) -> Result < ( ) > {
92178 println ! ( r"" ) ;
93179 println ! ( r"================================================================================================================" ) ;
@@ -182,6 +268,11 @@ fn main() -> Result<()> {
182268 println ! ( "\n ⏱️ 用时: {:.2} 秒" , duration. as_secs_f64( ) ) ;
183269
184270 println ! ( "🎉 处理完成" ) ;
271+
272+ if let Err ( e) = analyze_results ( & output_dir) {
273+ eprintln ! ( "❌ 分析过程中发生错误: {:?}" , e) ;
274+ }
275+
185276 pause_before_exit ( ) ;
186277 Ok ( ( ) )
187278}
0 commit comments