重采样大图像以进行显示 [英] Resampling a large image for display

查看:95
本文介绍了重采样大图像以进行显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



该帖子较少寻求解决方案",而更多的是寻求意见".

我有2个大图像文件.每个像素存储为短整数或浮点值(取决于源).图片非常大-大约10000px x 7000px.

我想在一个设置的窗口中显示它们-每个窗口500像素乘500像素(用户可调整大小).一个窗口将包含整个图像(重新采样),另一个窗口将包含1:1缩放视图.通过单击调整大小后的图像视图,可以选择要放大的区域. (标有红色方块)

那就是我打算做的.但是我需要确定如何实际实施的帮助.

1.我的一个想法是在开始时对整个文件重新采样(可能需要5到10秒?)并另存为位图或二进制文件.然后加载它.
第二个想法是动态加载补丁.因此,起初我会做类似最近邻居的事情,然后在小块上进行三次三次重采样.这将减少观看图像的等待时间,但可能要复杂得多. (有点像Google Earth一样吗?)
您认为哪一个更好?开始时要重新采样,但以后要有统一的用户体验.或以某种方式逐块重新采样.

2.我无法决定如何实现绘图图面.在文档上使用GDI逐像素绘制. (我使用MFC)或另存为位图并加载到图片框.还是一些openGL方法? (我在这里很迷路,但是我愿意学习-链接会被申请)

3.我可以在多个位置访问一个文件吗?如果我可以让一个线程对文件的一半进行重采样,而另一个线程对文件的下半部分进行重采样,那将非常快.但我不确定是否有可能. (也许我可以事先复制文件并查找?)

任何帮助和意见,将不胜枚举.我只是想制定一些工作框架/计划.
链接/教程.我是MFC的新手.

Hi,

This post is less "solution seeking" and more "opinion seeking".

I have 2 large image files. Each pixel is stored either as a short integer or a float value (depending on source). The images are huge - about 10000px by 7000px.

I want to display them in a set windows - of say 500px by 500px each (user resizable). One window will contain the whole image (resampled) and another will contain a 1:1 zoomed view. The area to zoom into will be chosen by clicking in the resized image view. (Marked with a red square)

That is what I intend to do. But I need help deciding how to actually implement it.

1. One idea I have is to resample the whole file at start (may take 5-10 secs?)and save as a bitmap or a binary file. Then load it.
The second idea is to load in patches dynamically. So initially I do something like a nearest neighbour approximation, and then do bicubic resampling on small patches. THis will reduce the wait time to see the image but may be much more complex. (Bit like what google earth does?)
Which one do you think is better? Resample at start, but have a uniform user experience later. Or resample block by block in some way.

2. I cant decide how to implement the drawing surface. Plot pixel by pixel using GDI on a document. (Im using MFC) Or save as a bitmap and load to picturebox. Or some openGL method? (Im very lost here, but im willing to learn - links will be appriciated)

3. Can I access one file at multiple points? If I could have one thread resampling half of the file, and another doing the next half, it would be really quick. But im not sure if its possible at all. (May be I can copy the file beforehand and seek?)

Any help and opinion on this would be appriciated. Im just trying to lay down some a framework / plan of work to.
Links / Tutorials appriciated. Im new to MFC.

推荐答案

我会选择选项2(即使您选择了选项1,您也可能必须将整个过程进行细分,因为它是作为一个单独的步骤执行的步骤,将需要大量的内存.)

关于第(3)点,我相信您可以,但是,也许您不需要.我的意思是您应该在线程之间分配 processing 时间(即每个线程在图像的不同部分上工作),从文件中读取时间可能不会影响整体结果.
I would choose option 2 (even if you choose option 1, you probably have to segment the whole process, because, performed as a single step, it would require a huge amount of memory).

As about point (3) I believe you can but, probably you don''t need. I mean you should split the processing time among the threads (that is each thread works on a different portion of the image) , the read-from-file time probably doesn''t affect the overall result.


如果要这样做,我会将图像保留在内存中,出于显示目的将其转换为RGB24(假设这些是彩色图像).每个210 MB,您可以负担得起.没有外部文件.

在进行转换的同时,我将以10乘10像素为单位进行平均,以生成缩小的图像. (不要使用三次三次重采样,只能进行平均!)

正确编码后,我希望每个图像的整个过程不会超过1秒.

通过SetDIBitsToDevice绘制大图像的子窗口,并传递所需的坐标.原则上,即使对于大图像,MS也确实以有效的方式实现了blitting.

如果要尽快显示缩小的图像,我看不到一种避免完全扫描原始图像的方法. [如果要生成大图像,则可以同时计算并保存缩小量.或在接收文件时使用专用的工具预先计算并保存缩减量.]

除非您采用抽取(而不是对10 x 10块中的所有像素取平均,否则可以对其他像素或三分之一进行平均...由于混叠而导致的质量损失很小).但这不会使您的速度线性提高,因为瓶颈将是内存访问.

最后一条建议:确保逐行(即通过增加地址)而不是逐列扫描图像.
If I were to do this, I would keep the images in memory, converted to RGB24 for display purposes (assuming these are color images). 210 MB each, you can afford that. No external file.

At the same time I am doing the conversion, I would average in blocks of, say, 10 by 10 pixels to yield the reduced images. (Don''t use bicubic resampling, just average!)

Properly coded, I''d expect the whole process not to exceed 1 second per image.

Drawing a subwindow of the large image is done with SetDIBitsToDevice, passing the desired coordinates. In principle, MS did implement the blitting in an efficient way even for big images.

If you want to show a reduced image as soon as possible, I don''t see a way to avoid a full scanning of the original image. [If you are generating the big images, you could precompute and save the reductions at the same time. Or precompute and save the reductions with a dedicated utility as you receive the files.]

Unless you resort to decimation (instead of averaging all pixels in 10 x 10 block, you could average every other pixel or every third... with a little loss of quality because of aliasing). But this won''t give you a linear speed improvement as the bottleneck will be memory accesses.

Last piece of advice: make sure to scan the image row by row (i.e. by increasing addresses) rather than column by column.


这篇关于重采样大图像以进行显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆