ITK C++中ImageToHistogramFilter结果无法传出函数的问题求助
解决ITK Histogram无法从函数传出的问题
问题原因分析
- 传引用方式失败:ITK的
Histogram类通过ITK_DISALLOW_COPY_AND_MOVE宏禁用了拷贝构造和移动构造函数,直接对引用参数赋值会触发拷贝操作,导致编译报错。 - 智能指针传参外部访问失效: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
相关产品推荐
相关产品推荐

