Nicha1234 commited on
Commit
2f72674
·
verified ·
1 Parent(s): 0d9cd1c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -63
app.py CHANGED
@@ -72,14 +72,15 @@ def load_kspace_data():
72
 
73
  kspace_raw = load_kspace_data()
74
 
75
- # ปรับแก้ความสว่างด้วย Log Transformation แบบ 100% สว่างคมชัด
76
  def format_kspace_display(k_data):
77
  k_mag = np.abs(k_data)
78
- if np.max(k_mag) == 0:
 
79
  return np.zeros_like(k_mag, dtype=np.uint8)
80
 
81
- # สูตร Log Transformation เพื่อดึงความสว่าง
82
- c = 255.0 / np.log(1 + np.max(k_mag))
83
  log_img = c * np.log(1 + k_mag)
84
  return log_img.astype(np.uint8)
85
 
@@ -92,64 +93,40 @@ def get_image_from_plot(fig):
92
  buf.seek(0)
93
  return Image.open(buf)
94
 
95
- # สร้างภาพแผนผังองค์ประกอบ K-Space วยโค้Matplotlib (ไม่ต้องใช้รูปภาภายอก)
96
  def draw_kspace_diagram():
97
- fig, ax = plt.subplots(figsize=(10, 6))
 
98
 
99
- c_center = '#E1B138' # สีหลืองตรงกล
100
- c_tb = '#4B8BDE' # สีฟ้าบนล่าง
101
- c_lr = '#5EAA4D' # สีเขียวซ้ายขวา
102
 
103
- # วาดโซนต
104
- ax.add_patch(plt.Rectangle((0.2, 0.2), 0.4, 0.6, facecolor=c_center, edgecolor='black', zorder=2))
105
- ax.add_patch(plt.Rectangle((0.1, 0.2), 0.1, 0.6, facecolor=c_lr, edgecolor='black', zorder=2))
106
- ax.add_patch(plt.Rectangle((0.6, 0.2), 0.1, 0.6, facecolor=c_lr, edgecolor='black', zorder=2))
107
- ax.add_patch(plt.Rectangle((0.1, 0.8), 0.6, 0.1, facecolor=c_tb, edgecolor='black', zorder=2))
108
- ax.add_patch(plt.Rectangle((0.1, 0.1), 0.6, 0.1, facecolor=c_tb, edgecolor='black', zorder=2))
109
 
110
- # วาดเส้Grid
111
- for i in range(1, 10):
112
- ax.plot([0.1, 0.7], [i*0.1, i*0.1], color='black', lw=0.5, alpha=0.5, zorder=3)
113
- for i in range(1, 7):
114
- ax.plot([0.1 + i*0.1, 0.1 + i*0.1], [0.1, 0.9], color='black', lw=0.5, alpha=0.5, zorder=3)
115
-
116
- # ตัวหนังสืออธิบาย
117
- ax.text(0.4, 0.95, "k-space data", ha='center', va='bottom', fontsize=16, fontweight='bold')
118
- ax.text(0.4, 0.85, "HIGH $K_y$ FREQUENCY ZONE\nCAPTURES HORIZONTAL EDGES", ha='center', va='center', fontsize=9, fontweight='bold')
119
- ax.text(0.4, 0.5, "LOW SPATIAL\nFREQUENCY ZONE\nCAPTURES BASIC CONTRAST", ha='center', va='center', fontsize=11, fontweight='bold')
120
-
121
- # แกน X, Y
122
- ax.annotate('', xy=(0.7, 0.05), xytext=(0.1, 0.05), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=2))
123
- ax.text(0.4, 0.0, 'Frequency Encoding (horizontal axis) $K_x$', ha='center', va='top', fontsize=14)
124
- ax.annotate('', xy=(0.05, 0.9), xytext=(0.05, 0.1), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=2))
125
- ax.text(0.0, 0.5, 'Phase Encoding\n(vertical axis) $K_y$', ha='center', va='center', rotation=90, fontsize=14)
126
-
127
- # วาดคลื่น 3 รูปแบบ
128
- x_w = np.linspace(0, 1, 300)
129
 
130
- # คลื่นน (Yellow - Low freq)
131
- y_w1 = np.sin(2 * np.pi * 2 * x_w) * 0.1 + 0.8
132
- ax.plot(x_w*0.2 + 0.8, y_w1, color=c_center, lw=3)
133
- ax.annotate('', xy=(0.78, 0.8), xytext=(0.55, 0.6), arrowprops=dict(arrowstyle='fancy', color=c_center, lw=2, connectionstyle="arc3,rad=-0.2"))
134
-
135
- # คลื่นกลาง (Blue - High freq y)
136
- y_w2 = np.sin(2 * np.pi * 12 * x_w) * 0.1 + 0.5
137
- ax.plot(x_w*0.2 + 0.8, y_w2, color=c_tb, lw=3)
138
- ax.annotate('', xy=(0.78, 0.55), xytext=(0.65, 0.85), arrowprops=dict(arrowstyle='fancy', color=c_tb, lw=2, connectionstyle="arc3,rad=0.2"))
139
 
140
- # คลืนล่ง (Green - High freq x)
141
- y_w3 = np.sin(2 * np.pi * 8 * x_w) * 0.1 + 0.2
142
- ax.plot(x_w*0.2 + 0.8, y_w3, color=c_lr, lw=3)
143
- ax.annotate('', xy=(0.78, 0.2), xytext=(0.65, 0.3), arrowprops=dict(arrowstyle='fancy', color=c_lr, lw=2, connectionstyle="arc3,rad=0.2"))
144
-
145
- ax.set_xlim(-0.05, 1.05)
146
- ax.set_ylim(-0.05, 1.05)
147
  ax.axis('off')
 
148
  return get_image_from_plot(fig)
149
 
150
  def draw_kspace_point(kx, ky, bg_image):
151
  fig, ax = plt.subplots(figsize=(4, 4))
152
- # vmin=0, vmax=255 ่วยให้ภสว่างเต็มที่
153
  ax.imshow(bg_image, cmap='gray', extent=[-112, 112, -112, 112], vmin=0, vmax=255)
154
  ax.plot(kx, ky, 'ro', markersize=6)
155
  ax.annotate('', xy=(kx, ky), xytext=(0, 0), arrowprops=dict(arrowstyle='->', color='yellow', lw=2))
@@ -186,6 +163,7 @@ def apply_filter(k_data, mode, radius):
186
 
187
  def draw_filtered_kspace(filtered_k):
188
  fig, ax = plt.subplots(figsize=(4, 4))
 
189
  ax.imshow(format_kspace_display(filtered_k), cmap='gray', vmin=0, vmax=255)
190
  ax.axis('off')
191
  return get_image_from_plot(fig)
@@ -193,7 +171,7 @@ def draw_filtered_kspace(filtered_k):
193
  def draw_mri(mri_result):
194
  fig, ax = plt.subplots(figsize=(4, 4))
195
  m_disp = mri_result / (np.max(mri_result) + 1e-8)
196
- ax.imshow(np.flipud(m_disp), cmap='gray')
197
  ax.axis('off')
198
  return get_image_from_plot(fig)
199
 
@@ -245,7 +223,6 @@ def draw_pulse_sequence(current_step, total_steps):
245
  plt.tight_layout()
246
  return get_image_from_plot(fig)
247
 
248
- # วาด Trajectory แบบลูกศรซ้ายไปขวา (เฉพาะโหมดจำลอง)
249
  def draw_kspace_filling(current_step, total_steps):
250
  fig, ax = plt.subplots(figsize=(5, 6))
251
 
@@ -295,19 +272,13 @@ with col_main:
295
  ข้อมูลใน k-space มักจะถูกนำมาแสดงผลในรูปแบบตารางสี่เหลี่ยม (Grid) โดยมีแกนหลักคือ **kx (แนวนอน - Frequency)** และ **ky (แนวตั้ง - Phase)** จุดสำคัญคือ **แกน kx และ ky เหล่านี้ ไม่ได้บอกตำแหน่งพิกัดในภาพอวัยวะ** แต่มันคือแกนที่บอกถึงลักษณะของ **"ความถี่เชิงพื้นที่"** ที่เป็นคลื่น (Sinusoidal wave) ด้วยเหตุนี้ **จุดแต่ละจุดบน K-space จึงไม่ได้จับคู่แบบ 1 ต่อ 1 กับพิกเซลบนภาพ MRI** (เช่น จุดมุมซ้ายบนของ K-space ไม่ได้สร้างภาพมุมซ้ายบนของอวัยวะ)
296
  """)
297
 
298
- _, col_img_center, _ = st.columns([1.5, 4, 1.5])
299
  with col_img_center:
300
- # ใช้กราฟโคแทนการดึงรูปภาพภายนอก
301
  st.image(draw_kspace_diagram(), use_container_width=True)
302
- # คำอ้างอิง
303
- st.markdown(
304
- """<p class="reference-text">ภาพจำลองอ้างอิงจาก: Clover Learning. (2024). <i>MRI k-space made easy - MRI physics explained</i> [Video]. YouTube.
305
- <a href="https://youtu.be/cfE6SL2Xj6o?t=68" target="_blank">https://youtu.be/cfE6SL2Xj6o?t=68</a></p>""",
306
- unsafe_allow_html=True
307
- )
308
 
309
  # ---------------------------------------------------------
310
- # NEW: K-Space Trajectories
311
  # ---------------------------------------------------------
312
  st.markdown("## 🛤️ K-Space Trajectories")
313
  st.markdown("""
@@ -398,7 +369,6 @@ with col_main:
398
  with col_img2:
399
  st.image(draw_wave(kx_val, ky_val), caption="แผ่นลวดลายคลื่น (2D Sinusoidal Wave)", use_container_width=True)
400
 
401
- # ส่วน Toggle สำหรับสังเกตคลื่น
402
  with st.expander("🔍 สังเกตลักษณะคลื่น (คลิกเพื่อดูคำอธิบายเพิ่มเติม)"):
403
  st.markdown("""
404
  **ลองปรับเลื่อนพิกัดเพื่อสังเกตความเปลี่ยนแปลง:**
 
72
 
73
  kspace_raw = load_kspace_data()
74
 
75
+ # ปรับแก้ความสว่างด้วย Log Transformation ตามสูตรของเพื่อน ให้สว่างแบบ Original
76
  def format_kspace_display(k_data):
77
  k_mag = np.abs(k_data)
78
+ max_val = np.max(k_mag)
79
+ if max_val == 0:
80
  return np.zeros_like(k_mag, dtype=np.uint8)
81
 
82
+ # สูตร Log Transformation เพื่อดึงความสว่างให้เห็นรายละเอียดเส้น K-space ชัดเจน
83
+ c = 255.0 / np.log(1 + max_val)
84
  log_img = c * np.log(1 + k_mag)
85
  return log_img.astype(np.uint8)
86
 
 
93
  buf.seek(0)
94
  return Image.open(buf)
95
 
96
+ # สร้างภาพองค์ประกอบ K-Space แบบกราฟเสนตักัน (พื้ดำ)
97
  def draw_kspace_diagram():
98
+ fig, ax = plt.subplots(figsize=(5, 5))
99
+ ax.set_facecolor('black')
100
 
101
+ # แกนส้นตรงสีข
102
+ ax.axhline(0, color='white', lw=2)
103
+ ax.axvline(0, color='white', lw=2)
104
 
105
+ # วาดคลืนจำลอ
106
+ x = np.linspace(-1, 1, 100)
107
+ y = np.linspace(-1, 1, 100)
 
 
 
108
 
109
+ # คลื่แดง (kx)
110
+ y_red = 0.2 * np.sin(10 * x)
111
+ ax.plot(x, y_red, color='red', alpha=0.8, lw=2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
+ # คลื่นน้ำเงิน (ky)
114
+ x_blue = 0.2 * np.sin(10 * y)
115
+ ax.plot(x_blue, y, color='blue', alpha=0.8, lw=2)
 
 
 
 
 
 
116
 
117
+ # ใสข้อควมบอกแกน
118
+ ax.text(0.95, 0.05, 'kx\n(Frequency)', transform=ax.transAxes, ha='right', va='bottom', fontsize=14, fontweight='bold', color='red')
119
+ ax.text(0.05, 0.95, 'ky\n(Phase)', transform=ax.transAxes, ha='left', va='top', fontsize=14, fontweight='bold', color='#4B8BDE')
120
+
121
+ ax.set_xlim(-1, 1)
122
+ ax.set_ylim(-1, 1)
 
123
  ax.axis('off')
124
+ fig.patch.set_facecolor('black')
125
  return get_image_from_plot(fig)
126
 
127
  def draw_kspace_point(kx, ky, bg_image):
128
  fig, ax = plt.subplots(figsize=(4, 4))
129
+ # vmin=0, vmax=255 เพือรักษาควาสว่าง
130
  ax.imshow(bg_image, cmap='gray', extent=[-112, 112, -112, 112], vmin=0, vmax=255)
131
  ax.plot(kx, ky, 'ro', markersize=6)
132
  ax.annotate('', xy=(kx, ky), xytext=(0, 0), arrowprops=dict(arrowstyle='->', color='yellow', lw=2))
 
163
 
164
  def draw_filtered_kspace(filtered_k):
165
  fig, ax = plt.subplots(figsize=(4, 4))
166
+ # ปรับภาพ Filter ให้สว่างและอัปเดตตามแบบ Real-time
167
  ax.imshow(format_kspace_display(filtered_k), cmap='gray', vmin=0, vmax=255)
168
  ax.axis('off')
169
  return get_image_from_plot(fig)
 
171
  def draw_mri(mri_result):
172
  fig, ax = plt.subplots(figsize=(4, 4))
173
  m_disp = mri_result / (np.max(mri_result) + 1e-8)
174
+ ax.imshow(np.flipud(m_disp), cmap='gray') # แก้ภาพกลับหัว
175
  ax.axis('off')
176
  return get_image_from_plot(fig)
177
 
 
223
  plt.tight_layout()
224
  return get_image_from_plot(fig)
225
 
 
226
  def draw_kspace_filling(current_step, total_steps):
227
  fig, ax = plt.subplots(figsize=(5, 6))
228
 
 
272
  ข้อมูลใน k-space มักจะถูกนำมาแสดงผลในรูปแบบตารางสี่เหลี่ยม (Grid) โดยมีแกนหลักคือ **kx (แนวนอน - Frequency)** และ **ky (แนวตั้ง - Phase)** จุดสำคัญคือ **แกน kx และ ky เหล่านี้ ไม่ได้บอกตำแหน่งพิกัดในภาพอวัยวะ** แต่มันคือแกนที่บอกถึงลักษณะของ **"ความถี่เชิงพื้นที่"** ที่เป็นคลื่น (Sinusoidal wave) ด้วยเหตุนี้ **จุดแต่ละจุดบน K-space จึงไม่ได้จับคู่แบบ 1 ต่อ 1 กับพิกเซลบนภาพ MRI** (เช่น จุดมุมซ้ายบนของ K-space ไม่ได้สร้างภาพมุมซ้ายบนของอวัยวะ)
273
  """)
274
 
275
+ _, col_img_center, _ = st.columns([2.5, 3, 2.5])
276
  with col_img_center:
277
+ # ใช้กราฟเสแทนการใช้รูปภาพ
278
  st.image(draw_kspace_diagram(), use_container_width=True)
 
 
 
 
 
 
279
 
280
  # ---------------------------------------------------------
281
+ # K-Space Trajectories
282
  # ---------------------------------------------------------
283
  st.markdown("## 🛤️ K-Space Trajectories")
284
  st.markdown("""
 
369
  with col_img2:
370
  st.image(draw_wave(kx_val, ky_val), caption="แผ่นลวดลายคลื่น (2D Sinusoidal Wave)", use_container_width=True)
371
 
 
372
  with st.expander("🔍 สังเกตลักษณะคลื่น (คลิกเพื่อดูคำอธิบายเพิ่มเติม)"):
373
  st.markdown("""
374
  **ลองปรับเลื่อนพิกัดเพื่อสังเกตความเปลี่ยนแปลง:**