RGB, HSV, grayscale — color space
এই পাঠে যা শিখবেন
- 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 আলাদা।
৪ · 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-এর কাছাকাছি দেখায়।
৭ · OpenCV-তে conversion — হাতে-কলমে
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])
৮ · Color-based detection — HSV-এর শক্তি
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।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ কেন 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:
- Vehicle detect (YOLO/Faster R-CNN) → bounding box।
- Box-এর center crop নিন — body color, side mirror বা glass বাদ।
- HSV-এ convert — color analysis।
- 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-এ থাকা চাই।
অনুশীলন
-
সূত্র প্রয়োগ: 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 -
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 একই -
ভাবুন: 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-এ আপনার পরবর্তী পদক্ষেপ
- পাঠ ০৩ · OpenCV-এ ছবি পড়া ও লেখা পরবর্তী পাঠ এবার আসল ছবি load — file থেকে tensor-এ।
- পাঠ ০১ · ছবি কীভাবে tensor হয় আগের পাঠ পিক্সেল ও channel-এ ফিরে যেতে চাইলে।
- পাঠ ০৪ · Threshold ও morphology এগিয়ে Color filter mask-এ যা শিখলেন তা apply করতে।
- সব AI Courses দেখুন ABCL TECH Python, ML, DL, NLP, CV, GenAI, RL, MLOps — সব AI কোর্স একসাথে।