A golden template comparison that runs clean on most images and throws an invalid ROI error on one or two is almost never a sizing problem. It is a double-registration problem: the image has already been rectified for perspective and rotation, and the comparison step is estimating its own perspective transform on top. This guide is for engineers wiring golden template inspection behind their own edge-based calibration. You will prove the cause in five minutes, fix it in one setting, and arrange the pipeline so it cannot return.
What "Invalid Roi" actually checks
A golden template is the reference image of a known-good part. The comparison registers the inspection image against that reference, subtracts the two, and scores the differences: bright where the part gains or reflects material, dark where it loses some. The alignment — either supplied by you or estimated by the step's own registration — specifies the area of the inspection image that gets compared to the template.
Before a single pixel is scored, the step checks that this area lies inside the inspection image. Invalid ROI is that geometric check failing, not a template problem. An unusable reference raises a different error of its own, and it fails every image, not one in ten. When the template visibly fits inside the frame and the region is defined inside it, something moved the region between your definition and the check. The only stage that can move it is the registration.
A region genuinely too small for its template is a separate failure with its own fix, covered in pattern match error template image too small: fix ROI size. And if a region draws in the wrong place rather than erroring out, that is usually a source-binding problem, covered in ROI image source binding: fix inspection region errors.
Why a second perspective fit breaks a rectified image
Your pipeline captures, calibrates from edges, and rectifies perspective and rotation in one pass. What leaves that stage is a straight image. Then the comparison, with registrationMethod set to Perspective inside InspectionOptions, looks at this straight image, estimates one more perspective transform from whatever edges it finds, and applies it to your search region.
There is no genuine perspective left to fit. What remains is residual keystone, and it is not uniform — it bends across the frame, stronger near the corners than the center. A fit on that residue returns a small transform, and a different one for every image, because every image carries different edge content. For most images the shift amounts to a few pixels and the region stays in bounds, so the scores come out correct. For one image, where weak edges and uneven residue combine, the estimate grows large enough that the mapped region crosses the frame border, and the step refuses the whole call.
That is why the failure follows image content rather than configuration: the loop can run ten times cleanly and fail on the eleventh image with every setting unchanged.
Worked example: a 650 × 550 px region on a 2448 × 2048 image
The inputs, with their sources:
- Inspection image: 2448 × 2048 px — the native frame of a 5 MP sensor, a standard smart-camera size.
- Template and search region, set by you: x from 1450 to 2100 px, y from 620 to 1170 px, so 650 × 550 px. Border margins: 1450 px left, 348 px right, 620 px top, 878 px bottom.
- Upstream edge-based rectification has removed the bulk of the keystone; a few percent remains and varies across the frame.
- The comparison's Perspective fit estimates, from that residue, a scale s = 1.06 about the image origin with a shift of t_x = +240 px and t_y = +40 px — magnitudes typical of a fit on residual keystone.
The rule in words: registration maps every region coordinate as x' = s·x + t_x and y' = s·y + t_y, and the region survives only while every mapped coordinate stays inside the frame, from 0 to W − 1 horizontally and 0 to H − 1 vertically.
The arithmetic, one corner at a time:
- x'_min = 1.06 × 1450 + 240 = 1537 + 240 = 1777 px — inside.
- x'_max = 1.06 × 2100 + 240 = 2226 + 240 = 2466 px — past the last pixel column, 2447 px, by 19 px.
- y'_min = 1.06 × 620 + 40 = 657.2 + 40 = 697.2 px — inside.
- y'_max = 1.06 × 1170 + 40 = 1240.2 + 40 = 1280.2 px — inside.
Result: a strip 19 px wide and 550 px tall — about 10,450 px² of the region's 357,500 px², or 2.9% — now lies outside the frame, and the step rejects the entire region instead of clipping it.
Decision: with the second fit in place, the right edge tolerates 2447 − 2226 = 221 px of further rightward shift before failing; an easier image whose fit returns t_x = +80 px maps x'_max to 2226 + 80 = 2306 px and passes. Pass, pass, fail — with no setting changed between images. With registrationMethod set to none the transform collapses to the identity, x'_max stays at 2100 px, and the right margin returns to its full 348 px.
The region and margins here are a typical bench set-up and the transform magnitudes are typical of a fit on residue; the mechanism, not the exact pixels, is what repeats on a line.
Prove the cause on the failing image
Three tests settle it in five minutes:
- Re-run the failing image with registrationMethod set to none in InspectionOptions. Error gone: the second fit was the cause. Error stays: your region is genuinely outside the rectified frame — check its coordinates against the frame size after rectification; cropping an image ROI when the corner coordinates are unknown covers that recovery.
- Log the registration result for every image in the loop and sort by shift. The failing image sits at the top; compare its shift against your border margin, 348 px on the right in the worked example.
- Re-run the failing image with your own rectification disabled and registrationMethod left at Perspective. It should now compare cleanly, because the image finally contains a real perspective for the fit to find. Confirmation from the other direction.
The same edge discipline that feeds your rectification is what keeps edge based pattern matching stable when lighting changes — weak edges hurt alignment quality and this fit alike.
The fix: rectify once, compare once
In a pipeline that already rectifies with edge-based calibration, set registrationMethod to none and let the comparison use the search region exactly as drawn. Your rectification becomes the single geometric authority on the frame, and the comparison does the one thing it is good at: subtract and score.
The alternative architecture is to drop your own rectification and keep Perspective, letting the step's registration handle pose on the raw image. That works, at the cost of per-image estimate jitter and a less regular frame for any other ROI on the part. Either way, run exactly one geometric stage. Running both is the bug.
Whether the comparison runs as the C call imaqCompareGoldenTemplate or as a wired step, the same choice sits in its options — configuring golden template match results in a Vision VI shows where those options and results live. One distinction to keep straight while you are in there: the search region bounds where alignment may look, which is not the same role as a position region on a moving line — limit search region vs position region in line tracking inspection separates the two.
Three fixes that only look like fixes
A sharpening convolution before the comparison is the classic false cure. Crisper residual edges pull the perspective estimate back toward the identity, the region stays in bounds, and the error disappears — while the double registration stays. It also breaks a hard rule of golden template inspection: nothing may change pixel intensities between rectification and scoring.
Buffer and format housekeeping belongs to a different error family. Unique destination image names, explicit plane extraction with imaqExtract and a cast with imaqCast prevent wrong-image and wrong-type failures. In this failure pattern they are innocent: sharing one destination image between the bright and dark defect outputs is fine, and images of different sizes are handled by the per-call alignment. None of it moves a region across a border.
Hiding the symptom is the third false cure. Skipping the failing image, swallowing the error or reordering the loop leaves the geometry broken for the next template you add.
| Suspect | Moves the region? | Verdict |
|---|---|---|
| registrationMethod = Perspective on a rectified image | Yes, per image | The cause |
| Convolution filter before comparison | Indirectly, by sharpening the fit | Hides the cause, risks the score |
| Shared bright/dark destination image | No | Fine in this pattern |
| Different image sizes in the loop | No, alignment is per call | Fine in this pattern |
Prevention: one geometric authority and a margin
- Fix the pipeline order: capture, then edge-based rectification for perspective and rotation, then golden template comparison with registrationMethod at none, then defect maps. Every ROI on the part then shares one geometry.
- Keep the search region at least 20 px inside every frame border, and 50 px or more where part placement varies close to the search tolerance. With registration none the region never moves at comparison time; the margin only absorbs rounding and placement jitter.
- If you crop or bin at the camera to speed the loop up, remap the template coordinates once after the change — camera ROI cropping at the source cuts bandwidth before the host, and its coordinate shift applies to your regions too.
- Rectification reshapes the frame itself. If black borders appear along the edges after undistortion, black borders after undistortion: cropping or calibration? separates the two causes — and a crop there moves every region coordinate with it.
Specifying hardware for the same inspection
Two paths cover this inspection on the line: smart cameras, which run the inspection on the device with no PC, and vision controllers, which pair camera and light I/O with on-board vision software. The pipeline rule travels with you to either platform: one rectification, then comparisons with no second registration. The camera finder filters smart cameras by resolution and shutter type, and the system configurator assembles the rest of the chain.
For a color part with fine detail, a 5 MP global-shutter sensor such as the MV-SC3050XC-16M-ATN-H keeps a template region in enough pixels to score small defects.
- Interface
- Fast Ethernet
- Resolution
- 5 MP
- Sensor format
- 1/1.45"
- Shutter
- Global
When several cameras share one inspection, the MV-VC3301H-128G66 vision controller runs the vision software with an Intel Core i3, 8 GB of memory, 5+ LAN ports, four built-in light channels and the included VM6200Pro license.
- LAN ports
- 5+ LAN ports
- USB 3 ports
- 3-4 USB 3 ports
- Light outputs
- 4 built-in channels
- Memory
- 8 GB
If your loop matches the failure above and the one-setting fix does not land, send the pipeline order and your logged shifts through the contact page. More ROI and region fixes sit on the systems topic page, alongside the learn hub.
Questions
Why does only one image in my loop trigger the invalid ROI error?
The comparison estimates its registration separately for every image, from that image's own edges. An image with clean, strong edges yields a small estimate and the shifted region stays inside the frame; an image with weak or cluttered edges yields a larger residual fit, and once the mapped region crosses the border the step refuses it. Log the estimated shift per image and the failing one will lead the list, letting you predict the next failure before it happens.
Does setting the registration method to none still handle part rotation?
No. With registrationMethod set to none the comparison takes your search region exactly as defined and applies no alignment of its own, so rotation has to be removed upstream. Your edge-based rectification already does that, which is precisely why the double registration occurred. If parts can still rotate after rectification, add an external alignment step that computes the rotation and offsets the region coordinates before the call, rather than re-enabling the comparison's own fit.
Can I keep perspective registration and drop my own rectification instead?
Yes, and it is a legitimate architecture. Leave the image un-rectified and keep registrationMethod at Perspective, so the step's registration fits the genuine perspective in the raw image. You trade a little per-image estimate jitter for a shorter pipeline. What you must never do is run both stages: a perspective fit applied to an already straight image is fitting noise, and that noise is what pushes the region out of bounds.
How much margin should I leave around the search region?
With registration none, keep at least 20 px between the search region and every frame border, and 50 px or more where part placement varies near the search tolerance. The margin only has to absorb rounding and placement jitter, because the region no longer moves at comparison time. In the worked example the region sat 348 px from the right border and still failed, but only because a second registration added a 240 px shift; without that fit, no shift exists.
Is an invalid ROI the same as an invalid golden template?
No, they are different checks at different stages. An invalid golden template file means the reference image itself is unusable, typically because the exclusion edges were not captured when it was built, which you adjust through the edge threshold used at template creation. An invalid ROI is purely geometric: the area about to be compared does not lie inside the inspection image. Fix the first by rebuilding the template; fix the second by correcting the region or removing the second registration.

