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

ITK C++中ImageToHistogramFilter结果无法传出函数的问题求助

解决ITK Histogram无法从函数传出的问题

问题原因分析

  1. 传引用方式失败:ITK的Histogram类通过ITK_DISALLOW_COPY_AND_MOVE宏禁用了拷贝构造和移动构造函数,直接对引用参数赋值会触发拷贝操作,导致编译报错。
  2. 智能指针传参外部访问失效:ITK滤波器的输出对象生命周期由滤波器管理,函数结束时滤波器对象(auto f)被销毁,其输出对象也会被自动释放,外部智能指针指向的是已失效的内存,因此访问时得到错误结果。

解决方案

方案1:传引用参数,手动填充已有Histogram对象

既然无法直接拷贝,我们可以通过Histogram的成员函数,将滤波器输出的直方图数据逐个复制到传入的引用对象中:

int Histogram(HistogramType& result, const ImageType& image1, ...)
{
    auto f = HistogramFilterType::New();
    f->SetInput(image1);
    // 设置直方图参数(如bin数量、范围等)
    // f->SetNumberOfBins(256); 示例:设置单通道256个bin
    f->Update();

    const auto& outputHist = *f->GetOutput();
    // 初始化传入的result,匹配输出直方图的维度和尺寸
    result.SetSize(outputHist.GetSize());
    for (unsigned int dim = 0; dim < HistogramType::MeasurementVectorSize; ++dim)
    {
        result.SetBinMin(dim, outputHist.GetBinMin(dim));
        result.SetBinMax(dim, outputHist.GetBinMax(dim));
    }

    // 复制所有bin的频率值
    for (unsigned int binIdx = 0; binIdx < outputHist.GetTotalNumberOfBins(); ++binIdx)
    {
        result.SetFrequency(binIdx, outputHist.GetFrequency(binIdx));
    }

    return EXIT_SUCCESS;
}

调用方式:

HistogramType result;
if (Histogram(result, image, ...) != EXIT_SUCCESS)
{
    return EXIT_FAILURE;
}
std::cout << result.GetTotalFrequency() << std::endl; // 输出正确值

方案2:智能指针传参,转移输出对象所有权

通过修改滤波器的释放策略,或克隆输出对象,确保外部智能指针能持有有效的直方图对象:

方式A:禁止滤波器自动释放输出

int Histogram(HistogramType::Pointer result, ImageType::ConstPointer image1, ...)
{
    auto f = HistogramFilterType::New();
    f->SetInput(image1);
    // 设置直方图参数
    f->SetReleaseDataFlag(false); // 关键:阻止滤波器销毁输出数据
    f->Update();

    auto outputHist = f->GetOutput();
    outputHist->Register(); // 增加引用计数,确保对象不被销毁
    result = outputHist;

    return EXIT_SUCCESS;
}

调用时无需提前创建Histogram对象:

HistogramType::Pointer result;
if (Histogram(result, image, ...) != EXIT_SUCCESS)
{
    return EXIT_FAILURE;
}
std::cout << result->GetTotalFrequency() << std::endl; // 输出正确值

方式B:克隆输出对象(推荐)

直接克隆滤波器的输出,得到独立的直方图对象,不受滤波器生命周期影响:

int Histogram(HistogramType::Pointer result, ImageType::ConstPointer image1, ...)
{
    auto f = HistogramFilterType::New();
    f->SetInput(image1);
    // 设置直方图参数
    f->Update();

    // 克隆输出对象并转换为对应类型的智能指针
    result = dynamic_cast<HistogramType*>(f->GetOutput()->Clone().GetPointer());

    return EXIT_SUCCESS;
}

调用方式与方式A一致,克隆后的对象完全独立,无需担心生命周期问题。


内容的提问来源于stack exchange,提问作者Ichwerdennauchsonst

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 10:24:50