# Computer Vision

> When to activate: computer vision, OpenCV, YOLO, YOLOv8, object detection, segmentation, albumentations, OCR, image classification

- Skill: `mattakushi432/computer-vision` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mattakushi432/computer-vision`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mattakushi432/computer-vision/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Mattakushi432 (https://skillmd.com/u/mattakushi432)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mattakushi432/computer-vision

---

# Computer Vision Patterns

## OpenCV Essentials

```python
import cv2
import numpy as np

img = cv2.imread("image.jpg")               # BGR, not RGB
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Resize preserving aspect ratio
h, w = img.shape[:2]
scale = 640 / max(h, w)
resized = cv2.resize(img, (int(w * scale), int(h * scale)), interpolation=cv2.INTER_AREA)

# Gaussian blur + Canny edges
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blurred, threshold1=50, threshold2=150)

# Draw bounding box
x, y, bw, bh = 100, 50, 200, 150
cv2.rectangle(img, (x, y), (x + bw, y + bh), color=(0, 255, 0), thickness=2)
cv2.putText(img, "Label 0.92", (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
```

## YOLOv8 Training & Inference

```python
from ultralytics import YOLO

# Training
model = YOLO("yolov8n.pt")  # nano backbone
results = model.train(
    data="dataset.yaml",
    epochs=100,
    imgsz=640,
    batch=16,
    device=0,
    project="runs/detect",
    name="exp1",
    patience=20,
    augment=True,
)

# Inference
model = YOLO("runs/detect/exp1/weights/best.pt")
results = model.predict("test.jpg", conf=0.4, iou=0.5, save=True)

for r in results:
    for box in r.boxes:
        cls = int(box.cls[0])
        conf = float(box.conf[0])
        xyxy = box.xyxy[0].tolist()
        print(f"Class {cls} ({conf:.2f}): {xyxy}")
```

## YOLOv8 dataset.yaml

```yaml
path: /data/my_dataset
train: images/train
val: images/val
test: images/test

nc: 3
names: ["cat", "dog", "bird"]
```

## Albumentations Augmentation Pipeline

```python
import albumentations as A
from albumentations.pytorch import ToTensorV2

train_transform = A.Compose([
    A.RandomResizedCrop(640, 640, scale=(0.5, 1.0)),
    A.HorizontalFlip(p=0.5),
    A.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1, p=0.5),
    A.GaussNoise(var_limit=(10.0, 50.0), p=0.3),
    A.MotionBlur(blur_limit=5, p=0.2),
    A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
    ToTensorV2(),
], bbox_params=A.BboxParams(format="yolo", label_fields=["class_labels"]))

val_transform = A.Compose([
    A.Resize(640, 640),
    A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
    ToTensorV2(),
])
```

## Segmentation (SAM)

```python
from segment_anything import SamPredictor, sam_model_registry

sam = sam_model_registry["vit_h"](checkpoint="sam_vit_h.pth")
sam.to("cuda")
predictor = SamPredictor(sam)

predictor.set_image(img_rgb)
masks, scores, _ = predictor.predict(
    point_coords=np.array([[500, 375]]),
    point_labels=np.array([1]),   # 1=foreground
    multimask_output=True,
)
best_mask = masks[scores.argmax()]
```

## OCR with EasyOCR

```python
import easyocr

reader = easyocr.Reader(["en"], gpu=True)
results = reader.readtext("document.jpg")

for (bbox, text, confidence) in results:
    if confidence > 0.5:
        print(f"{text!r} ({confidence:.2f})")
```

## CLIP Zero-Shot Classification

```python
import torch
from PIL import Image
import open_clip

model, _, preprocess = open_clip.create_model_and_transforms("ViT-B-32", pretrained="openai")
tokenizer = open_clip.get_tokenizer("ViT-B-32")
model.eval()

image = preprocess(Image.open("photo.jpg")).unsqueeze(0)
labels = ["a cat", "a dog", "a bird"]
text = tokenizer(labels)

with torch.no_grad():
    img_feat = model.encode_image(image)
    txt_feat = model.encode_text(text)
    img_feat /= img_feat.norm(dim=-1, keepdim=True)
    txt_feat /= txt_feat.norm(dim=-1, keepdim=True)
    probs = (100 * img_feat @ txt_feat.T).softmax(dim=-1)

for label, prob in zip(labels, probs[0]):
    print(f"{label}: {prob:.2%}")
```

## Key Patterns

- Always normalize with ImageNet mean/std when using pretrained backbones
- Use `cv2.INTER_AREA` for downscaling, `cv2.INTER_LANCZOS4` for upscaling
- For detection fine-tuning: freeze backbone for first 10 epochs, then unfreeze
- Mosaic augmentation (YOLOv8 default) improves small object detection significantly

