ฉันจะตอบคำถามแรกเท่านั้น: ความถี่ในภาพคืออะไร
การแปลงฟูริเยร์เป็นเทคนิคทางคณิตศาสตร์ที่แสดงข้อมูลภาพเดียวกันไม่ใช่สำหรับแต่ละพิกเซลแยกจากกัน แต่เป็นสำหรับแต่ละความถี่ คิดแบบนี้ ทะเลมีคลื่นซึ่งบางส่วนเคลื่อนไหวช้ามาก (เช่นกระแสน้ำ) อื่น ๆ มีขนาดปานกลางและบางส่วนก็เล็กเหมือนคลื่นที่เกิดจากความกระโชก คุณสามารถคิดว่าพวกมันเป็นคลื่นสามคลื่นแยกกัน แต่ในแต่ละจุดบนผิวน้ำทะเลและในช่วงเวลาหนึ่งคุณจะได้รับน้ำเพียงหนึ่งระดับ
เช่นเดียวกับภาพ คุณสามารถนึกถึงภาพที่เกิดขึ้นจากคลื่นหรือความถี่ต่าง ๆ ในการสร้างภาพของคุณเริ่มต้นด้วยสีเฉลี่ย (จริง ๆ แล้วคิดว่าภาพระดับสีเทานั้นง่ายกว่า) จากนั้นเพิ่มคลื่นที่มีความยาวและความแตกต่างของคลื่นเพื่อสร้างรายละเอียดในภาพอย่างช้าๆ
ภาพต้นฉบับ:
ความถี่แรก (เฉลี่ย):
ความถี่ที่สองตามแนวตั้งคือคลื่นที่เริ่มต้นที่ศูนย์ที่ด้านล่างของภาพเพิ่มขึ้นกลายเป็นศูนย์อีกครั้งตามขอบฟ้ากึ่งกลางและลดลงต่ำกว่าศูนย์ในที่สุดก็กลายเป็นศูนย์ที่ด้านบนของภาพ (ฉันอธิบายชุดฟูริเยร์โดยไม่มีการเลื่อนเฟส แต่การเปรียบเทียบยังคงมีอยู่)
ที่นี่คุณสามารถเห็นความถี่ที่สองตามแนวนอนและแนวตั้ง โปรดสังเกตว่าคุณสามารถกำหนดได้ว่าภูเขาจะอยู่ที่ไหน (มืด) และบริเวณที่ท้องฟ้าและทะเลสาบ (เบา)
ความถี่ที่สอง:
คลื่นหรือความถี่เพิ่มเติมแต่ละคลื่นจะนำระลอกคลื่นมากขึ้นและมีรายละเอียดมากขึ้น เพื่อให้ได้ภาพที่แตกต่างกันความสูงของคลื่น / แอมพลิจูดสามารถเปลี่ยนแปลงได้เช่นเดียวกับจุดเริ่มต้นของคลื่นที่เรียกว่าเฟส
ความถี่ที่สาม:
น่าสนใจจำนวนข้อมูลที่เหมือนกันในการนำเสนอนี้และสามารถย้อนกลับไปมาระหว่างภาพปกติ (โดเมนเชิงพื้นที่) และภาพที่แปลงฟูริเยร์ (โดเมนความถี่) ในโดเมนความถี่เราต้องเก็บข้อมูลความถี่ทั้งหมดพร้อมกับแอมพลิจูดและข้อมูลเฟส
ที่นี่ใช้ 50% ของความถี่:
มีความแตกต่างของทั้งหมดนี้ด้วยความแตกต่างที่จะทำในหมู่ฟูริเยร์ซีรีส์การแปลงฟูริเยร์และการแปลงฟูริเยร์แบบแยกและการแปลงโคไซน์ไม่ต่อเนื่อง (DCT)
แอปพลิเคชั่นที่น่าสนใจอย่างหนึ่งคือการใช้อัลกอริธึมการบีบอัดเช่น JPEG ที่นี่ DCT ใช้เพื่อบันทึกส่วนสำคัญของรูปภาพ (ความถี่ต่ำ) และความถี่สูงน้อยลง
ฉันเขียนสิ่งนี้ด้วยความหวังว่าผู้อ่านมือใหม่สามารถเข้าใจพื้นฐานของแนวคิดการแปลงฟูริเยร์ได้ สำหรับสิ่งที่ฉันทำเรียบง่ายที่ฉันหวังว่าผู้อ่านขั้นสูงจะให้อภัยฉัน
ภาพเคลื่อนไหว
วิดีโอที่สร้างโดยโทมัส Devoogdt สามารถดูได้ที่Vimeo
ความถี่ในการประมวลผลภายหลัง
มีวิธีการมากมายที่ต้องใช้ความถี่ในการประมวลผลภายหลังส่วนใหญ่เป็นเพราะเราไม่เคยดูทีละพิกเซล อัลกอริธึมหลายอย่างทำงานกับความถี่เพราะมันเป็นธรรมชาติมากกว่าที่จะคิดเกี่ยวกับพวกเขาด้วยวิธีนี้ แต่ก็เป็นเพราะการแปลงฟูริเยร์มีข้อมูลเดียวกับที่เราสามารถแสดงการดำเนินการทางคณิตศาสตร์ใด ๆ (หรือขั้นตอนการโพสต์) ในความถี่และโดเมนเชิงพื้นที่! บางครั้งคำอธิบายพิกเซลฉลาดดีกว่า แต่บ่อยครั้งคำอธิบายความถี่ดีกว่า (ส่วนใหญ่หมายถึงเร็วกว่าในบริบทนี้)
เทคนิคหนึ่งที่ฉันต้องการชี้ไปโดยไม่มีเหตุผลเฉพาะยกเว้นว่าเป็นศิลปินที่ทำงานโดยตรงกับความถี่และนั่นคือ * การแยกความถี่ * ฉันจะไม่อธิบาย แต่คุณสามารถดูวิธีการทำงานบน YouTube สำหรับทั้ง Photoshop และ GIMP
คุณสร้างสองชั้นหนึ่งที่มีความถี่ต่ำและหนึ่งที่มีความถี่สูง สำหรับการถ่ายภาพบุคคลคุณสามารถปรับผิวให้เรียบบนความถี่สูงโดยไม่ส่งผลกระทบต่อโทนสีผิวในความถี่ต่ำ
รหัส
นี่คือรหัสเพื่อสร้างตัวอย่างข้างต้น สามารถเรียกใช้เป็นโปรแกรม Python อย่างง่าย
from PIL import Image
from numpy.fft import rfft2, irfft2
import numpy as np
def save_dims(ft, low, high, name):
ft2 = np.zeros_like(ft)
# copy the frequencies from low to high but all others stay zero.
ft2[low:high, low:high] = ft[low:high, low:high]
save(ft2, name)
def save(ft, name):
rft = irfft2(ft)
img = Image.fromarray(rft)
img = img.convert('L')
img.save(name)
def main():
# Convert input into grayscale and save.
img = Image.open("input.jpg")
img = img.convert('L')
img.save('input_gray.png')
# Do Fourier Transform on image.
ft = rfft2(img)
# Take only zeroth frequency and do Inverse FT and save.
save_dims(ft, 0, 1, 'output_0.png')
# Take first two frequencies in both directions.
save_dims(ft, 0, 2, 'output_1.png')
save_dims(ft, 0, 3, 'output_2.png')
# Take first 50% of frequencies.
x = min(ft.shape)
save_dims(ft, 0, x/2, 'output_50p.png')
def generateGif():
''' Generates images to be later converted to a gif.
This requires ImageMagick:
convert -delay 100 -loop 0 output_*.png animation.gif
'''
# Requires images2gif from code.google.com/p/visvis/source/browse/vvmovie/images2gif.py
# from images2gif import writeGif
img = Image.open('input.jpg')
img = img.convert('L')
# Resize image before any calculation.
size = (640,480)
img.thumbnail(size, Image.ANTIALIAS)
ft = rfft2(img)
images = []
for x in range(0, max(ft.shape)):
ft2 = np.zeros_like(ft)
ft2[0:x, 0:x] = ft[0:x,0:x]
rft = irfft2(ft2)
img_out = Image.fromarray(rft).convert('L')
fname = 'animation/output_%05d.jpg' %(x, )
img_out.save(fname, quality=60, optimize=True)
#writeGif('animation.gif', images, duration=0.2)
if __name__=='__main__':
main()
#generateGif()