You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Emgu中调用FindTransformECC函数出现NaN异常求助

Troubleshooting NaN Exception with Emgu CV's FindTransformECC in C#

Hey there! Let's break down why you're hitting that NaN exception when using FindTransformECC and fix it step by step. NaNs usually pop up from numerical instability in the algorithm, so let's target the most common causes in your code and workflow:

1. Fix the Initial Warp Matrix Initialization

Your current code initializes the warp matrix but doesn't set it to a valid starting point. If you leave it as default (all zeros), the algorithm can hit division-by-zero scenarios or divergent calculations. Always start with a unit matrix for Euclidean/Affine transformations:

// Initialize Euclidean transformation matrix (identity = no initial shift/rotation)
Mat warpMatrix = new Mat(2, 3, DepthType.Cv32F, 1);
CvInvoke.SetIdentity(warpMatrix); // This sets the matrix to identity values

2. Ensure Proper Image Preprocessing

FindTransformECC works best with floating-point images, and low-contrast or 8-bit-only inputs can cause numerical issues. Here's how to adjust your preprocessing:

// Convert to grayscale first
CvInvoke.CvtColor(sourceimage, sourceimage, ColorConversion.Bgr2Gray);
CvInvoke.CvtColor(template, template, ColorConversion.Bgr2Gray);

// Convert to 32-bit float (required for stable ECC calculations)
Mat srcFloat = new Mat();
Mat templateFloat = new Mat();
sourceimage.ConvertTo(srcFloat, DepthType.Cv32F);
template.ConvertTo(templateFloat, DepthType.Cv32F);

// Optional but recommended: Equalize histograms to boost contrast
// This helps the algorithm detect meaningful features
CvInvoke.EqualizeHist(sourceimage, sourceimage);
CvInvoke.EqualizeHist(template, template);

3. Validate Input Image Dimensions

FindTransformECC requires the source and template images to be exactly the same size. If they aren't, resize one to match the other before proceeding:

if (sourceimage.Size != template.Size)
{
    CvInvoke.Resize(template, template, sourceimage.Size);
    // Don't forget to re-convert to float after resizing if needed
    template.ConvertTo(templateFloat, DepthType.Cv32F);
}

4. Adjust Algorithm Parameters

Unreasonable iterations or eps values can lead to numerical instability:

  • eps: Set it to a small but realistic value (e.g., 1e-4 instead of 1e-10, which might cause precision overflows)
  • iterations: Start with 50-100 iterations—too few might not converge, too many could cause divergence
// Use balanced termination criteria
TermCriteria criteria = new TermCriteria(
    TermCriteriaType.Eps | TermCriteriaType.MaxIter,
    100, // Max iterations
    1e-4 // Epsilon threshold
);

5. Full Corrected Alignment Function

Putting it all together, here's a revised version of your AlignImage function:

public static Mat AlignImage(Mat sourceImage, Mat template, int iterations = 100, double eps = 1e-4, MotionType motionType = MotionType.Euclidean)
{
    // Clone inputs to avoid modifying original images
    Mat src = sourceImage.Clone();
    Mat temp = template.Clone();

    // Step 1: Convert to grayscale
    CvInvoke.CvtColor(src, src, ColorConversion.Bgr2Gray);
    CvInvoke.CvtColor(temp, temp, ColorConversion.Bgr2Gray);

    // Step 2: Ensure matching dimensions
    if (src.Size != temp.Size)
    {
        CvInvoke.Resize(temp, temp, src.Size);
    }

    // Step 3: Convert to 32-bit float
    Mat srcFloat = new Mat();
    Mat tempFloat = new Mat();
    src.ConvertTo(srcFloat, DepthType.Cv32F);
    temp.ConvertTo(tempFloat, DepthType.Cv32F);

    // Step 4: Initialize warp matrix to identity
    Mat warpMatrix = new Mat(2, 3, DepthType.Cv32F, 1);
    CvInvoke.SetIdentity(warpMatrix);

    // Step 5: Set up termination criteria
    TermCriteria criteria = new TermCriteria(
        TermCriteriaType.Eps | TermCriteriaType.MaxIter,
        iterations,
        eps
    );

    // Step 6: Run ECC alignment
    try
    {
        double error = CvInvoke.FindTransformECC(tempFloat, srcFloat, warpMatrix, motionType, criteria);
        Console.WriteLine($"Alignment completed with error: {error}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Alignment failed: {ex.Message}");
        // Return identity matrix as fallback
        CvInvoke.SetIdentity(warpMatrix);
    }

    return warpMatrix;
}

Additional Checks

  • Make sure neither image is completely black or has no texture—ECC relies on distinct features to compute transformations.
  • If you're using a different motion type (e.g., Affine), ensure the warp matrix is initialized correctly for that type (Affine uses a 2x3 matrix, same as Euclidean, but allows scaling/shearing).

内容的提问来源于stack exchange,提问作者Lucie Svobodová

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:03:52