অধ্যায়Phase 3 · ক্লাসিক্যাল কম্পিউটার ভিশন
3.1 12 মিনিট পড়া

Contours ও Shape Detection

Object boundary বের করা।

🎬 গল্প দিয়ে শুরু
একটি কয়েন কয়টি? কাগজের shape কেমন? Defect-এর area কত pixel? — এই সব প্রশ্নের উত্তর দেয় Contour। Binary image-এর প্রতিটি object-এর সীমানা।

Contour কী?

Contour = same-intensity-এর pixel-গুলোর continuous boundary curve। সাধারণত binary mask-এ object-এর বাইরের সীমা।

python
contours.py
import cv2

img  = cv2.imread("coins.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7,7), 0)
_, th = cv2.threshold(blur, 0, 255,
                      cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

contours, hierarchy = cv2.findContours(
    th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

print("Total objects:", len(contours))
cv2.drawContours(img, contours, -1, (0,255,0), 2)
cv2.imwrite("out.jpg", img)
Retrieval mode
RETR_EXTERNAL — শুধু বাইরের contour। RETR_TREE — nested সম্পর্ক সহ সব। CHAIN_APPROX_SIMPLE — কম point store করে memory বাঁচায়।

Contour Properties

python
import cv2

for c in contours:
    area  = cv2.contourArea(c)
    peri  = cv2.arcLength(c, True)
    x,y,w,h = cv2.boundingRect(c)
    (cx,cy), r = cv2.minEnclosingCircle(c)
    rect = cv2.minAreaRect(c)                # rotated rect

    if area < 200:           # noise filter
        continue

    aspect = w / h
    extent = area / (w*h)    # bounding box-এর কত % ভরা

Shape Approximation

python
import cv2

for c in contours:
    peri   = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02 * peri, True)
    sides  = len(approx)

    if   sides == 3: name = "Triangle"
    elif sides == 4: name = "Square/Rect"
    elif sides == 5: name = "Pentagon"
    else:            name = "Circle/Other"
Document scanner-এর গোপন
কাগজ detect করতে — Canny → contour → approxPolyDP → ৪ কোণার rectangle। এটিই CamScanner-এর core algorithm।

Convex Hull ও Defects

python
import cv2

hull = cv2.convexHull(c)
cv2.drawContours(img, [hull], -1, (255,0,0), 2)

# Hand gesture recognition-এর জন্য defect points
hull_idx = cv2.convexHull(c, returnPoints=False)
defects  = cv2.convexityDefects(c, hull_idx)

Practical — কয়েন count + size estimate

python
import cv2

count = 0
for c in contours:
    a = cv2.contourArea(c)
    if a < 500: continue
    count += 1
    (x,y), r = cv2.minEnclosingCircle(c)
    cv2.circle(img, (int(x),int(y)), int(r), (0,255,0), 2)
    cv2.putText(img, str(count), (int(x)-10,int(y)+5),
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,0,255), 2)
print("Total coins:", count)
প্র্যাকটিস টাস্ক
  1. একটি কাগজে আঁকা shape (square, triangle, circle) photo থেকে detect ও label করুন।
  2. Conveyor belt-এ পড়া বোতল count করার script লিখুন।
  3. ID card-এর ৪ কোণা detect করে perspective transform করে scan-look তৈরি করুন।

সারসংক্ষেপ

  • Contour = binary mask-এর object boundary।
  • findContours-এর আগে Otsu/adaptive threshold + cleanup ভালো।
  • Area, perimeter, bounding box, hull → shape analysis।
  • approxPolyDP দিয়ে polygon shape চিনে document/object scanning।