File size: 2,319 Bytes
dda557a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { motion } from 'framer-motion'

export default function GradCamViewer({ original, gradcam }) {
  if (!gradcam) {
    return (
      <div className="p-6 rounded-2xl glass text-center text-gray-400 text-sm">
        Grad-CAM visualization unavailable.
      </div>
    )
  }

  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.5, delay: 0.2 }}
      className="rounded-2xl glass-strong p-6"
    >
      <div className="flex items-center justify-between mb-4">
        <div>
          <h3 className="font-semibold text-white">Model Focus (Grad-CAM)</h3>
          <p className="text-xs text-gray-400 mt-0.5">
            Warm areas show where the network paid the most attention.
          </p>
        </div>
        <span className="text-[10px] uppercase tracking-widest text-violet-300 px-2 py-1 rounded-md bg-violet-500/10 border border-violet-500/30">
          Explainability
        </span>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        <ImagePanel title="Original" src={original} />
        <ImagePanel title="Heatmap overlay" src={gradcam} highlight />
      </div>

      <ColorLegend />
    </motion.div>
  )
}

function ImagePanel({ title, src, highlight }) {
  return (
    <div className="flex flex-col">
      <span className="text-xs text-gray-400 mb-2 uppercase tracking-wider">{title}</span>
      <div
        className={`rounded-xl overflow-hidden border ${
          highlight ? 'border-violet-400/40 shadow-glow-violet' : 'border-white/10'
        } bg-black/40`}
      >
        {src ? (
          <img src={src} alt={title} className="w-full h-auto block" />
        ) : (
          <div className="aspect-square flex items-center justify-center text-gray-500 text-xs">
            unavailable
          </div>
        )}
      </div>
    </div>
  )
}

function ColorLegend() {
  return (
    <div className="mt-4 flex items-center gap-3 text-[11px] text-gray-400">
      <span>Low focus</span>
      <div
        className="flex-1 h-2 rounded-full"
        style={{
          background:
            'linear-gradient(to right, #00007f, #0000ff, #00ffff, #00ff00, #ffff00, #ff8000, #ff0000, #7f0000)',
        }}
      />
      <span>High focus</span>
    </div>
  )
}