Các phép biến đổi toàn cục
Phép biến đổi toàn cục là nhóm các kỹ thuật xử lý ảnh mà giá trị của mỗi điểm ảnh đầu ra phụ thuộc vào toàn bộ ảnh, không chỉ riêng điểm ảnh đó hay vùng lân cận. Các phép biến đổi này thường được thực hiện trong miền tần số hoặc dựa trên phân bố tổng thể của ảnh. Mục tiêu chính của biến đổi toàn cục là phân tích cấu trúc tổng quát, loại bỏ nhiễu có tính hệ thống và tăng cường chất lượng ảnh ở mức toàn ảnh.
Các phương pháp tiêu biểu của biến đổi toàn cục bao gồm biến đổi Fourier rời rạc (DFT), biến đổi cosin rời rạc (DCT) và các kỹ thuật lọc tần số. Trong miền tần số, ảnh được biểu diễn dưới dạng các thành phần tần số thấp và cao; tần số thấp tương ứng với vùng trơn và nền ảnh, trong khi tần số cao biểu diễn các biên và chi tiết. Dựa vào đặc điểm này, các bộ lọc thông thấp, thông cao và thông dải được áp dụng để làm mượt ảnh, tăng cường biên hoặc khử nhiễu.
Biến đổi toàn cục được ứng dụng rộng rãi trong nén ảnh (JPEG), khôi phục ảnh, lọc nhiễu, và các bài toán phân tích ảnh nâng cao trong thị giác máy tính.
Code lọc tần số
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Đọc ảnh xám
img = cv2.imread("input.jpg", cv2.IMREAD_GRAYSCALE)
if img is None:
raise ValueError("Không tìm thấy input.jpg")
rows, cols = img.shape
crow, ccol = rows // 2, cols // 2
# =========================
# 1. FOURIER TRANSFORM
# =========================
dft = np.fft.fft2(img)
dft_shift = np.fft.fftshift(dft)
magnitude = 20 * np.log(np.abs(dft_shift) + 1)
# =========================
# 2. TẠO MẶT NẠ LỌC
# =========================
radius = 40
# Lọc thông thấp
mask_low = np.zeros((rows, cols), np.uint8)
cv2.circle(mask_low, (ccol, crow), radius, 1, -1)
# Lọc thông cao
mask_high = 1 - mask_low
# =========================
# 3. ÁP DỤNG LỌC
# =========================
low_filtered = dft_shift * mask_low
high_filtered = dft_shift * mask_high
# =========================
# 4. BIẾN ĐỔI NGƯỢC
# =========================
img_low = np.fft.ifft2(np.fft.ifftshift(low_filtered))
img_low = np.abs(img_low)
img_high = np.fft.ifft2(np.fft.ifftshift(high_filtered))
img_high = np.abs(img_high)
# =========================
# HIỂN THỊ KẾT QUẢ
# =========================
plt.figure(figsize=(14,8))
images = [
(img, "Ảnh gốc"),
(magnitude, "Phổ tần số"),
(img_low, "Lọc thông thấp"),
(img_high, "Lọc thông cao")
]
for i, (image, title) in enumerate(images):
plt.subplot(2,2,i+1)
plt.imshow(image, cmap='gray')
plt.title(title)
plt.axis('off')
plt.text(5, 15, "Nguyễn Văn Chuân",
color='white', fontsize=9,
bbox=dict(facecolor='black', alpha=0.6))
plt.tight_layout()
plt.show()
Ảnh minh họa lọc tần số

Code minh họa phép biến đổi cosin rời rạc
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Đọc ảnh xám
img = cv2.imread("input.jpg", cv2.IMREAD_GRAYSCALE)
if img is None:
raise ValueError("Không tìm thấy input.jpg")
# Chuyển sang float32 để tính DCT
img_f = np.float32(img)
# =========================
# 1. DCT 2 CHIỀU
# =========================
dct = cv2.dct(img_f)
# Hiển thị phổ DCT (log để dễ quan sát)
dct_log = np.log(np.abs(dct) + 1)
# =========================
# 2. DCT NGƯỢC (IDCT)
# =========================
img_idct = cv2.idct(dct)
img_idct = np.uint8(np.clip(img_idct, 0, 255))
# =========================
# HIỂN THỊ KẾT QUẢ
# =========================
plt.figure(figsize=(12,4))
# Ảnh gốc
plt.subplot(1,3,1)
plt.imshow(img, cmap='gray')
plt.title("Ảnh gốc")
plt.axis('off')
plt.text(5, 15, "Nguyễn Văn Chuân",
color='white', fontsize=9,
bbox=dict(facecolor='black', alpha=0.6))
# Phổ DCT
plt.subplot(1,3,2)
plt.imshow(dct_log, cmap='gray')
plt.title("Phổ DCT (log)")
plt.axis('off')
plt.text(5, 15, "Nguyễn Văn Chuân",
color='white', fontsize=9,
bbox=dict(facecolor='black', alpha=0.6))
# Ảnh khôi phục
plt.subplot(1,3,3)
plt.imshow(img_idct, cmap='gray')
plt.title("Ảnh khôi phục (IDCT)")
plt.axis('off')
plt.text(5, 15, "Nguyễn Văn Chuân",
color='white', fontsize=9,
bbox=dict(facecolor='black', alpha=0.6))
plt.tight_layout()
plt.show()
Ảnh minh họa kết quả biến đổi cosin rời rạc

Code minh họa phép biến đổi Fourrier
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Đọc ảnh xám
img = cv2.imread("input.jpg", cv2.IMREAD_GRAYSCALE)
if img is None:
raise ValueError("Không tìm thấy input.jpg")
# =========================
# 1. DFT 2 CHIỀU
# =========================
dft = np.fft.fft2(img)
dft_shift = np.fft.fftshift(dft)
# Phổ biên độ (log để dễ quan sát)
magnitude = 20 * np.log(np.abs(dft_shift) + 1)
# =========================
# 2. DFT NGƯỢC (IDFT)
# =========================
img_idft = np.fft.ifft2(np.fft.ifftshift(dft_shift))
img_idft = np.abs(img_idft)
img_idft = np.uint8(np.clip(img_idft, 0, 255))
# =========================
# HIỂN THỊ KẾT QUẢ
# =========================
plt.figure(figsize=(12,4))
# Ảnh gốc
plt.subplot(1,3,1)
plt.imshow(img, cmap='gray')
plt.title("Ảnh gốc")
plt.axis('off')
plt.text(
5, 15, "Nguyễn Văn Chuân",
color='white', fontsize=9,
bbox=dict(facecolor='black', alpha=0.6)
)
# Phổ Fourier
plt.subplot(1,3,2)
plt.imshow(magnitude, cmap='gray')
plt.title("Phổ Fourier (log)")
plt.axis('off')
plt.text(
5, 15, "Nguyễn Văn Chuân",
color='white', fontsize=9,
bbox=dict(facecolor='black', alpha=0.6)
)
# Ảnh khôi phục
plt.subplot(1,3,3)
plt.imshow(img_idft, cmap='gray')
plt.title("Ảnh khôi phục (IDFT)")
plt.axis('off')
plt.text(
5, 15, "Nguyễn Văn Chuân",
color='white', fontsize=9,
bbox=dict(facecolor='black', alpha=0.6)
)
plt.tight_layout()
plt.show()
Ảnh minh họa kết quả phép biến đổi Fourrier

Code minh họa phép lọc trong miền tần số
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Đọc ảnh xám
img = cv2.imread("input.jpg", cv2.IMREAD_GRAYSCALE)
if img is None:
raise ValueError("Không tìm thấy input.jpg")
rows, cols = img.shape
crow, ccol = rows // 2, cols // 2
# =========================
# 1. FOURIER TRANSFORM
# =========================
dft = np.fft.fft2(img)
dft_shift = np.fft.fftshift(dft)
magnitude = 20 * np.log(np.abs(dft_shift) + 1)
# =========================
# 2. TẠO MẶT NẠ LỌC
# =========================
radius = 40
# --- Ideal Low-pass ---
mask_low = np.zeros((rows, cols), np.uint8)
cv2.circle(mask_low, (ccol, crow), radius, 1, -1)
# --- Ideal High-pass ---
mask_high = 1 - mask_low
# --- Gaussian Low-pass ---
x, y = np.meshgrid(np.arange(cols), np.arange(rows))
gaussian_low = np.exp(-((x-ccol)**2 + (y-crow)**2) / (2 * radius**2))
# --- Gaussian High-pass ---
gaussian_high = 1 - gaussian_low
# =========================
# 3. ÁP DỤNG LỌC
# =========================
low_filtered = dft_shift * mask_low
high_filtered = dft_shift * mask_high
gauss_low_filtered = dft_shift * gaussian_low
gauss_high_filtered = dft_shift * gaussian_high
# =========================
# 4. BIẾN ĐỔI NGƯỢC
# =========================
def idft(img_freq):
img_back = np.fft.ifft2(np.fft.ifftshift(img_freq))
return np.uint8(np.clip(np.abs(img_back), 0, 255))
img_low = idft(low_filtered)
img_high = idft(high_filtered)
img_gauss_low = idft(gauss_low_filtered)
img_gauss_high = idft(gauss_high_filtered)
# =========================
# HIỂN THỊ KẾT QUẢ
# =========================
plt.figure(figsize=(14,10))
results = [
(img, "Ảnh gốc"),
(magnitude, "Phổ Fourier"),
(img_low, "Ideal Low-pass"),
(img_high, "Ideal High-pass"),
(img_gauss_low, "Gaussian Low-pass"),
(img_gauss_high, "Gaussian High-pass")
]
for i, (image, title) in enumerate(results):
plt.subplot(3,2,i+1)
plt.imshow(image, cmap='gray')
plt.title(title)
plt.axis('off')
plt.text(
5, 15, "Nguyễn Văn Chuân",
color='white', fontsize=8,
bbox=dict(facecolor='black', alpha=0.6)
)
plt.tight_layout()
plt.show()
Ảnh minh họa kết quả phép lọc trong miền tần số

https://tritue.edu.vn/tuecode/tracnghiem30/site/data/YVdRc01qUTRMRjl5YjNWMFpTeGlZV2wyYVdWMEwzQnZjM1F2ZG1sbGR3PT0%3D