পাঠ ০২ · ৩৫-এর মধ্যে · মডিউল ১
Home / AI Courses / Computer Vision / Color spaces

RGB, HSV, grayscale — color space

Color spaces — RGB, HSV, Lab, grayscale
৬ মিনিট পড়া শুরু · Beginner OpenCV কোডসহ

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

  • RGB color cube — সব রঙ কীভাবে তিন সংখ্যায়
  • HSV-এর Hue, Saturation, Value — কেন এটি মানুষের intuition-এ কাছের
  • Grayscale conversion ও তার সূত্র
  • OpenCV-এ color space conversion — হাতে-কলমে

১ · একই রঙ, ভিন্ন স্থানাঙ্ক

একটি গাঢ় কমলা রঙ — RGB-তে $(255, 165, 0)$, HSV-তে $(39°, 100\%, 100\%)$, Lab-তে $(75, 30, 80)$। সব একই রঙ — প্রকাশের ভাষা ভিন্ন। ঠিক যেমন "ঢাকা শহর" — GPS coordinate-এ, postal address-এ, বা landmark-এ ভিন্নভাবে বলা যায় — কিন্তু জায়গাটা এক।

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

Color spaceColor Spaceরঙকে গাণিতিক স্থানাঙ্কে প্রকাশের একটি system। RGB, HSV, Lab, YCbCr — প্রতিটি ভিন্ন উদ্দেশ্যে। = রঙের জন্য ৩-মাত্রিক স্থানাঙ্ক system। কাজভেদে কোন space-এ কাজ করব সেটাই গুরুত্বপূর্ণ।

২ · RGB — display-এর ভাষা

Red, Green, Blue — তিনটি additive primary। প্রতিটি 0–255। স্ক্রিনের প্রতিটি পিক্সেলে এই তিনটি সাব-পিক্সেল জ্বলে।

  • $(0, 0, 0)$ — কালো
  • $(255, 255, 255)$ — সাদা
  • $(255, 0, 0)$ — purely red
  • $(255, 255, 0)$ — হলুদ (red+green)
  • $(0, 255, 255)$ — cyan

RGB হলো hardware-এর ভাষা — camera capture ও monitor display এতেই চলে। কিন্তু "এই ছবিতে লাল pixel কত?" — এই প্রশ্নের উত্তর RGB-তে তেমন সহজ না, কারণ shadow-এ লাল R মান কম হবে।

৩ · HSV — মানুষের ভাষা

Hue (রঙের ধরন), Saturation (কতটা গভীর/ফ্যাকাশে), Value (কতটা উজ্জ্বল)। মানুষ এভাবেই রঙ ভাবে — "একটু গাঢ় গোলাপি" বা "ফ্যাকাশে নীল"।

  • Hue: 0°–360° (OpenCV-তে 0–179)। 0° = লাল, 60° = হলুদ, 120° = সবুজ, 240° = নীল।
  • Saturation: 0% = grayscale, 100% = পূর্ণ রঙ।
  • Value: 0% = কালো, 100% = উজ্জ্বল।

কেন HSV ভাল? "এই ছবিতে যেকোনো লাল object" detect করতে — RGB-তে শত শত combination check করতে হয়। HSV-তে শুধু Hue ≈ 0° বা 180°-এর কাছাকাছি — saturation ও value আলাদা।

ভাবুন একজন রং-মিস্ত্রি। সে বলে — "একটু কম গাঢ় (saturation ↓), একটু কম উজ্জ্বল (value ↓), রঙটা একই (hue same)"। RGB-তে এই কথা বলতে গেলে তিনটি সংখ্যাই বদলাতে হবে। HSV-তে শুধু S বা V বদলালেই হলো — যেভাবে মানুষ রঙ ভাবে।

৪ · Grayscale — একক চ্যানেল

Grayscale ছবি = শুধু brightness তথ্য, রঙ নেই। RGB থেকে grayscale-এ যাওয়ার standard সূত্র (ITU-R BT.601):

$$Y = 0.299 R + 0.587 G + 0.114 B$$

কেন এই weight? মানুষের চোখ green-এ সবচেয়ে sensitive (~58.7%), red-এ মাঝামাঝি (~29.9%), blue-এ কম (~11.4%)। তাই simple average-এর চেয়ে এটি বেশি "natural" দেখায়।

৫ · Lab — perceptual space

Lightness, a (green↔red), b (blue↔yellow)। Lab-এ perceptual uniformity — দু'টি রঙের মধ্যে euclidean distance ≈ মানুষের চোখে কতটা ভিন্ন দেখায়।

Color matching, photo retouching, ও কিছু segmentation algorithm-এ Lab আদর্শ। কিন্তু সংখ্যা পড়া কঠিন — RGB-র মতো intuitive না।

৬ · YCbCr — video compression

Y (luminance), Cb, Cr (chrominance)। JPEG, MPEG, H.264 — সবই YCbCr ব্যবহার করে। কারণ মানুষ luminance-এ sensitive, chrominance-এ কম — তাই Cb/Cr কে compress করেও original-এর কাছাকাছি দেখায়।

একই রঙ — চারটি color space-এ A pure orange pixel RGB display, camera (255, 165, 0) R=255 G=165 B=0 HSV color-based detection (19, 100, 100) H=19° (orange) S=100% (vivid) V=100% (bright) Lab perceptual uniform (75, 30, 80) L=75 (light) a=30 (red↔green) b=80 (blue↔yel) Grayscale brightness only 173 Y=0.299·R +0.587·G +0.114·B কাজ অনুযায়ী space বাছুন — display-এ RGB, color filter-এ HSV, perception-এ Lab
একই কমলা রঙ — চারটি color space-এ ভিন্ন সংখ্যায়। প্রতিটির আলাদা শক্তি ও use case।

৭ · OpenCV-তে conversion — হাতে-কলমে

Python · OpenCV
import cv2
import numpy as np

# একটি 1x1 BGR পিক্সেল — orange (OpenCV BGR অর্ডার)
bgr = np.uint8([[[0, 165, 255]]])   # B=0, G=165, R=255

# RGB-তে convert
rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)
print("RGB:", rgb[0, 0])

# HSV-তে convert
hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV)
print("HSV:", hsv[0, 0])           # OpenCV-তে H 0-179

# Grayscale-এ convert
gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
print("Gray:", gray[0, 0])

# Lab
lab = cv2.cvtColor(bgr, cv2.COLOR_BGR2LAB)
print("Lab:", lab[0, 0])

    
OpenCV-তে HSV-এর Hue 0–179 (8-bit fit করতে), saturation ও value 0–255। তাই OpenCV doc-এ Hue range আলাদা — মাথায় রাখবেন।

৮ · Color-based detection — HSV-এর শক্তি

Python · OpenCV
import cv2
import numpy as np

# একটি ছোট test ছবি বানাই (red, green, blue patches)
img = np.zeros((100, 300, 3), dtype=np.uint8)
img[:, 0:100] = [0, 0, 255]        # red (BGR)
img[:, 100:200] = [0, 255, 0]      # green
img[:, 200:300] = [255, 0, 0]      # blue

# HSV-এ যাই
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# শুধু লাল pixel মাস্ক করি
lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])
mask = cv2.inRange(hsv, lower_red, upper_red)

print("Red pixel count:", np.count_nonzero(mask))
print("Total pixel:", mask.size)

    
cv2.inRange() একটি binary mask দেয় — যেখানে color condition match, সেখানে 255; বাকি 0। এটিই color-based object segmentation-এর ভিত্তি।

৯ · কোন space কখন

  • RGB: display, deep learning input, general processing।
  • HSV/HSL: color filter, traffic light detection, skin detection, fruit ripeness।
  • Lab: color correction, white balance, perceptual operation।
  • Grayscale: edge detection, OCR, low-power processing।
  • YCbCr: video coding, JPEG-এর internal।
OpenCV-তে BGR convention — মনে রাখুন। অন্য library থেকে আসা ছবি RGB-তে হতে পারে। প্রথম bug প্রায়ই color inversion।

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

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

প্র ০১ কেন HSV-তে red color দু'টি range লাগে — 0–10 এবং 170–179? কী সমস্যা ঘটছে?

এটি HSV-এর সবচেয়ে চেনা pitfall। Hue একটি circular coordinate — 0° এবং 360° একই বিন্দু (লাল)।

সমস্যা:

  • Hue circle-এ লাল 0° এ বসে। হালকা কমলা 10°, গাঢ় লাল 359°।
  • OpenCV 8-bit-এ Hue 0–179 (180 = 360°/2)।
  • লাল range = ~ 350°–10° (circular) → OpenCV-তে 175–179 ও 0–10।
  • একটি linear range-এ এই circular wrap হ্যান্ডল করা যায় না — তাই দু'টি range লাগে।

সমাধান:

mask1 = cv2.inRange(hsv, (0, 100, 100), (10, 255, 255))
mask2 = cv2.inRange(hsv, (170, 100, 100), (179, 255, 255))
red_mask = cv2.bitwise_or(mask1, mask2)

অন্য রঙে এই সমস্যা নেই কেন? Yellow (~30°), green (~60°), blue (~120°) — সবই circle-এর মাঝে — wrap হয় না। শুধু লাল 0°/360°-এ বসে বলেই।

মূল উপলব্ধি: Hue circular — এই geometry মাথায় রাখলে অনেক বাগ এড়ানো যায়। Cyclic data (angle, time-of-day) ML-এও common — sin/cos encoding ব্যবহৃত।

প্র ০২ Grayscale conversion-এ green-এর weight 0.587 — সবচেয়ে বেশি। মানুষের চোখ কেন green-এ এত sensitive? এটি AI-তে কী implication আনে?

এটি বিবর্তনের গল্প। মানুষের retina-এ ৩ ধরনের cone photoreceptor — S (short, blue), M (medium, green), L (long, red)। M ও L cone overlap করে — দু'টোই green-এর কাছে peak করে।

কেন green dominant?

  • আমাদের ancestors গাছপালার মাঝে বাস করত — green-এ subtle পার্থক্য বোঝা (পাকা ফল vs কাঁচা) survival-এর জন্য জরুরি ছিল।
  • সূর্যের peak emission ~550nm — green-এর কাছে। চোখ এই wavelength-এ optimized।
  • মোট cones-এর প্রায় 64% L+M (red+green sensitive), 2% blue।

AI-তে implication:

  • Bayer filter: camera sensor-এ 2 green, 1 red, 1 blue (RGGB pattern) — green double sample।
  • JPEG compression: green channel-এ কম compression — perceptual loss কম।
  • CNN training: ImageNet-এর pretrained মডেল RGB ধরে — green channel-এ feature বেশি হতে পারে।
  • Medical imaging: পুরো ভিন্ন — Bayer-এর বদলে monochrome high-bit, কারণ tissue contrast green-এ optimized না।

Color blindness: ৮% পুরুষ, ০.৫% নারী — সাধারণত red-green confusion (M বা L cone defect)। UI design-এ কেবল রঙে info দেওয়া অনুচিত।

মূল উপলব্ধি: Vision system biology-নির্ভর। CV-এর সব sensor, codec, normalization — মানুষের চোখের সীমা ও pattern-কে exploit করে। এই biology জানলে algorithm choice intuitive হয়।

প্র ০৩ একটি smart traffic camera কালো/সাদা/কমলা গাড়ি গণনা করে। আপনি কোন color space-এ কাজ করবেন? কী সমস্যা প্রত্যাশিত?

Color-based vehicle classification — practical CV problem। সরাসরি RGB threshold কাজ করে না — lighting condition বদলালে।

প্রস্তাবিত pipeline:

  1. Vehicle detect (YOLO/Faster R-CNN) → bounding box।
  2. Box-এর center crop নিন — body color, side mirror বা glass বাদ।
  3. HSV-এ convert — color analysis।
  4. Hue, Saturation, Value-এর histogram বিশ্লেষণ।

রঙভিত্তিক rule:

  • সাদা: V > 200, S < 30 (any hue, low sat, high value)।
  • কালো: V < 50 (any hue, low value)।
  • কমলা: H ∈ [10, 25], S > 100, V > 100।

সমস্যা যা প্রত্যাশিত:

  • Lighting variability: দিনের আলো, সন্ধ্যা, রাতের headlight — সাদা গাড়ি হলুদাভ দেখাবে।
  • Shadow: আংশিক ছায়ায় কালো ও গাঢ় নীল indistinguishable।
  • Reflection: চকচকে paint চারপাশের রঙ ফেলে — কমলা গাড়ি asphalt-এ ধূসর দেখাতে পারে।
  • Glare: camera sensor saturate — V=255 everywhere।
  • Color cast: sodium street light-এ সব হলুদাভ, LED-তে নীলাভ।

সমাধান কৌশল:

  • White balance correction: reference white neutralize করুন।
  • Lab space: L (lightness) আলাদা করে শুধু a, b দেখুন।
  • CNN-based color classifier: rule-based-এর বদলে — ResNet head retrain।
  • Multi-frame averaging: একই গাড়ি ১০ frame-এ track করে color majority vote।

Production reality: বড় system-এ সাধারণত color rule + CNN ensemble — speed ও accuracy-এর balance।

মূল উপলব্ধি: Pure color-space rule academic data-তে কাজ করে, real world-এ ভাঙে। CV deployment-এ environmental factor সবচেয়ে বড় চ্যালেঞ্জ।

প্র ০৪ Deep Learning-এ কেন বেশিরভাগ ছবি RGB-তে train হয়, HSV বা Lab-এ না? CNN নিজেই কি color space "শিখে" নেয়?

এটি একটি গভীর প্রশ্ন। Classical CV-তে color space matters — কিন্তু DL-এ মাঝেমধ্যে অপ্রাসঙ্গিক। কারণ আছে।

কেন RGB default:

  • Hardware native: camera/display RGB ধরে — extra conversion overhead নেই।
  • Linear transformation: RGB → HSV/Lab non-linear। CNN-এর প্রথম conv layer linear ও non-linear উভয় function approximate করতে পারে — তাই internal-এ space আলাদা করে শেখে।
  • Pretrained models: ImageNet RGB — সব weights সেখানে।
  • Implementation simplicity: data pipeline complexity কম।

CNN কি color space শিখে?

  • প্রথম conv layer-এর filter visualize করলে — কিছু filter color-blob detect করে, কিছু edge। মানে — color দ্বারা separate filter-ই learn হয়।
  • BatchNorm channel-wise normalize — অনেকটা Lab-এর L আলাদা করার মতো effect।
  • তবে CNN "complete" HSV transformation reproduce করে না — যা জরুরি না সেটাই শেখে।

কখন HSV/Lab আগে convert কাজে আসে?

  • Small dataset (< 1K images): hand-crafted feature সাহায্য করে।
  • Specific task: skin detection — HSV আগে কাজ করলে training fast।
  • Compute-constrained: mobile/edge device — preprocessing দিয়ে complexity কমানো।
  • Domain-specific: medical (Lab), satellite (multi-spectral, NDVI) — RGB যথেষ্ট না।

Multi-channel input: কখনো ৬-channel input দেওয়া হয় — RGB + HSV concat — যাতে CNN দু'টি view-ই পায়। কিছু paper-এ এতে accuracy বাড়ে।

মূল উপলব্ধি: "RGB যথেষ্ট" — কারণ DL implicit feature learning করে। কিন্তু explicit color space হাতে-কলমে কাজে লাগানো — যখন data কম বা domain specific। দু'টোই tool-এ থাকা চাই।

অনুশীলন

  1. সূত্র প্রয়োগ: RGB $(180, 90, 60)$ — গ্রে ভ্যালু কত হবে (BT.601 সূত্র)? নিজে হিসাব করে তারপর NumPy দিয়ে যাচাই করুন।

    $Y = 0.299 \times 180 + 0.587 \times 90 + 0.114 \times 60 = 53.82 + 52.83 + 6.84 = 113.49 \approx 113$

    import cv2, numpy as np
    bgr = np.uint8([[[60, 90, 180]]])  # BGR অর্ডার
    gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
    print(gray[0,0])  # ~113
  2. OpenCV-তে চেষ্টা: একটি sky-blue patch বানান, তার HSV value print করুন। তারপর HSV-তে শুধু V বাড়িয়ে আবার BGR-এ ফেরত — কেমন দেখাবে?
    import cv2, numpy as np
    img = np.full((100,100,3), [235,206,135], dtype=np.uint8)  # BGR sky
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    print("HSV:", hsv[0,0])
    hsv[:,:,2] = np.clip(hsv[:,:,2]*1.3, 0, 255)
    brighter = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    # brighter আগের চেয়ে উজ্জ্বল কিন্তু hue একই
  3. ভাবুন: JPEG-এ chrominance subsampling 4:2:0 — মানে Cb/Cr resolution অর্ধেক। কেন এটি acceptable, কখন এটি visible artifact দেয়?

    চোখ luminance-এ বেশি sensitive, color-এ কম। তাই color-এ resolution কমানো — perceptual loss সামান্য, file size half।

    সমস্যা যেখানে: শার্প red-blue text, gradient, fine color edge — Cb/Cr blur দেখায়। তাই chroma-heavy graphic-এ JPEG না, PNG ব্যবহার।

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

কোড রানার কাজ না করলে? ব্রাউজারে কাজ না করলে Google Colab ব্যবহার করুন — Google-এর ফ্রি অনলাইন Python পরিবেশ, শুধু Gmail অ্যাকাউন্ট লাগে।
পূর্ববর্তী পাঠ
পাঠ ০১ · ছবি কীভাবে tensor হয়