C++缓存设计建议
我有一个具有多种图像类型(RGB、灰色...)的 C++ 应用程序,每种类型都有旋转或缩放等属性。每个图像类型都是通过其他类型的一些计算生成的。例如,旋转的 GrayImage
是通过旋转 GrayImage
生成的,而 GrayImage
又是通过“灰化”RGBImage
生成的。
我想设计一个带有方法 GetX(...)
的缓存类,用于缓存各种图像(可能还有计算路径中的所有图像)。 该类还知道如何生成每个图像,以防它不在缓存中。
该类必须满足一些约束:
由于我们正在处理不同类型和表示形式(RGB、灰度等)的图像,因此缓存必须返回一个具体类,以便调用代码能够在不进行某种转换的情况下使用它。因此,缓存机制必须保存包含具体类型的不同缓存结构。 (如果我错了请纠正我)
例如。map<...,RGBImage> 地图<...,GrayImage>
缓存必须能够灵活地适应图像计算的变化。只要代码的更改不是太大,就可以接受。
我的当前版本为每种图像类型附加了一个 Key
结构。 有GrayKey
、RGBKey
等等。各种键都包含缩放和旋转等属性,并且可以具有特定于图像的属性(例如 GrayKey
的 toGrayConvertingMethod)。 缓存保存以下形式的地图:
map <XKey,XImage>
GetX(...)
方法接收 Key
结构作为请求旋转灰度图像的参数。 不过,这种实现迫使缓存应用大量逻辑来计算图像。它必须检查 GrayKey 是否请求旋转图像并采取相应措施。 我想以一种更优雅的方式“编码”这种图像计算关系,但似乎找不到。
有什么建议吗?
多谢。
I have a c++ application with several image types(RGB, Gray...) and every type has properties like Rotation or Scale. Every image type is generated via some computation from the other types. For example, A rotated GrayImage
is generated by rotating a GrayImage
which in turn is generated by "graying" an RGBImage
.
I would like to design a cache class with methods GetX(...)
that caches the various images (and possibly all images in the computation path).
This class would also know how to generate each image in case it is not in the cache.
The class must fulfill some constraints:
Since we are dealing with images of different types and representations(RGB, GrayScale etc.) the cache must return a concrete class for the calling code to be able to use it without some sort of casting. Thus, the cache mechanism must hold different cache structures containing concrete types. (fix me if I'm wrong here)
map<...,RGBImage> map<...,GrayImage>
for example.
The cache must be flexible to changes in computation of images. Changes to code are acceptable as long as they are not too large.
The current version I have attaches a Key
struct to each image type.
There's GrayKey
, RGBKey
and so on. the various keys hold properties like Scale and Rotation and can have properties specific to the image (e.g. toGrayConvertingMethod for GrayKey
).
The cache holds maps of the form:
map <XKey,XImage>
GetX(...)
method receives a Key
struct as parameter requesting a Rotated GrayImage for example.
Though, this implementation forces the cache to apply lots of logic for computations of images. It must check whether GrayKey requests a rotated image or not and act accordingly.
I would like to "encode" this image computation relationship in a more elegant way but can't seem to find one.
Any suggestions?
Thanks a lot.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
也许你可以使用
Boost.MultiIndex 做一些事情容器?它将允许您创建一个类型来存储图像数据及其操作方式的详细信息,然后根据您想要的键组合查找值。如果您以前没有使用过它,它可能看起来有点令人畏惧,但我在下面附上了一个示例。
显然,我的示例仅处理缓存机制的存储/检索部分,如果您将其组合在一起,如果查找失败,可以生成图像,它应该做您想做的一切。扩展它也很容易......需要查找额外的参数吗?您只需向
ImageCache
typedef 添加另一个索引即可。编辑:它是一个很大的...
我尝试扩展上面的示例,以在缓存中查找与您搜索的内容最接近的图像,但是带有偏差,因此如果您想要旋转 45,比例为 10,如果没有找到精确匹配,则将倾向于其中一个属性相同而另一个属性为 0 的结果(即比例为 10,但是0旋转,所以你需要做的就是旋转)。
该代码被注释以解释其作用,但基本上,它使用模板递归按顺序搜索索引,一旦索引找到一些匹配项,它就会尝试按相关性顺序对它们进行排序,并返回最佳匹配项。要添加另一个属性,您需要执行以下操作:
ImageCacheItem
ImageCacheSimilarity
ImageCache
typedef它可能不是最佳解决方案,但我认为它涵盖了您在评论中提到的用例。
Perhaps you could do something using the
Boost.MultiIndex
container? It would allow you to make a type that stores the image data, and details of how it was manipulated, then lookup values based on whatever combination of keys you want. If you haven't used it before, it could seem a bit daunting, but i've attached an example below.Obviously, my example only handles the storage/retrieval part of the caching mechanism, if you stick this together which something that can generate the images if the lookups fail, it should do everything you want. Extending it is easy too...need to lookup on extra parameters? you just need to add another index to the
ImageCache
typedef.Edit: its a big one...
I have had a stab at extending the above example to find the image in the cache that is closest to what you search for, but with a bias, so if you want rotation of 45, and a scale of 10, if no exact match is found, it would favour a result with one of the properties the same, and the other as 0 (i.e. a scale of 10, but 0 rotation, so all you need to do is rotate).
The code is commented to explain what its doing, but basically, it uses template recursion to search through the indices in order, as soon as an index finds some matches, it attempts to sort them in order of relevance, and returns the best match. To add another property, you would need to do the following:
ImageCacheItem
ImageCacheSimilarity
ImageCache
typedefIt may not be the most optimal solution, but I think it covers the use case you mentioned in your comment.
您是否考虑过使用瘦访问器来灰化和旋转彩色图像? Adobe 的通用图像库(现在是 boost 的一部分)以这种方式使用一些聪明的迭代器
Have you considered using thin accessors to gray and rotate your color image? Adobe' generic image library (now part of boost) uses some clever iterators that way
您是否考虑过使用 STL 容器?使用地图或集来存储对图像的引用。可以快速查找您是否已经创建了图像。
Did you consider using an STL container? Use a map or set to store references to the images. The have fast lookup to see if you've already created an image.