Update app.py
Browse files
app.py
CHANGED
|
@@ -72,17 +72,21 @@ def load_kspace_data():
|
|
| 72 |
|
| 73 |
kspace_raw = load_kspace_data()
|
| 74 |
|
| 75 |
-
# ปรับแก้ความสว่าง
|
| 76 |
def format_kspace_display(k_data):
|
| 77 |
k_mag = np.abs(k_data)
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
return np.zeros_like(k_mag, dtype=np.uint8)
|
| 81 |
|
| 82 |
-
#
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
|
| 87 |
kspace_bg_image = format_kspace_display(kspace_raw)
|
| 88 |
|
|
@@ -93,41 +97,45 @@ def get_image_from_plot(fig):
|
|
| 93 |
buf.seek(0)
|
| 94 |
return Image.open(buf)
|
| 95 |
|
| 96 |
-
# สร้างภาพองค์ประกอบ K-Space
|
| 97 |
def draw_kspace_diagram():
|
| 98 |
-
fig, ax = plt.subplots(figsize=(
|
| 99 |
-
ax.set_facecolor('black')
|
| 100 |
|
| 101 |
-
#
|
| 102 |
-
|
| 103 |
-
|
|
|
|
| 104 |
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
|
| 109 |
-
# คลื่น
|
| 110 |
-
|
| 111 |
-
ax.plot(x, y_red, color='red', alpha=0.8, lw=2)
|
| 112 |
|
| 113 |
-
# คลื่น
|
| 114 |
-
|
| 115 |
-
ax.
|
| 116 |
|
| 117 |
-
#
|
| 118 |
-
ax.
|
| 119 |
-
ax.text(0
|
| 120 |
|
| 121 |
-
|
| 122 |
-
ax.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
ax.axis('off')
|
| 124 |
-
|
|
|
|
| 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 |
-
#
|
| 130 |
-
ax.imshow(bg_image, cmap='gray', extent=[-112, 112, -112, 112], vmin=0, vmax=
|
| 131 |
ax.plot(kx, ky, 'ro', markersize=6)
|
| 132 |
ax.annotate('', xy=(kx, ky), xytext=(0, 0), arrowprops=dict(arrowstyle='->', color='yellow', lw=2))
|
| 133 |
ax.axhline(0, color='white', linewidth=0.5, linestyle='--')
|
|
@@ -163,15 +171,15 @@ def apply_filter(k_data, mode, radius):
|
|
| 163 |
|
| 164 |
def draw_filtered_kspace(filtered_k):
|
| 165 |
fig, ax = plt.subplots(figsize=(4, 4))
|
| 166 |
-
#
|
| 167 |
-
ax.imshow(format_kspace_display(filtered_k), cmap='gray', vmin=0, vmax=
|
| 168 |
ax.axis('off')
|
| 169 |
return get_image_from_plot(fig)
|
| 170 |
|
| 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 |
|
|
@@ -272,9 +280,8 @@ with col_main:
|
|
| 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([
|
| 276 |
with col_img_center:
|
| 277 |
-
# ใช้กราฟเส้นแทนการใช้รูปภาพ
|
| 278 |
st.image(draw_kspace_diagram(), use_container_width=True)
|
| 279 |
|
| 280 |
# ---------------------------------------------------------
|
|
|
|
| 72 |
|
| 73 |
kspace_raw = load_kspace_data()
|
| 74 |
|
| 75 |
+
# ปรับแก้ความสว่างภาพ K-Space ใหม่ (ใช้ Gamma Correction เพื่อให้เห็นวงกลมชัดแบบออริจินอล)
|
| 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.float32)
|
|
|
|
| 80 |
|
| 81 |
+
# 1. Log Transform ดึงสเกล
|
| 82 |
+
log_k = np.log(1 + k_mag)
|
| 83 |
+
# 2. Normalize ให้อยู่ในช่วง 0-1
|
| 84 |
+
log_norm = (log_k - np.min(log_k)) / (np.max(log_k) - np.min(log_k))
|
| 85 |
+
# 3. Gamma Correction (0.3) งัดส่วนที่มืดให้สว่างพุ่งขึ้นมา
|
| 86 |
+
gamma = 0.3
|
| 87 |
+
log_boosted = np.power(log_norm, gamma)
|
| 88 |
+
|
| 89 |
+
return log_boosted
|
| 90 |
|
| 91 |
kspace_bg_image = format_kspace_display(kspace_raw)
|
| 92 |
|
|
|
|
| 97 |
buf.seek(0)
|
| 98 |
return Image.open(buf)
|
| 99 |
|
| 100 |
+
# สร้างภาพ องค์ประกอบ K-Space (วาดกล่องมีลายคลื่น 2D และลูกศรแกนด้านนอก)
|
| 101 |
def draw_kspace_diagram():
|
| 102 |
+
fig, ax = plt.subplots(figsize=(6, 6))
|
|
|
|
| 103 |
|
| 104 |
+
# วาดรูปคลื่น 2D ในกรอบ
|
| 105 |
+
x = np.linspace(-112, 112, 224)
|
| 106 |
+
y = np.linspace(112, -112, 224)
|
| 107 |
+
X, Y = np.meshgrid(x, y)
|
| 108 |
|
| 109 |
+
freq_x = 10 / 224.0
|
| 110 |
+
freq_y = 10 / 224.0
|
| 111 |
+
wave = np.cos(2 * np.pi * (freq_x * X + freq_y * Y))
|
| 112 |
|
| 113 |
+
# แสดงรูปคลื่นในกรอบ
|
| 114 |
+
ax.imshow(wave, cmap='gray', extent=[-1, 1, -1, 1])
|
|
|
|
| 115 |
|
| 116 |
+
# ตีกรอบสี่เหลี่ยมรอบรูปคลื่น
|
| 117 |
+
rect = plt.Rectangle((-1, -1), 2, 2, fill=False, edgecolor='black', lw=2)
|
| 118 |
+
ax.add_patch(rect)
|
| 119 |
|
| 120 |
+
# วาดแกน Kx (แนวนอน) ข้างล่าง
|
| 121 |
+
ax.annotate('', xy=(1, -1.2), xytext=(-1, -1.2), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=3))
|
| 122 |
+
ax.text(0, -1.3, 'kx (Frequency)', ha='center', va='top', fontsize=18, fontweight='bold')
|
| 123 |
|
| 124 |
+
# วาดแกน Ky (แนวตั้ง) ข้างซ้าย
|
| 125 |
+
ax.annotate('', xy=(-1.2, 1), xytext=(-1.2, -1), arrowprops=dict(arrowstyle='<|-|>', color='black', lw=3))
|
| 126 |
+
ax.text(-1.3, 0, 'ky (Phase)', ha='right', va='center', rotation=90, fontsize=18, fontweight='bold')
|
| 127 |
+
|
| 128 |
+
ax.set_xlim(-1.5, 1.2)
|
| 129 |
+
ax.set_ylim(-1.5, 1.2)
|
| 130 |
ax.axis('off')
|
| 131 |
+
|
| 132 |
+
plt.tight_layout()
|
| 133 |
return get_image_from_plot(fig)
|
| 134 |
|
| 135 |
def draw_kspace_point(kx, ky, bg_image):
|
| 136 |
fig, ax = plt.subplots(figsize=(4, 4))
|
| 137 |
+
# แสดงภาพ K-space สว่างจ้า
|
| 138 |
+
ax.imshow(bg_image, cmap='gray', extent=[-112, 112, -112, 112], vmin=0, vmax=1)
|
| 139 |
ax.plot(kx, ky, 'ro', markersize=6)
|
| 140 |
ax.annotate('', xy=(kx, ky), xytext=(0, 0), arrowprops=dict(arrowstyle='->', color='yellow', lw=2))
|
| 141 |
ax.axhline(0, color='white', linewidth=0.5, linestyle='--')
|
|
|
|
| 171 |
|
| 172 |
def draw_filtered_kspace(filtered_k):
|
| 173 |
fig, ax = plt.subplots(figsize=(4, 4))
|
| 174 |
+
# ภาพ Filtered ก็จะสว่าง เห็นวงกลม Filter สีดำชัดเจน
|
| 175 |
+
ax.imshow(format_kspace_display(filtered_k), cmap='gray', vmin=0, vmax=1)
|
| 176 |
ax.axis('off')
|
| 177 |
return get_image_from_plot(fig)
|
| 178 |
|
| 179 |
def draw_mri(mri_result):
|
| 180 |
fig, ax = plt.subplots(figsize=(4, 4))
|
| 181 |
m_disp = mri_result / (np.max(mri_result) + 1e-8)
|
| 182 |
+
ax.imshow(np.flipud(m_disp), cmap='gray')
|
| 183 |
ax.axis('off')
|
| 184 |
return get_image_from_plot(fig)
|
| 185 |
|
|
|
|
| 280 |
ข้อมูลใน k-space มักจะถูกนำมาแสดงผลในรูปแบบตารางสี่เหลี่ยม (Grid) โดยมีแกนหลักคือ **kx (แนวนอน - Frequency)** และ **ky (แนวตั้ง - Phase)** จุดสำคัญคือ **แกน kx และ ky เหล่านี้ ไม่ได้บอกตำแหน่งพิกัดในภาพอวัยวะ** แต่มันคือแกนที่บอกถึงลักษณะของ **"ความถี่เชิงพื้นที่"** ที่เป็นคลื่น (Sinusoidal wave) ด้วยเหตุนี้ **จุดแต่ละจุดบน K-space จึงไม่ได้จับคู่แบบ 1 ต่อ 1 กับพิกเซลบนภาพ MRI** (เช่น จุดมุมซ้ายบนของ K-space ไม่ได้สร้างภาพมุมซ้ายบนของอวัยวะ)
|
| 281 |
""")
|
| 282 |
|
| 283 |
+
_, col_img_center, _ = st.columns([1.5, 4, 1.5])
|
| 284 |
with col_img_center:
|
|
|
|
| 285 |
st.image(draw_kspace_diagram(), use_container_width=True)
|
| 286 |
|
| 287 |
# ---------------------------------------------------------
|