| name | computer-vision-developer |
| description | Hands-on computer vision development covering image classification with transfer learning, object detection with YOLO and Faster R-CNN, semantic and instance segmentation, OpenCV image processing, data augmentation strategies, model optimization for edge deployment, video processing, and metrics for measuring model performance.
Use when the user asks about computer vision developer, computer vision developer best practices, or needs guidance on computer vision developer implementation.
Do NOT use when the user needs a different specialized skill or is asking about an unrelated technology domain.
|
| license | Apache-2.0 |
| metadata | {"author":"foundry-skills","version":"1.0.0","tags":"ai-ml deep-learning guide","category":"ai-machine-learning","subcategory":"applied-ai","depends":"","disclaimer":"none","difficulty":"intermediate"} |
Computer Vision Developer
Overview
Computer vision development involves building systems that extract meaningful information from images and video. This skill covers practical implementation of core CV tasks: classification, detection, segmentation, and image processing. The focus is on production-ready code using modern frameworks (PyTorch, YOLO, OpenCV), with emphasis on data preparation, training strategies, measuring results, and deployment optimization.
Image Classification
Transfer Learning Pipeline
import torch
import torch.nn as nn
from torchvision import models, transforms
from torch.utils.data import DataLoader, Dataset
train_transform = transforms.Compose([
transforms.RandomResizedCrop(224, scale=(0.8, 1.0)),
transforms.RandomHorizontalFlip(),
transforms.RandomRotation(15),
transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),
transforms.RandomAffine(degrees=0, translate=(0.1, 0.1)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
transforms.RandomErasing(p=0.1),
])
val_transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
class CustomClassifier(nn.Module):
def __init__(self, num_classes, freeze_backbone=True):
super().__init__()
self.backbone = models.efficientnet_v2_s(weights='IMAGENET1K_V1')
if freeze_backbone:
for param in self.backbone.parameters():
param.requires_grad = False
in_features = self.backbone.classifier[1].in_features
self.backbone.classifier = nn.Sequential(
nn.Dropout(p=0.3),
nn.Linear(in_features, 512),
nn.ReLU(),
nn.Dropout(p=0.2),
nn.Linear(512, num_classes),
)
def forward(self, x):
return self.backbone(x)
def unfreeze_backbone(self, num_layers=3):
"""Gradually unfreeze backbone layers for fine-tuning."""
layers = list(self.backbone.features.children())
for layer in layers[-num_layers:]:
for param in layer.parameters():
param.requires_grad = True
Training Loop with Best Practices
def train_classifier(model, train_loader, val_loader, num_epochs=30):
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device)
optimizer = torch.optim.AdamW(
filter(lambda p: p.requires_grad, model.parameters()),
lr=1e-3, weight_decay=1e-4
)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=10)
criterion = nn.CrossEntropyLoss(label_smoothing=0.1)
best_val_acc = 0
patience = 5
patience_counter = 0
for epoch in range(num_epochs):
if epoch == 10:
model.unfreeze_backbone(num_layers=3)
optimizer = torch.optim.AdamW([
{'params': model.backbone.features.parameters(), 'lr': 1e-5},
{'params': model.backbone.classifier.parameters(), 'lr': 1e-4},
], weight_decay=1e-4)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=20)
model.train()
running_loss = 0
correct = 0
total = 0
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=)
optimizer.step()
running_loss += loss.item()
_, predicted = outputs.()
total += labels.size()
correct += predicted.eq(labels).().item()
scheduler.step()
val_acc = measure_accuracy(model, val_loader, device)
(
)
val_acc > best_val_acc:
best_val_acc = val_acc
torch.save(model.state_dict(), )
patience_counter =
:
patience_counter +=
patience_counter >= patience:
()
Object Detection with YOLO
YOLOv8 Training and Inference
from ultralytics import YOLO
model = YOLO('yolov8m.pt')
results = model.train(
data='dataset.yaml',
epochs=100,
imgsz=640,
batch=16,
patience=20,
optimizer='AdamW',
lr0=0.001,
lrf=0.01,
warmup_epochs=3,
augment=True,
mosaic=1.0,
mixup=0.1,
close_mosaic=10,
device='0',
project='runs/detect',
name='custom-detector',
)
model = YOLO('runs/detect/custom-detector/weights/best.pt')
results = model.predict(
source='test_images/',
conf=0.25,
iou=0.45,
max_det=100,
save=True,
save_txt=True,
)
for result in results:
boxes = result.boxes
box boxes:
x1, y1, x2, y2 = box.xyxy[].tolist()
confidence = box.conf[].item()
class_id = (box.cls[].item())
class_name = model.names[class_id]
()
Dataset Configuration
path: /data/my_dataset
train: images/train
val: images/val
test: images/test
nc: 5
names:
0: car
1: truck
2: pedestrian
3: bicycle
4: traffic_sign
Image Segmentation
Semantic Segmentation with SegFormer
from transformers import SegformerForSemanticSegmentation, SegformerImageProcessor
import torch
import numpy as np
class SemanticSegmentor:
def __init__(self, model_name="nvidia/segformer-b2-finetuned-cityscapes-1024-1024"):
self.processor = SegformerImageProcessor.from_pretrained(model_name)
self.model = SegformerForSemanticSegmentation.from_pretrained(model_name)
def segment(self, image):
"""Segment image and return per-pixel class labels."""
inputs = self.processor(images=image, return_tensors="pt")
with torch.no_grad():
outputs = self.model(**inputs)
logits = outputs.logits
upsampled = torch.nn.functional.interpolate(
logits,
size=image.size[::-1],
mode='bilinear',
align_corners=False,
)
seg_map = upsampled.argmax(dim=1).squeeze().numpy()
return seg_map
def overlay_segmentation(self, image, seg_map, alpha=0.5):
"""Create colored overlay of segmentation on original image."""
color_map = self._get_color_map()
colored_seg = color_map[seg_map]
overlay = (np.array(image) * (1 - alpha) + colored_seg * alpha).astype(np.uint8)
return overlay
OpenCV Image Processing
Common Operations
import cv2
import numpy as np
class ImageProcessor:
"""Production image processing pipeline with OpenCV."""
def preprocess_for_model(self, image_path, target_size=(640, 640)):
"""Standard preprocessing pipeline."""
img = cv2.imread(image_path)
if img is None:
raise ValueError(f"Cannot read image: {image_path}")
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_resized = self.letterbox_resize(img_rgb, target_size)
img_normalized = img_resized.astype(np.float32) / 255.0
return img_normalized
def letterbox_resize(self, image, target_size, fill_color=(114, 114, 114)):
"""Resize with padding to maintain aspect ratio."""
h, w = image.shape[:2]
target_h, target_w = target_size
scale = min(target_w / w, target_h / h)
new_w, new_h = int(w * scale), int(h * scale)
resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_LINEAR)
canvas = np.full((target_h, target_w, 3), fill_color, dtype=np.uint8)
top = (target_h - new_h) // 2
left = (target_w - new_w) // 2
canvas[top:top + new_h, left:left + new_w] = resized
canvas
():
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (, ), )
edges = cv2.Canny(blurred, low_threshold, high_threshold)
edges
():
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, , , cv2.THRESH_BINARY + cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(
thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
[c c contours cv2.contourArea(c) >= min_area]
():
dst_points = np.float32([
[, ], [dst_size[], ],
[dst_size[], dst_size[]], [, dst_size[]]
])
matrix = cv2.getPerspectiveTransform(
np.float32(src_points), dst_points
)
cv2.warpPerspective(image, matrix, dst_size)
Data Augmentation Strategies
Augmentation by Task Type
Task Recommended Augmentations Avoid
---------------------------------------------------------------------------
Classification RandomCrop, Flip, ColorJitter, Aggressive geometric
Rotation, RandomErasing, transforms that change
Mixup, CutMix class semantics
Object Detection Mosaic, RandomScale, Flip, Transforms that move
HSV augmentation, Copy-Paste objects off-frame without
updating labels
Segmentation Elastic transform, RandomCrop, Transforms that create
Flip, Scale, ColorJitter ambiguous boundaries
Medical Imaging Rotation, Elastic deformation, Aggressive color jitter
Flip (if anatomically valid), (colors carry meaning),
Intensity normalization Flips that change anatomy
OCR/Document Perspective transform, slight Heavy rotation,
rotation, noise, blur color changes
Model Optimization for Deployment
ONNX Export and Quantization
import torch
import onnx
from onnxruntime.quantization import quantize_dynamic, QuantType
dummy_input = torch.randn(1, 3, 640, 640)
torch.onnx.export(
model,
dummy_input,
"model.onnx",
opset_version=17,
input_names=['input'],
output_names=['output'],
dynamic_axes={'input': {0: 'batch_size'}, 'output': {0: 'batch_size'}},
)
onnx_model = onnx.load("model.onnx")
onnx.checker.check_model(onnx_model)
quantize_dynamic(
"model.onnx",
"model_quantized.onnx",
weight_type=QuantType.QInt8,
)
import os
original_size = os.path.getsize("model.onnx") / 1e6
quantized_size = os.path.getsize("model_quantized.onnx") / 1e6
print(f"Original: {original_size:.1f}MB, Quantized: {quantized_size:.1f}MB")
print(f"Compression ratio: {original_size / quantized_size:.1f}x")
Performance Metrics
Metrics by Task
Classification:
- Accuracy, Precision, Recall, F1-Score
- Confusion Matrix
- Top-k Accuracy (for many classes)
- AUC-ROC (binary)
Object Detection:
- mAP@0.5 (IoU threshold 0.5)
- mAP@0.5:0.95 (COCO metric, averaged over IoU 0.5 to 0.95)
- Precision-Recall curve per class
- Inference FPS
Segmentation:
- mIoU (mean Intersection over Union)
- Pixel Accuracy
- Dice Coefficient (F1 for segmentation)
- Boundary F1 Score
Video Processing
class VideoProcessor:
"""Process video frames with detection model."""
def process_video(self, video_path, model, output_path, skip_frames=1):
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
writer = cv2.VideoWriter(
output_path, cv2.VideoWriter_fourcc(*'mp4v'),
fps / skip_frames, (width, height)
)
frame_count = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
if frame_count % skip_frames == 0:
results = model.predict(frame, conf=0.25, verbose=False)
annotated = results[0].plot()
writer.write(annotated)
frame_count += 1
cap.release()
writer.release()
CV Development Checklist
Data:
[ ] Collected diverse, representative training data
[ ] Labels verified by domain expert (spot-check 5%)
[ ] Train/val/test split with no data leakage
[ ] Augmentation strategy appropriate for task
[ ] Class distribution analyzed and addressed
Training:
[ ] Transfer learning from relevant pretrained model
[ ] Learning rate finder or known-good schedule
[ ] Early stopping to prevent overfitting
[ ] Multi-scale training for detection/segmentation
[ ] Training monitored with loss curves and metrics
Assessment:
[ ] Tested on held-out test set (never seen during training)
[ ] Per-class metrics analyzed (not just average)
[ ] Failure cases visually inspected
[ ] Performance tested on edge cases
[ ] Speed benchmarked (FPS on target hardware)
Deployment:
[ ] Model exported to ONNX or TensorRT
[ ] Quantization applied if latency-critical
[ ] Input preprocessing matches training pipeline exactly
[ ] Confidence thresholds tuned for production use case
[ ] Monitoring for prediction distribution shifts
When to Use
Use this skill when:
- Designing or implementing computer vision developer solutions
- Reviewing or improving existing computer vision developer approaches
- Making architectural or implementation decisions about computer vision developer
- Learning computer vision developer patterns and best practices
- Troubleshooting computer vision developer-related issues
Do NOT use this skill when:
- The question is about a fundamentally different technology domain
- A more specific sibling skill covers the exact topic needed
- The user needs a complete hands-on tutorial rather than expert guidance
Output Format
# Computer Vision Developer Analysis
## Context Assessment
[Situation summary and constraints]
## Recommended Approach
[Primary recommendation with rationale]
## Implementation Steps
1. [Step with specific details]
2. [Step with specific details]
3. [Step with specific details]
## Trade-offs and Considerations
- [Key trade-off 1]
- [Key trade-off 2]
## Next Steps
- [Immediate action item]
- [Follow-up action item]
Example
Input: "Help me implement computer vision developer for a medium-scale production application"
Output: A structured analysis covering current state assessment, recommended computer vision developer approach with specific patterns, implementation roadmap with milestones, and risk mitigation strategies tailored to the application scale and constraints.
Edge Cases
- Legacy system integration: When computer vision developer must coexist with legacy approaches, provide a gradual migration path rather than a complete rewrite
- Scale mismatch: When the solution complexity exceeds the project scale, recommend a simpler approach and note when to revisit
- Team skill gaps: When the team lacks experience with the recommended approach, include learning resources and simpler alternatives
- Conflicting requirements: When constraints conflict (e.g., performance vs. maintainability), explicitly state the trade-off and recommend based on stated priorities