Sink Mark Defect Detection for Chair Seats (Small Data)
Practical guide to sink marks defect detection on chair seats using classical CV and anomaly detection. Works with very small datasets (15 normal, 3 defects).
How to detect sink mark defects on chair seats using computer vision with a very small dataset?
I have a limited dataset: 15 images of good chair seats and only 3 images with sink mark defects (surface depressions). Sink marks always appear in the same fixed region of the chair seat.
Goal: Binary classification to detect if a sink mark defect is present (yes/no only, no localization or segmentation required).
Constraints: Avoid supervised deep learning (e.g., CNNs) due to limited defect samples; prefer classical or unsupervised computer vision methods.
What image processing or computer vision techniques are suitable for reliable sink mark detection under these conditions?
Detect sink marks on chair seats by treating the problem as an anomaly-detection task: crop the fixed ROI, normalize lighting and texture, extract classical descriptors (LBP, HOG, gradient/edge statistics) and train an Isolation Forest or One‑Class SVM on tiles from the 15 good images; optionally add a reconstruction autoencoder as a second anomaly score and calibrate thresholds using augmented versions of the 3 defect images. Tile the ROI (128–256 px, 25–50% overlap), score each tile, and mark the image defective if any tile’s anomaly score exceeds a tuned threshold — this avoids supervised CNNs while remaining robust to subtle depressions.
Contents
- Sink mark defect detection — problem & constraints
- Capture & preprocessing for subtle sink marks
- Classical defect detection approaches (LBP, HOG, gradients)
- Unsupervised anomaly detection: Isolation Forest, One‑Class SVM, Autoencoders
- Making the most of 3 defect images (augmentation & synthetic overlays)
- Inference tactics: tiling, score aggregation, thresholding
- Validation, metrics & deployment with tiny positives
- When to consider a small CNN / transfer learning (optional)
- Compact code example (Python + OpenCV + scikit-learn)
- Practical checklist & troubleshooting
- Sources
- Conclusion
Sink mark defect detection — problem & constraints
You have a tight but advantageous setup: sink marks always occur in the same, fixed seat region (so you can crop to an ROI), and the task is binary (yes/no). With only 3 defective images, standard supervised CNN training will overfit — avoid that. Instead, learn what “normal” looks like from the 15 good images, and flag deviations with anomaly detection or reconstruction-based methods. Industry practice for tiny-defect problems favors classical features + anomaly models or reconstruction models trained on normals rather than end-to-end supervised CNNs (see practical guides and reviews linked below) — a pragmatic and explainable route.
Capture & preprocessing for subtle sink marks
Good capture and preprocessing make or break detection for tiny surface depressions.
-
Camera and lighting
-
Fix camera pose and distance. Mount the camera on a jig or tripod so the ROI lines up pixel-to-pixel across images.
-
Use consistent lighting. If possible, add raking (oblique) light to exaggerate shallow depressions; polarizers can reduce specular highlights.
-
Higher resolution in the fixed ROI helps — more pixels over the same physical area makes subtle texture/shading differences detectable.
-
ROI alignment & cropping
-
Create a fixed mask or use template matching / simple homography to align and crop the same seat region every image. That reduces variance and focuses the model on the defect area.
-
Preprocessing pipeline (example order)
- Crop to ROI.
- Convert to grayscale (or work in luminosity channel).
- Denoise lightly (Gaussian sigma 0.5–1.5).
- Illumination normalization: apply CLAHE or subtract a low-frequency background estimate (morphological opening or a rolling-ball filter) to remove slow lighting gradients.
- Enhance local contrast: top-hat / black-hat morphological filters help highlight indentations; a Laplacian or Sobel magnitude image exposes small shading changes.
- Optionally apply a band-pass filter (high-pass / unsharp mask) to emphasize fine details.
These steps reduce capture noise and surface reflectance effects so the anomaly model sees consistent normal patterns. For ROI-focused defect work, preprocessing and alignment are as important as the detection model itself (see applied reviews and industry notes below).
Classical defect detection approaches (LBP, HOG, gradients)
Classical texture and gradient descriptors are compact, interpretable, and work well with few defect examples.
-
Texture descriptors
-
LBP (Local Binary Patterns): captures micro-texture. Use uniform LBP with P=8, R=1 and histogram normalization; LBP histograms per tile are strong cues for surface irregularities.
-
GLCM (gray-level co-occurrence matrix): contrast, homogeneity, energy, correlation — useful if material texture is regular.
-
Gradient / shape descriptors
-
HOG (Histogram of Oriented Gradients): picks up subtle directional shading and edge structure generated by small depressions. Typical params: orientations=9, pixels_per_cell=(16,16), cells_per_block=(2,2).
-
Edge density and gradient magnitude: compute mean and variance of Sobel magnitude, or normalize Canny edge counts by tile area.
-
Frequency / multi-scale
-
Wavelet or DCT coefficients sometimes reveal anomalies that aren’t obvious spatially.
-
Gabor filters for orientation-selective responses if sink marks have a directional component.
-
Feature aggregation
-
Build a per-tile feature vector by concatenating LBP histogram + HOG vector + simple stats (mean, std of gradients, edge count, brightness). Reduce dimensionality with PCA or a robust scaler before anomaly modeling.
Why this helps: these features are low-dimensional and robust to small datasets. Roboflow and other practitioners explicitly recommend combining LBP/HOG-style descriptors with unsupervised detectors for subtle defects.
Unsupervised anomaly detection: Isolation Forest, One‑Class SVM, Autoencoders
Three practical classes of unsupervised models work here:
-
Isolation Forest
-
Fast, non-parametric. Fit on feature vectors from tiles extracted across the 15 normal images. Good default: n_estimators=100–200, contamination tuned via validation (start tiny, e.g., 0.01).
-
Outputs an anomaly score per tile; use max or a high percentile across tiles for image-level decision.
-
One‑Class SVM
-
Works on feature vectors or PCA-reduced features. Choose RBF kernel with nu ≈ 0.01–0.05; gamma set to ‘scale’ or 1/(n_features * var). Sensitive to scaling — use StandardScaler.
-
Autoencoders / convolutional autoencoders
-
Train reconstruction models on normal tiles only. Tiles reconstruct well when normal; defects produce higher reconstruction error. With 15 images you must boost sample count via tiling (see below) and keep networks small to avoid memorization.
-
Use L2 reconstruction error per tile; again aggregate scores to an image-level statistic.
Practical ensemble
- Combine an Isolation Forest on classical features with an autoencoder reconstruction score; normalize both scores (z-score) and average or require both to exceed thresholds to reduce false positives.
Feature-extractor option (transfer learning, frozen)
- If classical features aren’t sufficient, you can use a pretrained CNN (ResNet) as a frozen feature extractor and run an Isolation Forest on pooled feature vectors. That improves discrimination without end-to-end supervised training — a middle ground recommended in reviews for small datasets.
A good reference describing these tiny-data tactics is an industry guide that shows classical + anomaly detection and tiling work well for subtle defects.
Making the most of 3 defect images (augmentation & synthetic overlays)
Three real defects are useful — but treat them carefully.
-
Augmentation types (for threshold tuning / validation)
-
Geometric: small rotations (±5–15°), tiny translations, small rescaling.
-
Photometric: brightness/contrast jitter, slight blur, gaussian noise, histogram matching to different normals.
-
Keep augmentations realistic; over-aggressive transforms create unrealistic artifacts.
-
Synthetic overlays
-
Manually mask the defect patch from each defective image and paste it onto different normal backgrounds with alpha blending and slight blur to match edges. Adjust local brightness to blend seams.
-
This generates more defect contexts and is especially helpful to set detection thresholds and measure recall.
-
Use case
-
Use augmented/synthetic defect images to tune thresholds, compute approximate ROC points, and stress-test the pipeline.
-
Avoid using synthetic defects as training positives for a “normal-only” anomaly detector — that defeats the one-class strategy. You can, however, use them to train a supervised classifier only if you produce lots of high-quality, varied defect examples.
For semi-supervised deep approaches and GAN-based augmentation, see survey literature on semi-supervised and generative methods for surface defects.
Inference tactics: tiling, score aggregation, thresholding
When defects are small relative to the ROI, smart inference beats brute force.
-
Tiling
-
Tile the ROI into overlapping patches (typical sizes: 128×128 or 256×256 px depending on image resolution). Use 25–50% overlap to avoid border effects.
-
Score each tile with your anomaly model(s).
-
Aggregation strategies
-
Max score (any tile above threshold → defective) — high recall, more false positives.
-
Percentile (e.g., 95th) — reduces noise from single false-high tiles.
-
Ensemble voting — require two detectors to agree to reduce false positives.
-
Threshold selection
-
Compute anomaly scores on all training tiles (normals), set an initial threshold at a high percentile (e.g., 99th). Then adjust using augmented / synthetic defect tiles to raise recall to acceptable levels.
-
If false positives are costly, tighten the threshold or require agreement between models.
-
Heuristics
-
Combine a morphological rule (edge/gradient deficit or black-hat response) with anomaly score to reduce spurious cases.
-
For small defects, SAHI-style slicing and aggregation helps — it’s just a structured tiling + scoring scheme.
Validation, metrics & deployment with tiny positives
Small positive counts make evaluation noisy — handle carefully.
-
Metrics to prioritize
-
Recall (sensitivity) — catching defects is usually more important than a few extra false alarms.
-
False positive rate (FPR) or precision — quantify operational cost.
-
ROC-AUC can be reported but unstable with 3 positives; use it cautiously.
-
Validation strategies
-
Cross-validate on normal tiles (k-fold or leave-one-image-out) to estimate variation in anomaly scores and FP tendencies.
-
Use bootstrapping on the normal tile set to produce confidence intervals for thresholds and FPR.
-
Use the augmented/synthetic defect set purely for threshold tuning and rough recall checks.
-
Deployment & monitoring
-
Start in guarded mode: send flagged images to human inspection for the first weeks, collect labels and iteratively retrain or adjust thresholds.
-
Log anomaly scores and false-positive/false-negative cases to build a labeled dataset for future supervised or semi‑supervised refinement.
When to consider a small CNN / transfer learning (optional)
Only reach for CNN-based supervised training if you can realistically expand defect variability.
-
Good uses
-
Use a pretrained CNN as a frozen feature extractor (no supervised fine-tuning) and run an Isolation Forest / One‑Class SVM on pooled features — often more discriminative than hand-crafted features without supervised training.
-
If you can generate hundreds of realistic synthetic defects or collect more labeled defects, a small classifier or fine-tuned head becomes feasible.
-
Techniques to avoid overfitting
-
Freeze most layers, train only a small head; heavy augmentation; strong regularization (dropout, weight decay); early stopping; and cross-validation.
-
Metric‑learning / Siamese approaches or Deep SVDD are options for few-shot scenarios, but they require careful engineering.
Reviews of defect-detection literature highlight that pretrained backbones + classical/unsupervised heads are a practical compromise on small datasets.
Compact code example (Python + OpenCV + scikit-learn)
# Minimal pipeline: ROI crop -> tiles -> LBP+HOG features -> IsolationForest
import cv2, glob, numpy as np
from skimage.feature import local_binary_pattern, hog
from sklearn.ensemble import IsolationForest
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
ROI = (x0, y0, w, h) # set these to your fixed ROI coordinates
TILE = 128
OVERLAP = 0.5
def tiles_from_img(img, tile=TILE, overlap=OVERLAP):
h,w = img.shape[:2]
step = int(tile*(1-overlap))
for y in range(0, h-tile+1, step):
for x in range(0, w-tile+1, step):
yield img[y:y+tile, x:x+tile]
def features_from_tile(tile):
gray = cv2.cvtColor(tile, cv2.COLOR_BGR2GRAY) if tile.ndim==3 else tile
lbp = local_binary_pattern(gray, P=8, R=1, method='uniform')
lbp_hist, _ = np.histogram(lbp.ravel(), bins=10, range=(0,10), density=True)
hog_vec = hog(gray, pixels_per_cell=(16,16), cells_per_block=(2,2), orientations=9, feature_vector=True)
grads = np.abs(cv2.Sobel(gray, cv2.CV_32F, 1, 0)) + np.abs(cv2.Sobel(gray, cv2.CV_32F, 0, 1))
grad_stats = [np.mean(grads), np.std(grads)]
return np.hstack([lbp_hist, hog_vec, grad_stats])
# load normal images, extract features from tiles
X = []
for fn in glob.glob('data/normals/*.jpg'):
img = cv2.imread(fn)
roi = img[ROI[1]:ROI[1]+ROI[3], ROI[0]:ROI[0]+ROI[2]]
for t in tiles_from_img(roi):
X.append(features_from_tile(t))
X = np.vstack(X)
# scale + reduce
scaler = StandardScaler().fit(X)
Xs = scaler.transform(X)
pca = PCA(n_components=0.95).fit(Xs)
Xr = pca.transform(Xs)
# train Isolation Forest
iso = IsolationForest(n_estimators=200, contamination=0.01, random_state=0).fit(Xr)
# score a test image
def image_anomaly_score(img):
roi = img[ROI[1]:ROI[1]+ROI[3], ROI[0]:ROI[0]+ROI[2]]
scores = []
for t in tiles_from_img(roi):
f = features_from_tile(t)
fr = pca.transform(scaler.transform(f.reshape(1,-1)))
s = -iso.decision_function(fr)[0] # higher = more anomalous
scores.append(s)
return max(scores) # image-level score
# threshold = np.percentile( -iso.decision_function(pca.transform(scaler.transform(X))), 99 )
This is a starting point — tweak tile size, overlap, contamination, PCA dims, and thresholds for your data.
Practical checklist & troubleshooting
- Capture: fix camera pose and lighting; try raking light to highlight depressions.
- ROI: align and crop to the same pixels every image; small misalignments kill sensitivity.
- Preprocess: CLAHE + background subtraction + top-hat/black-hat morphological filters.
- Features: experiment with LBP + HOG + gradient stats; reduce with PCA.
- Models: start with Isolation Forest on tiles; add a small autoencoder and fuse scores.
- Thresholds: set at a high percentile of normal scores, then tune with augmented defects.
- If FP rate is too high: tighten threshold, require ensemble agreement, or add a simple rule (e.g., edge-count check).
- Operational: route uncertain cases to human inspection; collect labels and retrain iteratively.
Sources
- https://blog.roboflow.com/detect-subtle-defects/
- https://blog.roboflow.com/flaw-detection/
- https://www.nature.com/articles/s41598-023-49359-9
- https://link.springer.com/article/10.1007/s40684-021-00343-6
- https://www.mdpi.com/2227-9709/11/2/25
- https://asmedigitalcollection.asme.org/computingengineering/article/21/4/040801/1094064/Image-Based-Surface-Defect-Detection-Using-Deep
- https://dac.digital/how-defect-detection-with-computer-vision-works/
- https://github.com/Charmve/Surface-Defect-Detection
- https://www.reddit.com/r/computervision/comments/18b301g/defect_detection_using_computer_vision/
Conclusion
For sink marks on a fixed seat region with only 15 normals and 3 defects, the most reliable path is classical CV plus unsupervised anomaly detection: crop the ROI, normalize lighting, extract LBP/HOG/gradient features from overlapping tiles, train an Isolation Forest or One‑Class SVM on the normal tiles, optionally add a small autoencoder for reconstruction scoring, and tune thresholds with augmented/synthetic defect examples. Start with this lightweight, explainable pipeline; collect labeled edge cases in production and iterate — you’ll avoid overfitting and achieve practical sink mark defect detection without supervised CNNs.