A directional filter can work too well. Oriented at the line texture, a Gabor-filtered image leaves bright machining lines and a bright round defect side by side above any brightness threshold, and a second pixel filter — median, blur, another Gabor pass — fades the defect along with the lines. The fix is to stop filtering pixels and start filtering shapes: threshold, label connected blobs, then keep only regions whose compactness is close to a perfect circle's. This guide gives the compactness values for the shapes you will meet, a worked example at 6.0 µm per pixel, the cutoff logic, and the checks that keep the filter honest on a smart camera or a PC-based system.
Why a second filter pass loses
Once the image is thresholded, defect and background lines are both white regions on black. They differ in geometry, not gray level, so any pixel-neighborhood operation acts on both at once and blurs the evidence you need. Region-level logic acts on each blob separately: the line is long and thin, the defect is round and compact, and one scalar per region separates them.
The shape route also tolerates a rough first stage. Once direction-selective filtering has pulled the line response apart from the defect response, a wide band of binarization thresholds produces the same regions, because shape rather than gray level makes the final call. Check candidates on a live binary image preview instead of tuning the threshold by eye on the grayscale image.
Detecting the defect from texture before any segmentation is the other route; the local variance filtering guide covers that case. This guide handles the one where the defect already segments cleanly and the linear background features survive next to it — and need to be removed by shape.
The compactness number that separates a defect from a line
Compactness compares a region's area A with its perimeter P:
C is dimensionless: measure in pixels or millimetres, the score is the same. A perfect circle gives C = 1.00 by construction — for a fixed perimeter the circle encloses the most area — and every other shape scores lower. The fill fraction F is the alternative: draw the disk with the same area as the blob, centered on the blob's centroid, and count how much of the blob falls inside. Both metrics rank shapes the same way; compactness needs only area and perimeter, which every blob tool prints.
Solid shapes, ideal continuous perimeters:
| Region | Shape | Compactness C |
|---|---|---|
| Round defect | circle | 1.00 |
| Square pad | 1:1 | 0.79 |
| Slightly elongated blob | 2:1 | 0.70 |
| Elongated blob | 4:1 | 0.50 |
| Grind line | 10:1 | 0.26 |
| Fiber or hairline | 20:1 | 0.14 |
The gaps are wide. A 10:1 line scores roughly a quarter of a round defect's value, and the same 10:1 rectangle keeps only about 0.35 of its pixels inside its equivalent disk, against 1.00 for the circle. Rasterized boundaries inflate the perimeter slightly, and the effect grows as regions shrink — the reason a pixel floor appears in the checklist.
What you need
The chain is short, and every piece exists in any vision library or smart-camera toolset:
- The direction-filtered or otherwise high-contrast image: Gabor output, or dark-field illumination that makes the lines bright.
- An automatic threshold. Otsu's method handles bimodal histograms — the Otsu segmentation walkthrough in Lab color shows the setup — and local mean adaptive thresholding covers an uneven background.
- Connected-component labeling with a chosen connectivity; the connectivity 4 or 8 comparison for circular markers explains when the choice changes the result.
- Per-region area and perimeter, to compute C.
- Enough pixels: at least 20 px across the smallest defect's minor axis, or the perimeter estimate wobbles and the score sinks on its own.
The pipeline runs on-device on smart cameras with blob tools, or on a PC fed by an area scan camera when the Gabor stage and custom gates live in your code.
Steps: filtered image to defect-only mask
- Threshold. Start automatic (Otsu), then freeze a fixed value once the lighting is stable. Keep the polarity straight: a bright defect keeps above-threshold pixels; a dark defect needs the image inverted first.
- Clean the binary mask. A 3 × 3 median on the binary image strips single-pixel specks and pinholes so labeling returns clean regions. Do not median the grayscale image here — it rounds the defect boundary you are about to measure.
- Label connected components. Use 8-connectivity when the lines break into diagonal fragments; use 4 when you want strict separation and the shapes are axis-aligned.
- Measure each region. Compute area and perimeter with the tool's own conventions, then C = 4πA/P² per blob.
- Apply the gates. Keep regions with C ≥ 0.70 for round defects and with area inside ±30% of the nominal defect area. Lines fail the compactness gate; wrong-size debris fails the area gate.
- Rebuild the output. Union the kept labels into the defect mask, or overlay them on the original image for the operator.
Worked example: a 0.6 mm round defect over 10:1 grind lines
Inputs, as a typical small-part case — bright round inclusion in a field of directional lines:
- Field width: 24 mm, framed to one machined face (typical framing for this part class).
- Sensor: 4000 × 3000 px, the printed resolution of the camera below.
- Image scale: 24 mm ÷ 4000 px = 6.0 µm/px.
- Defect: bright round inclusion, 0.6 mm diameter (typical inclusion size for this case).
- Background: grind lines at 10:1, sized to the same area as the defect — the hard case, where an area gate cannot help.
Rule in words: compactness compares a region's area with the circle of the same perimeter, and only the circle reaches 1.00.
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
Defect, in pixels: 0.6 mm ÷ 0.006 mm/px = 100 px across, radius 50 px.
- Area: A = π × 50² = 7854 px²
- Perimeter: P = π × 100 ≈ 314 px
- Compactness: C = 4π × 7854 ÷ 314² ≈ 98,696 ÷ 98,596 ≈ 1.00
Grind line with the same area: 10w² = 7854 px² gives w ≈ 28 px, length ≈ 280 px.
- Area: A = 28 × 280 = 7840 px²
- Perimeter: P = 2 × (28 + 280) = 616 px
- Compactness: C = 4π × 7840 ÷ 616² = 98,520 ÷ 379,456 ≈ 0.26
Decision: set the cutoff at C ≥ 0.70. The defect passes with 43% headroom (1.00 against 0.70); the line fails by a factor of 2.7 (0.70 ÷ 0.26). The two regions carry the same area, so only shape separates them — which is the point. Rasterization trims the real circle score to roughly 0.95-1.00, still far above the cutoff.
Pixel floor: 20 px × 6.0 µm/px = 0.12 mm, the smallest feature this geometry judges by shape. Smaller defects need more pixels over the same field; the camera resolution calculator sizes that budget directly. Estimate the pixels your smallest defect needs:
Where the pipeline runs: device or PC
On-device, a vision sensor or smart camera runs thresholding, labeling and region features internally and switches an output on the accept condition — the compactness filter is a set of feature limits in the blob tool, not custom code. For a single station at a fixed working distance, this is the shortest route:
- Interface
- GigE
- Resolution
- 6-10 MP
- Interface
- GigE
- Resolution
- Up to 3 MP
The MV-SC5060XM-08M-WBN processes 6 MP mono images on-device over GigE. The LS-SMC-0063 pairs its processor with an integrated 16 mm lens and polarized white light, which suppresses the specular sheen that makes brushed lines flare above threshold.
On a PC, the same six steps run in your code, and you take that route when the Gabor stage itself must be yours, when gates combine shape with position and gray statistics, or when the pixel budget wants a larger sensor. The 12 MP camera in the worked example covers the middle ground at 30 fps over USB3.
Moving parts add one rule: keep part speed × exposure below one pixel of blur, and use a global shutter so the readout cannot distort a moving image. The MV-CH120-11UC is the 12 MP high-speed USB3 camera with global shutter and a C-mount for that job:
- Sensor format
- 1.1"
- Lens mount
- C-mount
- Interface
- USB3
- Resolution
- 12 MP
Prove the cutoff on known parts
Set the cutoff from your own populations, not from the table alone:
- Run 20-30 trusted parts, half known-good, half with known defects, and log C and area for every region.
- Line junk should sit at 0.4 or below and the defect population at 0.9 or above. Place the cutoff in the gap; 0.70 is the usual landing point for round defects.
- Line regions scoring above 0.5 mean the lines merged into sheets at your threshold. Lower the threshold slightly or reduce the Gabor smoothing so regions separate before labeling.
- A defect that touches a line inherits the line's perimeter and fails its own gate. Erode the binary mask by 1-2 px before labeling to cut thin bridges; the area gate absorbs the lost pixels.
- Small blobs that score low are boundary pixelation, not geometry. Enforce the 20 px minor-axis floor; do not lower the cutoff below 0.50, which starts admitting 4:1 junk shapes.
Keep the optical background stable across the shift so the two populations do not drift toward each other; the ambient light variation guide covers the controls that matter. When parts start failing for no obvious reason, suspect the lighting before the software — the glass bottle defect walkthrough is the classic case.
When compactness is the wrong tool
- The genuine defect is elongated. Cracks and scratches score 0.26 like any other line. Invert the logic — keep low-C regions — and bound them with the expected elongation band, or filter on major/minor axis ratio instead. When a scratch is the target, lighting and dynamic thresholding come first; the scratch defect detection guide starts there, and the glossy panel lighting guide handles the reflective surfaces that make scratches hard to light.
- The background is textured, not linear. Stochastic noise in uniform gray regions never collapses into labeled lines, so no shape score keys on it; the local variance route covered earlier is the right discriminator there.
- The contaminant is dark on a dark surface. Bright-blob logic inverts, and lighting carries the job again; the dark contaminant detection guide sequences the lighting first and the same blob checks second.
Cutoff checklist
- Smallest defect at least 20 px across the minor axis at the chosen image scale — below that, perimeter noise sinks the score by itself.
- Threshold fixed and confirmed on a live binary image, polarity checked.
- Connectivity set for the fragments your lines actually produce (8 for diagonals).
- C = 4πA/P² computed with the same library and conventions in setup and production.
- Gates: C ≥ 0.70 plus area within ±30% of nominal.
- A 20-30 image validation run with logged scores, cutoff placed in the gap between populations.
- Failure behavior defined: the station defaults to reject.
Size the camera from the pixel budget first and the rest follows: the camera finder filters by resolution, shutter and sensor format, the configurator walks sensor to mount, and the systems topic page collects the companion image-processing guides. If a background resists, send a sample image through the contact page and we will look at the two populations with you.
Questions
Why does a round blob still score below 1.00?
The perimeter of a digital blob follows pixel edges, so every staircase step adds length the true circle does not have. The error shrinks as the blob grows: a 100 px diameter circle lands within a few percent of 1.00, while a 10 px circle can lose a tenth of its score or more. Keep the smallest defect you must judge at 20-30 px across and the cutoff stays safe.
Can a smart camera run the compactness filter without a PC?
Yes. Blob tools on smart cameras and vision sensors compute area, perimeter, compactness, bounding box and center of gravity per region, then switch an output on the accept condition. You set the threshold, the connectivity and the feature limits in the tool's configuration, and the device returns pass/fail and position over its digital I/O or Ethernet link — no external processing for a single-station inspection.
My defect is elongated — will compactness reject it too?
Yes, and that is the metric working as designed. Score the defect's own shape first: a 2:1 rectangle computes to 0.70 and a 4:1 rectangle to 0.50, against 0.26 for a 10:1 line. Set the cutoff between your defect's score and the background's, for example 0.5 for a 4:1 crack in a field of grind lines, and gate on area as a second condition.
Would morphological opening remove the lines more simply?
Opening with a disk removes any feature thinner than the disk, so it clears uniform lines in one operation. It struggles when line width varies across the part, and it erodes a genuine defect's edge at the same time, distorting the very area and perimeter you may want to measure. Shape filtering after labeling leaves the kept blob pixel-intact.
Where does the median filter belong in this chain?
After thresholding, not before. Applied to the grayscale image it also rounds the defect's boundary, which widens the threshold band you must test. Keep the binary cleanup to the single 3 × 3 median pass described in the steps: the compactness filter itself needs no smoothing, because it judges whole regions, not pixel neighborhoods.



