পাঠ ০১ · ৩৫-এর মধ্যে · মডিউল ১
Home / AI Courses / Computer Vision / ছবি ও tensor

ছবি কীভাবে tensor হয় — পিক্সেল ও চ্যানেল

Images as tensors — pixels and channels
৭ মিনিট পড়া শুরু · Beginner NumPy কোডসহ

এই পাঠে যা শিখবেন

  • পিক্সেল কী — একটি ছবির ক্ষুদ্রতম একক
  • Grayscale বনাম RGB — চ্যানেলের ধারণা
  • একটি ছবির shape কীভাবে পড়তে হয় — (H, W, C)
  • NumPy দিয়ে ছবিকে tensor হিসেবে ব্যবহার

১ · একটি ছবি আসলে কী?

আপনি একটি বিড়ালের ছবি দেখলে সাথে সাথেই বুঝে যান — এটি বিড়াল। কিন্তু কম্পিউটারের চোখে ছবি বলে কিছু নেই — শুধু সংখ্যা। একটি ছবি হলো পিক্সেলPixel"Picture Element"-এর সংক্ষেপ। ছবির ক্ষুদ্রতম একক — একটি ছোট চৌকো ঘর যাতে একটি রঙ বা brightness বসে। ছবির resolution মানে কত পিক্সেল আছে।-এর গ্রিড। প্রতিটি পিক্সেল একটি সংখ্যা — সাধারণত 0 (কালো) থেকে 255 (সাদা) পর্যন্ত।

কেন্দ্রীয় ধারণা

ছবি = সংখ্যার সাজানো গ্রিড। AI ছবি "চোখে" দেখে না — প্রতিটি পিক্সেলের সংখ্যা থেকে বুঝে। তাই Computer Vision-এর প্রথম কাজ — ছবিকে tensorTensorবহু-মাত্রিক সংখ্যার অ্যারে। ১-D = vector, ২-D = matrix, ৩-D ও তার বেশি = tensor। NumPy/PyTorch-এর মূল ডেটা-কাঠামো।-এ রূপান্তর।

২ · Grayscale ছবি — ২-D matrix

একটি সাদা-কালো ছবি হলো ২-D matrix। প্রতিটি ঘরে একটি সংখ্যা। 0 মানে কালো, 255 মানে সাদা, মাঝের সংখ্যাগুলো ধূসরের নানা ছায়া।

একটি ছোট 3×3 grayscale ছবি কেমন:

$$\text{ছবি} = \begin{bmatrix} 0 & 128 & 255 \\ 64 & 192 & 32 \\ 200 & 50 & 100 \end{bmatrix}$$

এর shape = $(3, 3)$ — মানে height=৩, width=৩।

ভাবুন একটি কাঁচ-কাগজে আঁকা ছবি — যা ৩×৩ চৌকোয় ভাগ। প্রতিটি চৌকোয় শুধু একটি সংখ্যা — কতটা কালো বা সাদা। একে দূর থেকে দেখলে দেখাবে আবছা মুখ বা কোনো প্যাটার্ন।

৩ · RGB ছবি — ৩-D tensor

রঙিন ছবি একটু জটিল — কিন্তু একই ধারণা। প্রতিটি পিক্সেলে এক সংখ্যা না — তিনটি সংখ্যা: R (Red), G (Green), B (Blue)। একে বলে চ্যানেল।

একটি RGB ছবির shape = $(H, W, 3)$ — যেখানে $H$ = height, $W$ = width, ৩ = চ্যানেল সংখ্যা। যেমন একটি 224×224 RGB ছবির shape = $(224, 224, 3)$।

একটি পিক্সেল কেমন? $(255, 0, 0)$ মানে purely red। $(0, 255, 0)$ — green। $(255, 255, 255)$ — সাদা (সব চ্যানেল full)। $(0, 0, 0)$ — কালো (সব চ্যানেল zero)।

৪ · একটি ছবির আকার — গণিতে

$$\text{মোট পিক্সেল} = H \times W \times C$$

যেমন একটি 224×224 RGB ছবি = $224 \times 224 \times 3 = 150{,}528$ সংখ্যা। প্রতিটি 8-bit (1 byte) হলে ছবির মেমোরি প্রায় 150 KB।

৫ · Channel-first বনাম channel-last

দু'টি convention জনপ্রিয়:

  • Channel-last (HWC): shape = $(H, W, C)$ — TensorFlow ও OpenCV ব্যবহার করে।
  • Channel-first (CHW): shape = $(C, H, W)$ — PyTorch ব্যবহার করে।

একটি library থেকে অন্যটিতে ছবি পাঠাতে গেলে এই অর্ডার বদলাতে হয় — ভুললে shape mismatch error আসবে।

৬ · Pixel value এবং AI

AI মডেলে ছবি ঢুকানোর আগে সাধারণত pixel value ০–১ এ normalizeNormalizationসংখ্যাগুলোকে একটি ছোট পরিসরে আনা — সাধারণত [0, 1] বা [-1, 1]। AI training-এ gradient stable রাখার জন্য জরুরি। করা হয়:

$$\text{normalized} = \frac{\text{pixel}}{255.0}$$

কারণ — নিউরাল নেটওয়ার্কে বড় সংখ্যা gradient explosion ঘটায়। 0–255 এর জায়গায় 0–1 ব্যবহার training stable রাখে।

ImageNet-এ pretrained মডেলগুলো আরও এক ধাপ এগিয়ে — প্রতিটি চ্যানেল-এর mean বিয়োগ ও std দিয়ে ভাগ করে। যেমন ResNet-এ: mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]।
একটি ছবি — ৩টি দৃষ্টিতে RGB image → tensor 📷 চোখে দেখা ছবি 224 × 224 px মানুষ যা দেখে 🔢 পিক্সেল গ্রিড 12 68 142 প্রতিটি ঘর = সংখ্যা 0–255 🤖 NumPy tensor img.shape (224, 224, 3) H × W × C 3 channel: R, G, B কম্পিউটার যা পায়
একই ছবি — মানুষের চোখে রঙিন দৃশ্য, কম্পিউটারে $(H, W, C)$ shape-এর tensor।

৭ · NumPy দিয়ে একটি ছবি

আসুন একটি ছোট grayscale ছবি বানিয়ে দেখি — শুধু NumPy দিয়ে।

Python · NumPy
import numpy as np

# 3x3 grayscale ছবি — হাতে বানানো
img_gray = np.array([
    [  0, 128, 255],
    [ 64, 192,  32],
    [200,  50, 100]
], dtype=np.uint8)

print("shape:", img_gray.shape)   # (3, 3)
print("dtype:", img_gray.dtype)   # uint8
print("min:", img_gray.min(), "max:", img_gray.max())

    
shape: (3, 3) — height=৩, width=৩। dtype: uint8 — unsigned 8-bit integer, যা 0–255 সংখ্যা ধরতে পারে।

৮ · একটি ছোট RGB ছবি বানানো

Python · NumPy
import numpy as np

# 2x2 RGB ছবি — চারটি পিক্সেল, প্রতিটি 3-channel
img_rgb = np.array([
    [[255,   0,   0], [  0, 255,   0]],   # লাল, সবুজ
    [[  0,   0, 255], [255, 255, 255]],   # নীল, সাদা
], dtype=np.uint8)

print("shape:", img_rgb.shape)             # (2, 2, 3)
print("পিক্সেল [0,0]:", img_rgb[0, 0])     # [255 0 0] — লাল
print("শুধু R channel:")
print(img_rgb[:, :, 0])                    # সব পিক্সেলের R মান

    
img_rgb[:, :, 0] — সব পিক্সেলের শুধু Red চ্যানেল বের করে। AI-তে চ্যানেল আলাদা করে কাজ করা সাধারণ।

৯ · বাস্তব AI-তে ছবির shape

  • ImageNet: 224×224×3 — সবচেয়ে জনপ্রিয় size।
  • CIFAR-10: 32×32×3 — ছোট ছবি, দ্রুত training।
  • MNIST: 28×28×1 — grayscale digit।
  • HD photo: 1920×1080×3 ≈ 6.2 million সংখ্যা।
  • Batch: AI সাধারণত একসাথে অনেক ছবি দেখে — shape হয় $(N, H, W, C)$ যেখানে $N$ = batch size।
Computer Vision শেখার পুরো পথ — এই tensor-গুলো দিয়েই হবে। প্রতিটি filter, kernel, neural network — শেষমেশ সংখ্যার এই গ্রিড-এ গণিতের অপারেশন। এই পাঠের shape ও indexing ভালো করে রপ্ত করুন।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ কেন একটি ছবি 8-bit (0–255) এ store হয়, 16-bit বা 32-bit-এ না? এর সুবিধা ও সীমাবদ্ধতা কী?

মানুষের চোখ একটি চ্যানেলে প্রায় ১০০-২০০ ভিন্ন brightness level আলাদা করতে পারে। 8-bit (২৫৬ level) — চোখের ক্ষমতার চেয়ে সামান্য বেশি — তাই দেখতে স্বাভাবিক।

৮-bit-এর সুবিধা:

  • মেমোরি: 4MP RGB ছবি 8-bit-এ ১২MB, 16-bit-এ ২৪MB। ওয়েব, মোবাইল ও ডেটাসেট-এর জন্য বিশাল সাশ্রয়।
  • হার্ডওয়্যার: বেশিরভাগ camera sensor, display ও GPU 8-bit native — দ্রুত প্রক্রিয়াকরণ।
  • JPEG/PNG compatibility: জনপ্রিয় ফরম্যাট 8-bit-কেই ধরে।

সীমাবদ্ধতা:

  • Banding: মসৃণ gradient-এ ধাপে-ধাপে ভাগ দেখা যায় (যেমন আকাশের ছবিতে)।
  • HDR loss: খুব উজ্জ্বল ও খুব অন্ধকার একই সাথে capture কঠিন।
  • Medical imaging: CT, MRI সাধারণত 12-bit বা 16-bit — ক্ষুদ্র tissue পার্থক্য ধরতে।
  • Astronomy/scientific: 16-bit বা float32 — খুব ক্ষীণ আলো ধরা।

আধুনিক বিকল্প:

  • HDR (10-bit per channel): Dolby Vision, HDR10 — gaming ও premium display।
  • RAW (12-14 bit): DSLR camera — post-processing flexibility-এর জন্য।
  • float32 in AI: training-এর সময় normalize করে float-এ কাজ করা হয় — gradient stable রাখতে।

মূল উপলব্ধি: 8-bit একটি engineering compromise — মানব visual system-এর সীমা ও hardware সক্ষমতার balance। AI-তে আমরা একে normalize করে float-এ rotate করি।

প্র ০২ একটি 1MP RGB ছবি (1000×1000×3) AI-তে দেওয়া হলে — flatten করলে ৩,০০০,০০০-মাত্রিক vector। এত বড় vector কি Fully Connected Network-এ সরাসরি দেওয়া যায়? কেন CNN দরকার?

এই প্রশ্নের উত্তরই Computer Vision-এ CNN-এর জন্ম দিয়েছিল। আগের যুগে (LeCun-এর LeNet-এর আগে) ছবি flatten করে MLP-তে দেওয়া হতো — সমস্যা ছিল বিরাট।

সরাসরি FCN-এ দেওয়ার সমস্যা:

  • Parameter explosion: 3M input × 1000 hidden neurons = 3 billion parameters শুধু প্রথম layer-এ। GPU memory-তে ধরে না।
  • Training data: এত parameter fit করতে শতকোটি ছবি লাগে — যা পাওয়া অসম্ভব।
  • Spatial structure হারানো: পাশাপাশি পিক্সেল-এর সম্পর্ক flatten-এ মিশে যায়। বিড়ালের চোখ কোথায় সেটা matter করে।
  • Translation invariance নেই: বিড়াল উপরে থাকলেও আর নিচে থাকলেও একই — কিন্তু flatten-এ সেটা ভিন্ন vector।

CNN-এর সমাধান:

  • Local connectivity: প্রতিটি neuron শুধু ছোট patch (যেমন 3×3) দেখে — পুরো ছবি নয়।
  • Weight sharing: একই kernel পুরো ছবিতে slide করে — parameter কম।
  • Translation equivariance: বস্তু যেখানেই থাকুক, একই kernel detect করে।
  • Hierarchical features: প্রথম layer edges, পরে textures, তারপর objects — একদম biology-র visual cortex-এর মতো।

সংখ্যায় তুলনা:

  • FCN (3M → 1000): 3 billion parameters।
  • CNN (3×3×3 kernel × 64 filters): মাত্র ১,৭২৮ parameters — পুরো ছবিতে কাজ করে।
  • প্রায় ১.৭ million গুণ কম!

মূল উপলব্ধি: ছবির 2D structure preserve করা ও weight sharing — এই দু'টো ধারণা CV-কে scalable করেছে। CNN ছাড়া আজকের ImageNet, YOLO, Face Recognition — কিছুই হতো না।

প্র ০৩ OpenCV-তে একটি ছবি load করলে শুনেছেন BGR অর্ডারে আসে — RGB না। কেন এই অদ্ভুত choice? এতে কী সমস্যা হয়?

এটি Computer Vision-এর একটি কুখ্যাত quirk। শুরুতে অনেকের ছবি "নীলাভ" দেখায় — কারণ এই BGR/RGB confusion।

কেন BGR?

  • OpenCV ১৯৯৯-এ Intel-এ শুরু — তখনকার camera ও Windows BMP ফরম্যাট BGR ব্যবহার করত (little-endian RGB-র memory layout)।
  • এই historical decision আজও চলছে — backwards compatibility-র কারণে।
  • Internally — Blue first byte, Green second, Red third — যা CPU-এ একটু দ্রুত ছিল সেই যুগে।

সমস্যা যা হয়:

  • Matplotlib (RGB ধরে) এ সরাসরি দেখালে — লাল ও নীল উল্টে যায়। গাঢ় লাল গোলাপ দেখাবে নীল।
  • PIL/Pillow, TensorFlow, PyTorch — সবই RGB। OpenCV থেকে এদের পাঠানোর আগে convert করতে হয়।
  • Color-based detection (যেমন red car detect) — wrong channel-এ search করলে ফল ভুল।

সমাধান:

img = cv2.imread('photo.jpg')          # BGR
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img_rgb)                     # ঠিকঠাক দেখাবে

অন্যান্য library-র convention:

  • OpenCV: BGR (channel-last)।
  • PIL, Matplotlib, TF: RGB (channel-last)।
  • PyTorch: RGB (channel-first)।
  • Skimage: RGB।
  • DICOM (medical): grayscale বা special encoding।

মূল উপলব্ধি: Library-র convention জেনে রাখা CV engineer-এর duty। প্রথম bug প্রায়ই color channel inversion। Production code-এ সবসময় explicit convert করুন।

প্র ০৪ একটি AI মডেলে ছবি ঢুকানোর আগে আমরা pixel value 0–1 এ normalize করি। কিন্তু কখনও ImageNet mean-std subtract করি, কখনও just /255। কখন কোনটা?

Normalization choice training stability ও accuracy দু'টোতেই প্রভাব ফেলে। ভুল normalization ভাল মডেলকেও ১০-২০% accuracy কমিয়ে দিতে পারে।

(১) /255 (Min-Max scaling):

  • সব pixel 0–1 এ আসে।
  • Scratch থেকে train করলে — সাধারণত যথেষ্ট।
  • সরল, predictable, GPU-friendly।
  • ছোট dataset (CIFAR-10) ও simple architecture-এ ভাল কাজ করে।

(২) ImageNet mean-std (Z-score):

  • $x' = (x/255 - \mu) / \sigma$ যেখানে $\mu = [0.485, 0.456, 0.406]$, $\sigma = [0.229, 0.224, 0.225]$।
  • Pretrained ResNet, VGG, EfficientNet ব্যবহার করলে — অবশ্যই ব্যবহার করতে হবে। কারণ মডেলটি এই distribution-এ train হয়েছে।
  • Transfer learning-এ এটাই default।

(৩) [-1, 1] scaling:

  • $x' = (x/255) \times 2 - 1$।
  • GAN, Stable Diffusion, কিছু Vision Transformer এ standard।
  • Tanh activation-এর সাথে mathematical সামঞ্জস্য।

(৪) Custom dataset mean-std:

  • Medical imaging, satellite — ImageNet mean-std অপ্রাসঙ্গিক।
  • নিজের ডেটাসেটের mean-std হিসাব করে use করুন।

সাধারণ ভুল:

  • Pretrained মডেল ব্যবহারে /255-এ থামা — ১০% accuracy drop।
  • Inference-এ training-এর normalization apply না করা — ছবি unrecognizable।
  • Train ও validation-এ ভিন্ন normalization — silent bug।

Production tip: Normalization preprocessing pipeline-এর প্রথম step হিসেবে dataset class-এ লিখুন। Inference-এর সময় একই function ব্যবহার — train/test skew এড়াতে।

মূল উপলব্ধি: "Normalize করেছি" — যথেষ্ট না। কোন strategy কেন — বুঝতে হবে। মডেলের training distribution match করানো সর্বদা priority।

অনুশীলন

  1. Shape হিসাব করুন:
    • একটি 1080p RGB ভিডিও frame-এর shape ও মোট পিক্সেল কত?
    • একটি 4K (3840×2160) RGBA (4-channel) ছবির shape ও মেমোরি (8-bit) কত?
    • ৩২ ছবির একটি batch — প্রতিটি 224×224×3 — shape কী?
    • 1080p = 1920×1080×3, shape = $(1080, 1920, 3)$, মোট পিক্সেল = $1920 \times 1080 \times 3 = 6{,}220{,}800$।
    • 4K RGBA: shape = $(2160, 3840, 4)$, মেমোরি = $3840 \times 2160 \times 4 \approx 33$ MB।
    • Batch shape = $(32, 224, 224, 3)$ — channel-last। PyTorch-এ $(32, 3, 224, 224)$।
  2. NumPy-তে চেষ্টা: একটি 5×5 grayscale ছবি বানান যেখানে কেন্দ্রের pixel সবচেয়ে উজ্জ্বল (255) ও কোণায় কালো (0) — gradient pattern।
    import numpy as np
    
    img = np.zeros((5, 5), dtype=np.uint8)
    center = (2, 2)
    for i in range(5):
        for j in range(5):
            dist = max(abs(i - center[0]), abs(j - center[1]))
            img[i, j] = 255 - (dist * 64)
    print(img)
    # কেন্দ্রে 255, ১ ঘর দূরে 191, ২ ঘর দূরে 127
  3. ভাবুন: একটি ছবি 0–255-এর বদলে -128 থেকে +127 (signed int8) এ store করলে কী সুবিধা/অসুবিধা হবে?

    সুবিধা:

    • Mean প্রায় 0 — neural network-এ symmetric activation-এর সাথে fit।
    • Subtract operation সরাসরি; centered data → faster convergence।

    অসুবিধা:

    • Display/storage standard (PNG, JPEG) সাধারণত unsigned।
    • Conversion overhead প্রতিটি I/O-তে।
    • Human intuition: 0=কালো, 255=সাদা — সবার মুখস্থ।

    তাই storage-এ uint8, training-এ float-এ centered করা — best of both worlds।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

কোড রানার কাজ না করলে? ব্রাউজারে কাজ না করলে Google Colab ব্যবহার করুন — Google-এর ফ্রি অনলাইন Python পরিবেশ, শুধু Gmail অ্যাকাউন্ট লাগে।
কোর্স সূচি
Computer Vision সব পাঠ