在 Jupyter Notebook 畫超焦距的示意圖

春麗 S.T.E.M.
9 min readAug 16, 2024

--

目錄

⦿ Jupyter Notebook
⦿ 使用 matplotlib 畫圖
⦿ 畫一個超焦距的示意圖
⦿ 畫一個透鏡成像的示意圖

Jupyter Notebook

之前的文章中,我們知道要執行一段 Python 檔案可能有點麻煩,需在 Terminal 中鍵入 python3 file.py 來去執行(當時使用 Beautifulsoup 去爬可口可樂的股價資訊),但這讓我們不能隨時修改並執行,於是介紹了 Jupyter Notebook,這讓我們可以一邊修改,一邊重新執行。

後來的例子是使用 selenium 去寫一個自動登入預約場地的程式,因為有多個步驟需要一邊測試一邊執行,所以使用 Jupyter Notebook 來操作,於是就知道 Jupyter Notebook 有多方便了。

繼續閱讀|回目錄

使用 matplotlib 畫圖

當我問對話機器人「能夠畫圖表示超焦距的概念嗎」,得到的答案如下:

import matplotlib.pyplot as plt
import numpy as np

# Set up the figure and axis
fig, ax = plt.subplots(figsize=(8, 3))
ax.set_xlim(0, 10)
ax.set_ylim(0, 1)
ax.axis('off')

# Define distances and labels
hyper_focal = 4 # Hyperfocal distance
focus_distance = 2 # Distance where sharpness begins

# Camera and hyperfocal line
ax.plot([0, 10], [0.5, 0.5], 'k--', label='Ground level')
camera_icon = plt.Line2D((0.2, 0.2), (0.45, 0.55), color="blue", marker='o', markersize=10)
ax.add_line(camera_icon)
ax.text(0.1, 0.6, 'Camera', fontsize=10, ha='center')

# Draw hyperfocal distance
ax.plot([hyper_focal, hyper_focal], [0.45, 0.55], 'r-')
ax.text(hyper_focal, 0.6, 'Hyperfocal Distance', color='red', fontsize=10, ha='center')

# Draw focus range
ax.plot([focus_distance, 10], [0.4, 0.4], 'g-', linewidth=8, alpha=0.6)
ax.text(focus_distance / 2, 0.3, 'Acceptable sharpness\nstarts here', fontsize=9, ha='center', color='green')

# Annotations for clarity
ax.text(hyper_focal / 2, 0.7, 'Blurry', fontsize=10, ha='center', style='italic')
ax.text((hyper_focal + 10) / 2, 0.7, 'Acceptable Sharpness', fontsize=10, ha='center', style='italic')
ax.text(10, 0.7, '∞', fontsize=12, ha='center')

# Display the plot
plt.show()

並且下方就有 plot 的展示。

而看了看答案的程式碼是使用 python,這表示我可以在 Jupyter Notebook 中加入此段程式碼來畫圖。

但貼上 Notebook 中執行後卻得到下面的錯誤。

---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[1], line 1
----> 1 import matplotlib.pyplot as plt
2 import numpy as np
4 # Set up the figure and axis

ModuleNotFoundError: No module named 'matplotlib'

這是因為缺少 matplotlib 這個模組,matplotlib 是 python 中一個很流行的繪圖庫,仿 MatLab 的繪圖功能。

於是我們在 Notebook 中安裝 matplotlib,在 Notebook 中鍵入 !pip install matplotlib 並執行,如此便會下載及安裝這個庫了。

繼續閱讀|回目錄

畫一個超焦距的示意圖

所以將上面那段程式碼貼上執行,同樣會得到如下:

這張圖表示,當我攝影機對焦在超焦距的位置(Hyperfocal Distance),可以得到最大的景深,綠色那一段就是我們能夠接受的銳利度(Acceptable sharpness),而當對焦在超焦距的位置,前段景深剛好就是超焦距的一半,以十等分來說,前段 4,後段 6,而景深範圍就變成 2 + 6 = 8,用這個圖來表示對焦在超焦距上,能夠獲得最大的景深

繼續閱讀|回目錄

畫一個透鏡成像的示意圖

欲解釋透鏡成像,對話機器人給出的程式碼如如下:

import matplotlib.pyplot as plt
import numpy as np

def draw_lens(f=1.0, height=2.0):
""" Draw a simple thin lens diagram with focal points. """
# Draw lens
plt.plot([0, 0], [-height/2, height/2], color='blue') # Lens
# Draw focal points
plt.scatter([-f, f], [0, 0], color='red', marker='x') # Focal points
plt.text(f, -0.2, 'F', ha='center', va='top', color='red')
plt.text(-f, -0.2, 'F', ha='center', va='top', color='red')

def draw_rays_and_object(f=1.0, object_height=1.0, object_distance=-2.0):
""" Draw object, image and rays through a lens. """
# Calculate image distance using lens formula (1/f = 1/do + 1/di)
image_distance = 1 / (1/f - 1/object_distance)
image_height = -object_height * image_distance / object_distance

# Draw object
plt.plot([object_distance]*2, [0, object_height], 'k-')
plt.text(object_distance, object_height, 'Object', ha='right')

# Draw image
plt.plot([image_distance]*2, [0, image_height], 'k--')
plt.text(image_distance, image_height, 'Image', ha='left')

# Draw rays
plt.plot([object_distance, 0], [object_height, 0], 'green') # Object to lens center
plt.plot([0, image_distance], [0, image_height], 'green') # Lens center to image
plt.plot([object_distance, 0], [object_height, object_height], 'green') # Object top parallel to principal axis
plt.plot([0, image_distance], [object_height, 0], 'green') # Refracted through focal point

# Set up the plot
plt.figure(figsize=(8, 4))
plt.axis('equal')
plt.grid(True)
plt.axhline(0, color='black', lw=0.5) # Principal axis

# Draw the lens system
focal_length = 1.5
object_distance = -3
object_height = 1
draw_lens(f=focal_length)
draw_rays_and_object(f=focal_length, object_height=object_height, object_distance=object_distance)

# Adjust plot
plt.xlim(-5, 5)
plt.ylim(-2, 2)
plt.title('Lens Imaging')
plt.show()

最終得到的結果如下:

雖然畫得頭頭是道,但其實是不對的,如果物體是在一倍到兩倍焦距內,會呈現的是縮小倒立實像,如果是在兩倍焦距上,會呈現的是等大倒立實像,而且這個作圖方式錯誤,通過鏡心的光是不偏折的,且平行光入射,會通過鏡後焦點,不過好玩嘛,有畫出圖倒是無所謂。

最後只好幫它手動修正一下,真正的 Image 是長這樣。

下次再來詳細研究 plot。

這次就分享到這,感謝您的閱讀。

繼續閱讀|回目錄

--

--

春麗 S.T.E.M.
春麗 S.T.E.M.

Written by 春麗 S.T.E.M.

Do not go gentle into that good night, Old age should burn and rave at close of day; Rage, rage, against the dying of the light.

No responses yet