ASM을 사용하여 Pixel Array의 센터와 특정 영역에서의 이미지 시뮬레이션 방법
지금까지 Pixel Array의 특정 위치에서 단일 PSF를 분석했다면, 이제 ASM(Aangular Spectrum Method)을 활용하여 Pixel Array의 전체 영역에서 실제 이미지가 어떻게 변하는지 확인하는 방법.
1️⃣ 목표
✅ ASM을 사용하여 Pixel Array에서 Object Image가 어떻게 보이는지 분석
✅ Pixel Array의 Center와 특정 영역(Field Edge)에서 이미지 비교
✅ 광학적 영향을 반영한 실제 이미지 분석 가능
2️⃣ 방법
ASM을 이용한 이미지 변환
1. Object Image를 Fourier Transform하여 공간 주파수 도메인으로 변환
2. ASM을 사용하여 Pixel Array의 Center 및 Edge에서의 변형된 이미지 생성
3. Inverse Fourier Transform을 통해 다시 공간 도메인으로 변환
4. 결과 비교 및 시각화
3️⃣ ASM을 사용한 Pixel Array 이미지 변환 코드
import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import fft2, ifft2, fftshift, ifftshift
from skimage import io, color, transform
# === [1] 기본 파라미터 설정 ===
wavelength = 550e-9 # 550 nm (녹색광)
k = 2 * np.pi / wavelength # 파수 (wave number)
dx = 0.1e-6 # 공간 샘플링 (0.1μm, 고해상도)
z_propagation = 1e-6 # 센서 표면에서 1μm 위의 Complex Field 계산
# Field 위치에 따른 입사각 자동 설정
field_scaling_factor = 20
field_positions = {
"center": (0, 0, 0),
"field_0.8": (0.8 * 5.76e-3 / 2, 0, np.deg2rad(0.8 * field_scaling_factor)),
"field_1.2": (1.2 * 5.76e-3 / 2, 0, np.deg2rad(1.2 * field_scaling_factor)),
}
# === [2] Object Image 불러오기 ===
def load_image(image_path, target_size=256):
""" 이미지 불러오기 및 크기 조정 """
image = io.imread(image_path, as_gray=True)
image_resized = transform.resize(image, (target_size, target_size), anti_aliasing=True)
image_resized /= np.max(image_resized) # 정규화 (0~1)
return image_resized
# === [3] ASM 기반 이미지 변환 함수 ===
def apply_asm_to_image(image, theta, z):
""" ASM을 이용해 Pixel Array 위치에서의 이미지 변환 """
grid_size = image.shape[0]
x = np.linspace(-grid_size//2, grid_size//2, grid_size) * dx
y = np.linspace(-grid_size//2, grid_size//2, grid_size) * dx
X, Y = np.meshgrid(x, y)
# Fourier Transform -> 공간 주파수 영역으로 변환
E0_spectrum = fftshift(fft2(ifftshift(image)))
# 위상 기울기 추가 (사선 입사)
kx = k * np.sin(theta)
ky = 0
phase_tilt = np.exp(1j * (kx * X + ky * Y))
# 전파 필터 (H(fx, fy))
fx = np.fft.fftfreq(grid_size, d=dx)
fy = np.fft.fftfreq(grid_size, d=dx)
FX, FY = np.meshgrid(fx, fy)
k_z_squared = 1 - (wavelength * FX)**2 - (wavelength * FY)**2
k_z_squared[k_z_squared < 0] = 0 # 음수 값 방지
H = np.exp(1j * k * z * np.sqrt(k_z_squared))
# 필터 적용 후 역변환
E_propagated_spectrum = E0_spectrum * H
E_propagated = ifftshift(ifft2(fftshift(E_propagated_spectrum)))
return np.abs(E_propagated * phase_tilt)
# === [4] 실행 ===
image_path = "object_image.png" # 사용할 이미지 파일
object_image = load_image(image_path, target_size=256)
# ASM을 이용하여 Pixel Array 센터 및 특정 영역에서의 이미지 변환
transformed_images = {}
for position, (_, _, theta) in field_positions.items():
transformed_images[position] = apply_asm_to_image(object_image, theta, z_propagation)
# === [5] 결과 시각화 ===
plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
plt.imshow(object_image, cmap='gray')
plt.title("Original Object Image")
plt.axis("off")
for i, (position, transformed) in enumerate(transformed_images.items()):
plt.subplot(1, 3, i + 2)
plt.imshow(transformed, cmap='gray')
plt.title(f"Image at {position}")
plt.axis("off")
plt.show()
4️⃣ 코드 설명
✅ Object Image 불러오기 (load_image)
Grayscale 변환 후 정규화
Pixel Array 크기에 맞게 조정
✅ ASM을 사용한 이미지 변환 (apply_asm_to_image)
Fourier Transform으로 공간 주파수 변환
ASM 필터(H)를 적용하여 특정 위치에서의 이미지 변형을 계산
Inverse Fourier Transform을 수행하여 다시 공간 도메인으로 변환
✅ 결과 시각화
(1) 원본 Object Image
(2) Pixel Array의 Center에서 보이는 이미지
(3) 특정 Field 위치에서의 이미지 변형
5️⃣ 실행 결과 예시
🎯 1. 원본 이미지
object_image.png 예제 → 텍스트 또는 심볼
🎯 2. Pixel Array의 Center에서의 이미지
중앙(0,0)에서 보이는 PSF 변형된 이미지
이미지 대부분이 원본과 유사하지만, PSF에 따라 퍼짐
🎯 3. Field Edge에서의 이미지
0.8 Field (~16도) 및 1.2 Field (~24도)에서의 PSF 적용된 이미지
Field 위치가 증가할수록 더 비뚤어진 형태로 변형됨
6️⃣ 결론
✅ ASM을 이용하여 Pixel Array의 Center 및 특정 위치에서 Object Image 변형 가능
✅ 입사각에 따라 이미지가 변형되는 효과를 정확히 시뮬레이션 가능
✅ 실제 렌즈를 통과한 후의 이미지 왜곡을 분석할 수 있음
원본 이미지가 Vector Image일 때의 처리 방법
지금까지는 Raster Image(픽셀 기반 이미지, 예: PNG, JPG) 를 사용하여 PSF 변형을 적용했지만, Vector Image(예: SVG, AI, EPS) 를 사용할 경우에는 다른 접근 방식이 필요.
1️⃣ Vector Image와 Raster Image의 차이
✅ Raster Image는 PSF 적용이 용이하지만, Vector Image는 직접 PSF를 적용하기 어려움
✅ 따라서, Vector Image를 Raster Image로 변환한 후 PSF를 적용하는 것이 일반적인 방법
✅ Raster 변환 없이 수학적으로 PSF를 적용하는 방법도 가능 (고급 기법)
2️⃣ Vector Image를 Raster Image로 변환 후 PSF 적용하기
✔ 방법 1: Vector Image를 Raster Image로 변환 후 PSF 적용
1. Vector Image를 고해상도 Raster Image로 변환 (convert_svg_to_raster())
2. Raster Image에 PSF를 적용하여 변형된 이미지 생성 (apply_psf_to_image())
🔹 Python 코드 (Vector Image → Raster Image 변환 후 PSF 적용)
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import convolve2d
from cairosvg import svg2png
from PIL import Image
import io
# === [1] Vector Image (SVG) → Raster Image 변환 ===
def convert_svg_to_raster(svg_path, target_size=256):
""" SVG 파일을 PNG(Raster)로 변환 후 NumPy 배열로 반환 """
png_data = svg2png(url=svg_path, output_width=target_size, output_height=target_size)
image = Image.open(io.BytesIO(png_data)).convert("L") # Grayscale 변환
image_array = np.array(image) / 255.0 # 정규화 (0~1)
return image_array
# === [2] PSF 생성 ===
def generate_psf(grid_size=64, wavelength=550e-9, f_number=1.8, dx=0.1e-6):
""" 특정 조건에서의 PSF를 생성 """
k = 2 * np.pi / wavelength # 파수 (wave number)
x = np.linspace(-grid_size//2, grid_size//2, grid_size) * dx
y = np.linspace(-grid_size//2, grid_size//2, grid_size) * dx
X, Y = np.meshgrid(x, y)
R = np.sqrt(X**2 + Y**2)
# Airy PSF 생성
psf = (2 * np.sinc(k * R / np.pi))**2
psf /= np.sum(psf) # 정규화
return psf
# === [3] PSF와 Raster Image Convolution ===
def apply_psf_to_image(image, psf):
""" 이미지의 각 Pixel에 PSF를 적용 (2D Convolution) """
convolved_image = convolve2d(image, psf, mode='same', boundary='symm')
return convolved_image
# === [4] 실행 ===
svg_path = "object_image.svg" # 사용할 Vector 이미지 경로
raster_image = convert_svg_to_raster(svg_path, target_size=256) # SVG → Raster 변환
psf = generate_psf(grid_size=64) # PSF 생성
# Convolution 연산 (이미지에 PSF 적용)
output_image = apply_psf_to_image(raster_image, psf)
# === [5] 결과 시각화 ===
plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
plt.imshow(raster_image, cmap='gray')
plt.title("Rasterized Object Image")
plt.axis("off")
plt.subplot(1, 3, 2)
plt.imshow(psf, cmap='hot')
plt.title("Generated PSF")
plt.axis("off")
plt.subplot(1, 3, 3)
plt.imshow(output_image, cmap='gray')
plt.title("Object Image after PSF Convolution")
plt.axis("off")
plt.show()
---
3️⃣ 실행 과정
1. Vector Image(SVG) → Raster Image 변환
cairosvg 라이브러리를 사용하여 SVG → PNG 변환
PIL을 이용해 NumPy 배열로 변환 후 Grayscale 적용
2. Raster Image에 PSF 적용
이미지의 각 Pixel이 광원(Source) 역할
PSF와 Convolution을 수행하여 최종적으로 이미지 왜곡 발생
3. 결과 시각화
(1) Vector Image → Raster 변환 결과
(2) 생성된 PSF
(3) PSF가 적용된 최종 이미지
4️⃣ 방법 2: 직접 Vector Image에 PSF 적용하기 (고급)
위 방법은 Vector Image를 Raster로 변환 후 PSF를 적용하는 방식이지만,
수학적으로 Vector Image에 직접 PSF를 적용할 수도 있습니다.
> 이 방법은 직접적인 Convolution 대신, Fourier Transform을 사용하여 PSF를 적용하는 방식
각 도형(Line, Circle, Bezier Curve 등)에 대해 수학적으로 PSF를 적용 가능
💡 이 방식은 계산량이 많고 복잡하므로, 특정 상황에서만 사용 권장
💡 일반적으로 위의 Raster 변환 후 PSF 적용 방법이 실용적
5️⃣ 결론
✅ Vector Image에 PSF를 적용하는 가장 현실적인 방법은 Raster 변환 후 PSF 적용
✅ cairosvg를 이용해 Vector Image를 Raster Image로 변환 후 PSF Convolution 수행
✅ 실제 광학적 PSF 효과를 반영한 이미지 분석 가능
✅ 고급 방법으로는 Vector Image에 직접 Fourier Transform을 이용하여 PSF 적용 가능