ডিসক্রিট কোসাইন ট্রান্সফর্ম (DCT) ও কমপ্রেশন
এই পাঠে যা শিখবেন
- DCT-II-এর সংজ্ঞা ও সরাসরি ক্লোজড-ফর্ম সামেশন সূত্র
- Python-এ হাতে-লেখা DCT বাস্তবায়ন করা, DFT-এর সাথে তুলনা করে
- এনার্জি কম্প্যাকশন ধারণা ও কেন এটি মসৃণ সিগন্যালের জন্য বিশেষভাবে কার্যকর
- DCT কীভাবে JPEG/MP3-এর মতো বাস্তব কমপ্রেশন স্ট্যান্ডার্ডে ব্যবহৃত হয়
১ · DCT-II-এর সংজ্ঞা
DCT (Discrete Cosine Transform)Discrete Cosine Transformশুধু কোসাইন বেসিস ফাংশন ব্যবহারকারী একটি রিয়েল-ভ্যালুড ফ্রিকোয়েন্সি-ডোমেইন ট্রান্সফর্ম, যা মসৃণ সিগন্যালের এনার্জি কম কয়েকটি কোয়েফিসিয়েন্টে কেন্দ্রীভূত করে। -এর সবচেয়ে প্রচলিত রূপ, DCT-II, সংজ্ঞায়িত হয়:
$$X[k] = \sum_{n=0}^{N-1} x[n] \cos\!\left(\frac{\pi}{N}\left(n+\tfrac{1}{2}\right)k\right), \quad k=0,1,\dots,N-1$$M২২-এর DFT সূত্রের সাথে তুলনা করলে — DFT-তে $e^{-j2\pi kn/N}$ (কমপ্লেক্স, সাইন ও কোসাইন উভয় অংশ থাকে), DCT-তে শুধু $\cos(\cdot)$ (বিশুদ্ধ রিয়েল সংখ্যা)। এই সাধারণ পরিবর্তনটাই DCT-কে একটি বাস্তব-মূল্যবান ($x[n] \in \mathbb{R}$-এর জন্য $X[k] \in \mathbb{R}$) ট্রান্সফর্মে পরিণত করে — সংরক্ষণ ও প্রসেসিং-এর জন্য সুবিধাজনক, কারণ কমপ্লেক্স সংখ্যার আলাদা রিয়েল/ইমাজিনারি অংশ ব্যবস্থাপনা করতে হয় না।
DFT-এর মতোই DCT-ও একটি $O(N^2)$ সরাসরি সামেশন হিসেবে গণনাযোগ্য — এই পাঠে সেটাই বাস্তবায়ন করা হয়েছে, কোনো লাইব্রেরি ছাড়া।
মসৃণ সিগন্যালের জন্য DCT কোয়েফিসিয়েন্টগুলো $k$ বাড়ার সাথে সাথে দ্রুত ছোট হয়ে যায় — নিচের ডেমোতে সরাসরি গণনা করে দেখানো হয়েছে।
JPEG ছবিকে ৮×৮ ব্লকে ভাগ করে প্রতিটিতে ২D DCT প্রয়োগ করে, তারপর ছোট (উচ্চ-ফ্রিকোয়েন্সি) কোয়েফিসিয়েন্টগুলো বাদ দিয়ে/কম নির্ভুলতায় সংরক্ষণ করে কমপ্রেস করে।
২ · একটি সত্যিকারের ডেমো — DCT বনাম DFT এনার্জি কম্প্যাকশন
নিচের কোডে $N=16$ দৈর্ঘ্যের একটি মসৃণ টেস্ট সিগন্যাল তৈরি করা হয়েছে — একটি Gaussian bump ($x[n] = e^{-(n-7.5)^2/(2\cdot3^2)}$, কেন্দ্রে সর্বোচ্চ, প্রান্তে ধীরে শূন্যের কাছে নামে, কোনো আকস্মিক লাফ নেই)। এই একই সিগন্যালের উপর M৫-এর হাতে-লেখা DFT এবং সরাসরি সূত্র দিয়ে বাস্তবায়িত DCT-II — উভয়ই প্রয়োগ করে প্রতিটির এনার্জি (কোয়েফিসিয়েন্ট স্কয়ারের যোগফল) কতটা প্রথম কয়েকটি পদে কেন্দ্রীভূত তা তুলনা করা হয়েছে।
import math, cmath
def dft(x):
N = len(x)
X = []
for k in range(N):
s = 0 + 0j
for n in range(N):
s += x[n] * cmath.exp(-2j * math.pi * k * n / N)
X.append(s)
return X
def dct2(x):
N = len(x)
X = []
for k in range(N):
s = 0.0
for n in range(N):
s += x[n] * math.cos(math.pi / N * (n + 0.5) * k)
X.append(s)
return X
N = 16
# মসৃণ টেস্ট সিগন্যাল: একটি Gaussian bump, কেন্দ্র n=7.5, sigma=3
x = [math.exp(-((n - 7.5) ** 2) / (2 * 3.0 ** 2)) for n in range(N)]
X_dct = dct2(x)
X_dft = dft(x)
dct_energy = [c * c for c in X_dct]
dft_energy = [abs(c) ** 2 for c in X_dft]
total_dct = sum(dct_energy)
total_dft = sum(dft_energy)
print(f"{'k':>3} | {'DCT coef':>10} | {'DFT |X[k]|':>10}")
for k in range(N):
print(f"{k:>3} | {X_dct[k]:>10.4f} | {abs(X_dft[k]):>10.4f}")
print()
for K in [2, 3, 6]:
dct_pct = 100 * sum(dct_energy[:K]) / total_dct
dft_pct = 100 * sum(dft_energy[:K]) / total_dft
print(f"প্রথম K={K} কোয়েফিসিয়েন্ট: DCT ধরে রাখে {dct_pct:.2f}% এনার্জি, DFT(mag) ধরে রাখে {dft_pct:.2f}% এনার্জি")
DCT-এর কোসাইন-শুধু বেসিস মসৃণ সিগন্যালের জন্য DFT-এর চেয়ে অনেক বেশি এনার্জি-কম্প্যাক্ট প্রতিনিধিত্ব দেয় — উপরের ডেমোতে ৯৯.৭৩% বনাম ৮২.৭৫% এই পার্থক্য স্পষ্ট করে। যেহেতু ছবি ও অডিও সিগন্যালের বেশিরভাগ অংশই স্থানীয়ভাবে মসৃণ (পাশাপাশি পিক্সেল/স্যাম্পল কাছাকাছি মানের), DCT-ভিত্তিক কমপ্রেশন (JPEG, MP3, AAC) অল্প কয়েকটি বড় কোয়েফিসিয়েন্ট সংরক্ষণ করে আর বাকিগুলো বাতিল/কোয়ান্টাইজ করে ফাইল-সাইজ অনেক কমাতে পারে, গুণগত মান খুব একটা না হারিয়ে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ উপরের ডেমোতে সব বিজোড় $k$-এর DCT কোয়েফিসিয়েন্ট প্রায় শূন্য কেন?
টেস্ট সিগন্যাল $x[n] = e^{-(n-7.5)^2/(2\cdot 3^2)}$ ঠিক $n=7.5$-এর চারপাশে প্রতিসম (symmetric) — অর্থাৎ $x[7-i] \approx x[8+i]$ যেকোনো $i$-এর জন্য। কোসাইন ফাংশন নিজেও একটি জোড় (even) ফাংশন, তাই বিজোড় কোসাইন বেসিসগুলো (যেগুলোর মধ্যে একটি প্রতিসাম্য-বিরোধী গঠন আছে) এই প্রতিসম সিগন্যালের সাথে গুণ করলে ধনাত্মক ও ঋণাত্মক অবদান একে অপরকে বাতিল করে দেয় — ঠিক M২৩-এর জোড়/বিজোড় সিমেট্রি বিশ্লেষণের মতোই একটি যুক্তি।
প্র ০২
যদি টেস্ট সিগন্যালটি মসৃণ না হয়ে সম্পূর্ণ র্যান্ডম (যেমন random.gauss নয়েজ) হতো,
তাহলে DCT-এর এনার্জি-কম্প্যাকশন কেমন হতো বলে আপনার ধারণা?
অনেক খারাপ হতো — প্রায় সমান-সমান ছড়িয়ে যেত। এনার্জি-কম্প্যাকশন নির্ভর করে সিগন্যালের পাশাপাশি স্যাম্পলগুলোর মধ্যে পারস্পরিক সম্পর্ক (correlation)-এর উপর — মসৃণ সিগন্যালে পাশাপাশি মানগুলো কাছাকাছি (উচ্চ correlation), যা কম কয়েকটি নিম্ন-ফ্রিকোয়েন্সি কোসাইনেই ভালোভাবে প্রকাশযোগ্য। বিশুদ্ধ র্যান্ডম নয়েজে পাশাপাশি স্যাম্পলের মধ্যে কোনো সম্পর্ক থাকে না, তাই এনার্জি সব কোয়েফিসিয়েন্টে প্রায় সমানভাবে ছড়িয়ে যায় — এটাই কমপ্রেশন অ্যালগরিদম নয়েজি ডেটাতে খারাপ কাজ করার মূল কারণ।
প্র ০৩ DFT আর DCT উভয়েরই $k=0$ কোয়েফিসিয়েন্ট $7.4644$ — একদম সমান। এটি কি কাকতালীয়?
না। উভয় সূত্রেই $k=0$-তে বসালে সাইন/কোসাইন পদ যথাক্রমে $e^0=1$ এবং $\cos(0)=1$ হয়ে যায় (DCT-তে $\cos(\frac{\pi}{N}(n+0.5)\cdot 0) = \cos(0) = 1$ সব $n$-এর জন্য) — তাই উভয় ক্ষেত্রেই $k=0$ কোয়েফিসিয়েন্ট আসলে শুধু সিগন্যালের সব মানের যোগফল, $\sum_n x[n]$। যেহেতু একই $x$ ব্যবহার হয়েছে, দুটোই একই মান দেয়।
অনুশীলন
-
চিন্তা করুন: উপরের কোডে
K-এর মান ২ থেকে ৩-এ বাড়ালে DCT-এর এনার্জি-শতাংশ ৭৯.১৫%(K=২) থেকে হঠাৎ ৯৯.৭৩%(K=৩)-এ লাফ দেয়। এত বড় লাফের কারণ কী হতে পারে বলে আপনার ধারণা (উপরের প্র ০১-এর উত্তর মনে করুন)?কারণ $k=1$ (বিজোড়) কোয়েফিসিয়েন্ট প্রায় শূন্য, তাই K=২ থেকে K=৩-এ যাওয়ার আসল "লাফ"টা ঘটে $k=2$ যোগ হওয়ার সময় (যার মান $-3.8059$, দ্বিতীয়-সবচেয়ে-বড় এনার্জি-অবদানকারী), $k=1$ যোগ হওয়ার সময় নয়। এটাই দেখায় কেন K বাড়ানোর প্রভাব সবসময় সরল-রৈখিক নয় — নির্দিষ্ট সিগন্যালের গঠনের উপর নির্ভর করে।
-
পরীক্ষা করুন: কোড সেলে সিগন্যাল
x-কে একটি সরল লিনিয়ার র্যাম্প (x = [n/15 for n in range(16)])-এ বদলে Run চাপুন — এটিও একটি মসৃণ সিগন্যাল, কি DCT এনার্জি-কম্প্যাকশন আগের Gaussian bump-এর মতোই শক্তিশালী থাকে?রান করলে দেখা যাবে একটি রৈখিক র্যাম্পও ভালো এনার্জি-কম্প্যাকশন দেখায় (যদিও প্রতিসম না হওয়ায় বিজোড় কোয়েফিসিয়েন্টগুলো এবার শূন্য হবে না) — কারণ এটিও একটি মসৃণ, ধীরে-পরিবর্তনশীল সিগন্যাল। তবে সঠিক শতাংশ ভিন্ন হবে, কারণ সিগন্যালের গঠন ভিন্ন — এটি নিশ্চিত করে এনার্জি-কম্প্যাকশন সিগন্যালের "মসৃণতা"-র উপর নির্ভরশীল একটি সাধারণ বৈশিষ্ট্য, শুধু একটি নির্দিষ্ট উদাহরণের কাকতালীয় ফলাফল নয়।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- অ্যাডাপটিভ ফিল্টার — LMS অ্যালগরিদমের ভিত্তি পরবর্তী পাঠ এই মডিউলের শেষ পাঠ — একটি ফিল্টার যা নিজে থেকেই সিগন্যাল দেখে দেখে শিখে-শিখে তার কোয়েফিসিয়েন্ট আপডেট করে।
- ইমেজ প্রসেসিং-এ DSP — 2D কনভোলিউশনের ভিত্তি M১২ JPEG-এর মতো কমপ্রেশন পাইপলাইনের ধারণাগত পটভূমি — এই পাঠের DCT সেখানকার একটি মূল উপাদান।
- Numerical Methods কোর্স সহোদর কোর্স সাধারণ সংখ্যাগত অ্যালগরিদম ও ত্রুটি বিশ্লেষণ — এই কোর্স সেই একই হাতে-লেখা দর্শনের উপর সিগন্যাল-প্রসেসিং-নির্দিষ্ট দিকটি যোগ করে।