Nicha1234 commited on
Commit
41728e0
·
verified ·
1 Parent(s): 4f27e81

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -26
app.py CHANGED
@@ -14,11 +14,14 @@ st.set_page_config(layout="wide", page_title="K-Space to MRI")
14
 
15
  st.markdown("""
16
  <style>
17
- /* CSS แก้ปัญหาการสั่นของหน้าจอ (ังคัให้มี Scrollbar ตลอดวลา หน้าเวบจะไ้ไม่หดย) */
18
- html, body {
19
- overflow-y: scroll !important;
 
 
 
 
20
  }
21
- .stApp { transition: none !important; }
22
 
23
  html, body, [class*="st-"] {
24
  font-size: 18px;
@@ -87,7 +90,6 @@ def format_kspace_display(k_data):
87
  c = 255.0 / np.log(1 + max_val)
88
  log_img = c * np.log(1 + k_mag)
89
 
90
- # เสริม Gamma correction ดึงความสว่างให้เห็นมิติรอยตัดชัดเจน
91
  log_norm = (log_img - np.min(log_img)) / (np.max(log_img) - np.min(log_img) + 1e-8)
92
  log_boosted = np.power(log_norm, 0.3)
93
  return log_boosted
@@ -96,7 +98,7 @@ kspace_bg_image = format_kspace_display(kspace_raw)
96
 
97
  def get_image_from_plot(fig):
98
  buf = io.BytesIO()
99
- # ลบ bbox_inches='tight' ออกพื่อไม่ให้รูปภาพเปลี่ขนาดพิกเซลไปม(แกสั่น)
100
  plt.savefig(buf, format='png', dpi=100)
101
  plt.close(fig)
102
  buf.seek(0)
@@ -109,32 +111,32 @@ def draw_kspace_diagram():
109
  rect = plt.Rectangle((-1, -1), 2, 2, fill=False, edgecolor='black', lw=3)
110
  ax.add_patch(rect)
111
 
112
- # วาดแกนลูกศรตัดกันตรงกลาง
113
  ax.annotate('', xy=(0.95, 0), xytext=(-0.95, 0), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=2))
114
  ax.annotate('', xy=(0, 0.95), xytext=(0, -0.95), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=2))
115
 
116
  # ตัวอักษรบอกทิศทาง +kx, -kx, +ky, -ky
117
  ax.text(1.1, 0, '+kx', fontsize=20, fontweight='bold', va='center')
118
- # ขยับ -kx ให้อยู่ตรงกลางระหว่างกรอบและเส้นลูกศร Phase axis
119
- ax.text(-1.15, 0, '-kx', fontsize=20, fontweight='bold', va='center', ha='center')
 
 
120
  ax.text(0, 1.1, '+ky', fontsize=20, fontweight='bold', ha='center')
121
  ax.text(0, -1.1, '-ky', fontsize=20, fontweight='bold', ha='center', va='top')
122
 
123
- # Label บอกชื่อแกน (เอาไว้ข้างนอกกรอบแบบในรูป)
124
- # Frequency axis ด้านล่าง (ขยับเส้นให้ต่ำลง)
125
  ax.annotate('', xy=(1, -1.4), xytext=(-1, -1.4), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=4))
126
  ax.text(0, -1.5, 'kx (Frequency)', ha='center', va='top', fontsize=16, fontweight='bold')
127
 
128
- # Phase axis ด้านซ้าย (ขยับเส้นหนีออกไปทางซ้ายมากขึ้น เพื่อไม่ให้ทับ -kx)
129
  ax.annotate('', xy=(-1.5, 1), xytext=(-1.5, -1), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=4))
130
  ax.text(-1.6, 0, 'ky (Phase)', ha='right', va='center', rotation=90, fontsize=16, fontweight='bold')
131
 
132
- # ขยายขอบเขตการแสดงผลให้ครอบคลุม Label ที่ขยับออกไป
133
- ax.set_xlim(-2.0, 1.4)
134
- ax.set_ylim(-1.8, 1.4)
135
  ax.axis('off')
136
 
137
- plt.tight_layout()
 
138
  return get_image_from_plot(fig)
139
 
140
  def draw_kspace_point(kx, ky, bg_image):
@@ -147,6 +149,7 @@ def draw_kspace_point(kx, ky, bg_image):
147
  ax.set_xlim(-112, 112)
148
  ax.set_ylim(-112, 112)
149
  ax.axis('off')
 
150
  return get_image_from_plot(fig)
151
 
152
  def draw_wave(kx, ky):
@@ -159,6 +162,7 @@ def draw_wave(kx, ky):
159
  wave = np.cos(2 * np.pi * (freq_x * X + freq_y * Y))
160
  ax.imshow(wave, cmap='gray', extent=[-112, 112, -112, 112])
161
  ax.axis('off')
 
162
  return get_image_from_plot(fig)
163
 
164
  def apply_filter(k_data, mode, radius):
@@ -177,19 +181,19 @@ def draw_filtered_kspace(filtered_k):
177
  fig, ax = plt.subplots(figsize=(4, 4))
178
  ax.imshow(format_kspace_display(filtered_k), cmap='gray', vmin=0, vmax=1)
179
  ax.axis('off')
 
180
  return get_image_from_plot(fig)
181
 
182
- # ฟังก์ชัน MRI แก้ให้ภาพสว่างใส โดยตัด Noise พิกเซลทิ้ง
183
  def draw_mri(mri_result):
184
  fig, ax = plt.subplots(figsize=(4, 4))
185
  if np.max(mri_result) > 0:
186
- # ตัดพิกเซลที่สว่างหรือมืดเกินไป (Noise) ออกไป 1% เพื่อให้เนื้อสมองสว่างชัดเจน
187
- vmin, vmax = np.percentile(mri_result, (1, 99))
188
  else:
189
  vmin, vmax = 0, 1
190
 
191
  ax.imshow(np.flipud(mri_result), cmap='gray', vmin=vmin, vmax=vmax)
192
  ax.axis('off')
 
193
  return get_image_from_plot(fig)
194
 
195
  def draw_pulse_sequence(current_step, total_steps):
@@ -237,7 +241,8 @@ def draw_pulse_sequence(current_step, total_steps):
237
  ax.text(0, 0.5, 'Signal\n(Echo)', fontsize=14, fontweight='bold', va='center', ha='right', transform=ax.get_yaxis_transform())
238
  ax.axis('off')
239
 
240
- plt.tight_layout()
 
241
  return get_image_from_plot(fig)
242
 
243
  def draw_kspace_filling(current_step, total_steps):
@@ -266,6 +271,8 @@ def draw_kspace_filling(current_step, total_steps):
266
  fig.patch.set_facecolor('black')
267
 
268
  ax.axis('off')
 
 
269
  return get_image_from_plot(fig)
270
 
271
  # ==========================================================
@@ -336,15 +343,12 @@ with col_main:
336
 
337
  st.progress((st.session_state.fill_step + 1) / total_anim_steps)
338
 
 
339
  col_anim1, col_anim2 = st.columns([1, 1])
340
  with col_anim1:
341
- img1_ph = st.empty()
342
- # นำ use_container_width=True ออกเพื่อล็อกขนาดภาพไม่ให้สั่น
343
- img1_ph.image(draw_pulse_sequence(st.session_state.fill_step, total_anim_steps))
344
  with col_anim2:
345
- img2_ph = st.empty()
346
- # นำ use_container_width=True ออกเพื่อล็อกขนาดภาพไม่ให้สั่น
347
- img2_ph.image(draw_kspace_filling(st.session_state.fill_step, total_anim_steps))
348
 
349
  st.markdown("""
350
  ---
 
14
 
15
  st.markdown("""
16
  <style>
17
+ /* CSS แก้ปัญหาการสั่นของหน้าจอบบเ็ดขา */
18
+ .stApp {
19
+ overflow-y: scroll !important;
20
+ transition: none !important;
21
+ }
22
+ .main .block-container {
23
+ min-height: 101vh !important;
24
  }
 
25
 
26
  html, body, [class*="st-"] {
27
  font-size: 18px;
 
90
  c = 255.0 / np.log(1 + max_val)
91
  log_img = c * np.log(1 + k_mag)
92
 
 
93
  log_norm = (log_img - np.min(log_img)) / (np.max(log_img) - np.min(log_img) + 1e-8)
94
  log_boosted = np.power(log_norm, 0.3)
95
  return log_boosted
 
98
 
99
  def get_image_from_plot(fig):
100
  buf = io.BytesIO()
101
+ # เซฟภาพด้วยขนาดพิกเซลยตัว ้ามใช้ bbox_inches='tight' เด็ดขดเพื่อป้องกันเว็บสั่น
102
  plt.savefig(buf, format='png', dpi=100)
103
  plt.close(fig)
104
  buf.seek(0)
 
111
  rect = plt.Rectangle((-1, -1), 2, 2, fill=False, edgecolor='black', lw=3)
112
  ax.add_patch(rect)
113
 
114
+ # วาดแกนลูกศรตัดกันตรงกลาง (อยู่ภายในกรอบ)
115
  ax.annotate('', xy=(0.95, 0), xytext=(-0.95, 0), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=2))
116
  ax.annotate('', xy=(0, 0.95), xytext=(0, -0.95), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=2))
117
 
118
  # ตัวอักษรบอกทิศทาง +kx, -kx, +ky, -ky
119
  ax.text(1.1, 0, '+kx', fontsize=20, fontweight='bold', va='center')
120
+
121
+ # ขยับ -kx ออกไปทางซ้ายให้มีช่องว่าง (ha='right' ทำให้ขอบขวาของตัวหนังสืออยู่ที่พิกัด -1.1 ซึ่งไม่ทับกรอบ)
122
+ ax.text(-1.1, 0, '-kx', fontsize=20, fontweight='bold', va='center', ha='right')
123
+
124
  ax.text(0, 1.1, '+ky', fontsize=20, fontweight='bold', ha='center')
125
  ax.text(0, -1.1, '-ky', fontsize=20, fontweight='bold', ha='center', va='top')
126
 
127
+ # Label บอกชื่อแกน (เอาไว้ข้างนอกกรอบ)
 
128
  ax.annotate('', xy=(1, -1.4), xytext=(-1, -1.4), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=4))
129
  ax.text(0, -1.5, 'kx (Frequency)', ha='center', va='top', fontsize=16, fontweight='bold')
130
 
 
131
  ax.annotate('', xy=(-1.5, 1), xytext=(-1.5, -1), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=4))
132
  ax.text(-1.6, 0, 'ky (Phase)', ha='right', va='center', rotation=90, fontsize=16, fontweight='bold')
133
 
134
+ ax.set_xlim(-2.0, 1.5)
135
+ ax.set_ylim(-1.8, 1.5)
 
136
  ax.axis('off')
137
 
138
+ # ล็อกระยะขอบให้ตายตัวป้องกันการกระตุก
139
+ fig.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)
140
  return get_image_from_plot(fig)
141
 
142
  def draw_kspace_point(kx, ky, bg_image):
 
149
  ax.set_xlim(-112, 112)
150
  ax.set_ylim(-112, 112)
151
  ax.axis('off')
152
+ fig.subplots_adjust(left=0, right=1, top=1, bottom=0)
153
  return get_image_from_plot(fig)
154
 
155
  def draw_wave(kx, ky):
 
162
  wave = np.cos(2 * np.pi * (freq_x * X + freq_y * Y))
163
  ax.imshow(wave, cmap='gray', extent=[-112, 112, -112, 112])
164
  ax.axis('off')
165
+ fig.subplots_adjust(left=0, right=1, top=1, bottom=0)
166
  return get_image_from_plot(fig)
167
 
168
  def apply_filter(k_data, mode, radius):
 
181
  fig, ax = plt.subplots(figsize=(4, 4))
182
  ax.imshow(format_kspace_display(filtered_k), cmap='gray', vmin=0, vmax=1)
183
  ax.axis('off')
184
+ fig.subplots_adjust(left=0, right=1, top=1, bottom=0)
185
  return get_image_from_plot(fig)
186
 
 
187
  def draw_mri(mri_result):
188
  fig, ax = plt.subplots(figsize=(4, 4))
189
  if np.max(mri_result) > 0:
190
+ vmin, vmax = np.percentile(mri_result, (1, 99.5))
 
191
  else:
192
  vmin, vmax = 0, 1
193
 
194
  ax.imshow(np.flipud(mri_result), cmap='gray', vmin=vmin, vmax=vmax)
195
  ax.axis('off')
196
+ fig.subplots_adjust(left=0, right=1, top=1, bottom=0)
197
  return get_image_from_plot(fig)
198
 
199
  def draw_pulse_sequence(current_step, total_steps):
 
241
  ax.text(0, 0.5, 'Signal\n(Echo)', fontsize=14, fontweight='bold', va='center', ha='right', transform=ax.get_yaxis_transform())
242
  ax.axis('off')
243
 
244
+ # ล็อกระยะกรอบตายตัวเพื่อหยุดอาการสั่น
245
+ fig.subplots_adjust(left=0.2, right=0.95, top=0.95, bottom=0.05, hspace=0.2)
246
  return get_image_from_plot(fig)
247
 
248
  def draw_kspace_filling(current_step, total_steps):
 
271
  fig.patch.set_facecolor('black')
272
 
273
  ax.axis('off')
274
+ # ล็อกระยะกรอบตายตัวเพื่อหยุดอาการสั่น
275
+ fig.subplots_adjust(left=0.05, right=0.95, top=0.9, bottom=0.05)
276
  return get_image_from_plot(fig)
277
 
278
  # ==========================================================
 
343
 
344
  st.progress((st.session_state.fill_step + 1) / total_anim_steps)
345
 
346
+ # วางภาพแสดงผลโดยตรง ใช้ use_container_width เพื่อให้รูปขยายเต็มคอลัมน์โดยไม่กระตุก
347
  col_anim1, col_anim2 = st.columns([1, 1])
348
  with col_anim1:
349
+ st.image(draw_pulse_sequence(st.session_state.fill_step, total_anim_steps), use_container_width=True)
 
 
350
  with col_anim2:
351
+ st.image(draw_kspace_filling(st.session_state.fill_step, total_anim_steps), use_container_width=True)
 
 
352
 
353
  st.markdown("""
354
  ---