C++ 图像二值化库的设计模式

C++ 图像二值化库的设计模式,c++,design-patterns,image-processing,C++,Design Patterns,Image Processing,我现在正在开发一个图像二值化库,在这个库中,将实现经典的二值化方法,如Sauvola和Otsu方法。现在我的问题是如何优雅地设计图书馆。目前,我有两个解决方案: 解决方案1: class Binarization { public: BiinterfacePtr interface_; enum BinarizationMethods { Method1, Method2, Method3, Method4

我现在正在开发一个图像二值化库,在这个库中,将实现经典的二值化方法,如Sauvola和Otsu方法。现在我的问题是如何优雅地设计图书馆。目前,我有两个解决方案:

解决方案1:

    class Binarization
    {
    public:
       BiinterfacePtr interface_;
       enum BinarizationMethods
       {
           Method1, Method2, Method3, Method4
       }
       void set(BinarizationMethods method, Image *p_in, Image *p_out, Binarizationpara &para)
       {
           if (method == Method1)
           {
               BiinterfacePtr interfacetemp(new BinarizationMethod1());
               interface_ = interfacetemp;
            }
           if (method == Method2)
           {
            BiinterfacePtr interfacetemp(new BinarizationMethod2());
               interface_ = interfacetemp;
           } 
           ....
       }
       bool run()
       {  
          interface_->run();
        }
       Image* output()
       {
          return interface->output();
        }
}
如您所见,不同二值化方法的实现是在
Biinterface
类中完成的。当我们使用
Binarization
类时,我们可以通过调用
set
方法来表示我们想要使用的方法。然而,不同的二值化方法可能有不同的参数设置,因此
Binarizationpara
的结构将变得复杂

解决方案2

class BinarizationMethod1()
{
  public:
    perform_binarization(Image *p_in, Image *p_out, BinarizationMethod1Para &para);
}

class BinarizationMethod2()
{
  public:
    perform_binarization(Image *p_in, Image *p_out, BinarizationMethod2Para &para);
}
我的问题是哪一个更好。欢迎提出设计图书馆的想法。谢谢

我会选择一个简单的,有点像你的第一个解决方案,只是我会使用构造函数注入。我真的不明白为什么要使用枚举,它是紧密耦合的,不是维护应用程序的最佳方式。您还可以将想要的方法直接传递给二进制化模块。如果需要将参数传递给方法,只需使用它们的run方法(当然,如果它们都有相同的run方法,否则可以使用方法构造函数)。此外,这使得新方法的创建和维护变得容易

例如,您可以只执行以下操作:

Binarization binarization(new SauvolaMethod()...);
binarization->run();

免责声明:我不是C++的家伙

我知道这是一个老帖子,但是我会更新那些有兴趣的人。 这个问题的答案很容易被误导。如果您打算编写一个高质量的图像二值化库,但尚未仔细考虑,那么在开始之前,您必须计划以下一些事情

<> LI>在C++中没有好的图像读取器/作者烘焙,所以你可能需要创建一个通用的图像概念,它将与第三方库一起工作。但该图像会保持32b RGBA值还是8b灰度/黑白值?这会对设计产生巨大影响
  • 一旦你能最终处理一个图像,你会发现你的算法在没有整体图像优化的情况下会运行得太慢。所有局部自适应阈值算法都可以共享这一点。确保它是您设计的一部分
  • 现在您正在使用整数图像,需要存储在这些结构中的值对于大图像来说可能太大。您现在需要采用“平铺”方法进行设计,该方法将大块处理大型图像
  • 既然您正在平铺,为什么要按顺序进行?这会让您对所有事情产生疑问,并想知道为什么不首先将其发送到GPU,由自定义内核进行处理
  • 你终于走到了尽头。您的库看起来很棒,具有所有的魔力,但它可能没有它可能快,因为您不想走GPU的路线,而是选择了面向对象继承的设计。许多编译器无法像您希望的那样优化此类结构。你永远不会真正注意到这一点,除非你将它与一个具有同等功能的单片函数进行比较
  • 关于第五点,如果您需要更快的速度,我有一个建议:模板和奇怪的重复模板模式。

    如果您坚持使用OOD方法,我也会使用上面推荐的策略模式,但也会利用门面提供更干净的体验


    祝你好运!我根据经验说:

    您可能正在寻找工厂模式(您现在已经实现了一个相当基本的模式)。您的各种构造函数签名之间的差异有多大?@alrikai感谢您的评论。根据所采用的二值化方法,构造函数签名有很大不同。我认为Shinosha给出了一个很好的解决方案,其他人也没关系