在Day 25:監弒器.WebCam的陰謀中,你的室友們想要潛入女生宿舍送宵夜,還拉你下水,但當室友A──眼鏡仔破解門禁系統時,卻觸發了保護機制,結果你、眼鏡仔、毛帽男三人被困在一個女生房間裡。
你們發現房間裡有一個盆栽,上面的樹莓正閃爍著紅色LED亮光,裡面還有一條線連接到DHT22溫溼度感測器。你們發現如果溫度跟濕度達到一定的標準,就會觸發繼電器。你們想盡辦法成功觸發繼電器後,發現這個繼電器連接到風扇的插頭,然後風扇開始緩緩轉動。
你們在風扇後面找到一張紙條,是大漂亮給你們的提示。上面寫著要你們用WebCam攝影機拍照,然後用Python程式把照片轉換成ASCII碼,再用GPIO4接腳控制LED燈,讓它閃爍出ASCII碼。
PIL
、numpy
和 cv2
。ASCII碼
ASCII圖像
,可以在終端機上顯示,也可以儲存成文字檔ASCII圖像
是用不同亮度等級的ASCII字元
來模擬原始影像的外觀 , ,
(o,o)
\_/
-"-"-
PIL
、numpy
和cv2
,可以用pip
指令來安裝。install PIL, numpy and cv2
cv2
模組來開啟WebCam攝影機,並且捕捉一張照片import cv2, PIL and numpy
cap <- VideoCapture(0)
ret, frame <- cap.read()
cap.release()
write frame to "webcam.jpg"
PIL
模組來讀取剛剛儲存的照片,並且調整大小和灰階化。PIL
模組開啟image圖片檔img <- Image.open("webcam.jpg")
width, height <- img.size aspect_ratio <- height / width new_width <- 100 new_height <- aspect_ratio * new_width * 0.55 img <- img.resize(new_width, new_height)
img <- img.convert("L")
numpy
模組來將灰階圖像轉換成ASCII碼
,用來儲存不同亮度等級的字元
ASCII 字元列表
,從最暗到最亮chars <- ["@", "#", "S", "%", "?", "*", "+", ";", ":", ",", "."]
pixels <- numpy.array(img)
ascii_pixels <- numpy.array([chars[pixel / 25] for pixel in pixels.flatten()])
ascii_pixels <- ascii_pixels.reshape(new_height, new_width)
ascii_image <- "\n".join("".join(row) for row in ascii_pixels)
print(ascii_image)
open "ascii_image.txt" as f write ascii_image to f close f
pip install PIL numpy opencv-python
Python
模組就像一個裡面有很多工具的工具箱,可以幫助使用者完成不同的任務。PIL
模組可以協助處理圖片檔案,numpy
模組可以協助處理數字和矩陣,cv2
模組可以協助使用攝影機和影像處理。pip
指令是提供解除安裝套件功能、支援Wheel格式套件。它就像是一個快遞員,可以把工具箱送到使用者的電腦。# 引入cv2模組
import cv2
# 建立一個VideoCapture物件,參數0表示使用第一個攝影機
cap = cv2.VideoCapture(0)
# 讀取一偵影像,ret是布林值,表示是否成功讀取,frame是影像資料
ret, frame = cap.read()
# 釋放VideoCapture物件
cap.release()
# 將frame影像資料儲存成image圖片檔
cv2.imwrite("webcam.jpg", frame)
# 用PIL模組來讀取剛剛儲存的照片,並且調整大小和灰階化
from PIL import Image
ASCII圖像
的照片。cv2
模組,就像是打開工具箱。VideoCapture
物件,就像是拿出攝影機。VideoCapture
物件,就像是關掉攝影機。frame
影像資料儲存成image
圖片檔,就像是把照片洗出來。img = Image.open("webcam.jpg")
# 調整 縮小 圖片大小
width, height = img.size
aspect_ratio = height / width
new_width = 100
new_height = int(aspect_ratio * new_width * 0.55)
img = img.resize((new_width, new_height))
# 圖片灰階化
img = img.convert("L")
PIL
模組中引入Image
類別,就像是拿出畫筆。image
圖片檔,就像是把照片放在畫板上。100像素
,高度根據長寬比和一個係數0.55
來計算,就像是用尺量出適合的尺寸。import numpy as np
# 建立一個`ASCII 字元列表`,從最暗到最亮
chars = ["@", "#", "S", "%", "?", "*", "+", ";", ":", ",", "."]
# 將圖像的像素值轉換成 numpy 陣列
pixels = np.array(img)
# 將每個像素值對應到一個 ASCII 字元
ascii_pixels = np.array([chars[pixel // 25] for pixel in pixels.flatten()])
# 將 ASCII 陣列重塑成與圖像形狀相同
ascii_pixels = ascii_pixels.reshape(new_height, new_width)
# 將 ASCII 字元連接成一個字串
ascii_image = "\n".join("".join(row) for row in ascii_pixels)
# 印出 ASCII 圖檔
print(ascii_image)
ASCII圖像
。numpy
模組,就像是打開另一個工具箱。ASCII字元
列表,就像是一個密碼表。numpy
陣列,就像是把照片切割成很多小方塊。ASCII字元
,就像是用密碼表來替換每個小方塊。0到10的索引值
,再用這個索引值來選擇ASCII字元列表
中的一個字元。ASCII字元的陣列
重新整理成跟圖像一樣的形狀,就像是把小方塊重新拼回原來的位置。ASCII字元
連接成一個字串,並且印出來,就可以看到ASCII圖像了。with open("ascii_image.txt", "w") as f:
f.write(ascii_image)
open
函數來建立一個文字檔案,並且命名為ascii_image.txt
。參數"w"
表示要以寫入模式打開這個檔案。with
語句來管理這個檔案物件f
,這樣可以確保檔案在使用完畢後會自動關閉。write
方法來將ascii_image
字串寫入到f中,就可以把ASCII圖像儲存起來了。