简体   繁体   English

逐像素进行图像处理需要很长时间

[英]Image processing, pixel by pixel, takes a long time

I'm writing an Android application which processes an image pixel by pixel. 我正在编写一个Android应用程序,它逐个像素地处理图像。 To read and set the pixels I use two nested loops. 为了读取和设置像素,我使用了两个嵌套循环。

This process is very time-consuming. 此过程非常耗时。 Even if I delete the instructions in the loops, it takes about a minute to run on an 8 megapixel image. 即使删除循环中的指令,在8兆像素的图像上运行也需要大约一分钟。

Why is it taking so long? 为什么要花这么长时间? Are there any other ways to get and set pixels? 还有其他获取和设置像素的方法吗?

    long mn = img_w*img_h;
    long o = 0;
    for(int i =0;i<img_w;i++) {
        for(int j=0;j<img_h;j++) {

                System.out.println(mn-o);

        o++;

        }
    }

This code simulate processing image, and this code take very long time 此代码模拟处理图像,此代码需要很长时间

logcat (section): logcat(部分):

    02-12 19:01:40.815: I/System.out(332): 4999.0
02-12 19:01:40.815: I/System.out(332): 4998.0
02-12 19:01:40.815: I/System.out(332): 4997.0
02-12 19:01:40.825: I/System.out(332): 4996.0
02-12 19:01:40.825: I/System.out(332): 4995.0
02-12 19:01:40.825: I/System.out(332): 4994.0
02-12 19:01:40.825: I/System.out(332): 4993.0
02-12 19:01:40.825: I/System.out(332): 4992.0
02-12 19:01:40.825: I/System.out(332): 4991.0
02-12 19:01:40.825: I/System.out(332): 4990.0
02-12 19:01:40.835: I/System.out(332): 4989.0
02-12 19:01:40.835: I/System.out(332): 4988.0
02-12 19:01:40.835: I/System.out(332): 4987.0
02-12 19:01:40.835: I/System.out(332): 4986.0
02-12 19:01:40.845: I/System.out(332): 4985.0
02-12 19:01:40.845: I/System.out(332): 4984.0
02-12 19:01:40.845: I/System.out(332): 4983.0
02-12 19:01:40.845: I/System.out(332): 4982.0
02-12 19:01:40.845: I/System.out(332): 4981.0
02-12 19:01:40.845: I/System.out(332): 4980.0
02-12 19:01:40.845: I/System.out(332): 4979.0
02-12 19:01:40.845: I/System.out(332): 4978.0
02-12 19:01:40.855: I/System.out(332): 4977.0
02-12 19:01:40.855: I/System.out(332): 4976.0
02-12 19:01:40.855: I/System.out(332): 4975.0
02-12 19:01:40.855: I/System.out(332): 4974.0
02-12 19:01:40.855: I/System.out(332): 4973.0
02-12 19:01:40.865: I/System.out(332): 4972.0

The way you have arranged your loops is very cache unfriendly. 安排循环的方式对缓存非常不友好。 Make the inner loop pass over the width and the outer loop pass over the height. 使内循环越过宽度,外循环越过高度。

I don't think you can solve your problem in Java in this manner. 我认为您无法以这种方式解决Java问题。 There are overheads involved in executing Java statements (and method calls in particular) and doing this 8 million times - even if the instructions do almost nothing, like setting a value - will always be slow. 执行Java语句(尤其是方法调用)会涉及开销,并且这样做800万次-即使指令几乎不执行任何操作(如设置值),也总是很慢。

The standard answer would be to implement this function in C++ which is compiled instead of interpreted by the Java Virtual Machine, and hence should be faster. 标准答案是在C ++中实现此功能,该功能已编译而不是由Java虚拟机解释,因此应该更快。 It still probably won't be fast enough for a real time application; 对于实时应用而言,它可能仍然不够快。 you are still doing something 8 million times, just less each time. 您仍然在做800万次,每次都更少。

Doing peek and poke operations in Java across an entire 8 Mb pixel buffer isn't ever going to be fast. 用Java在整个8 Mb像素缓冲区中进行窥视和戳操作永远不会很快。 However, the designers of Java were aware of this issue, which is why they provide the extended 2D graphics API to often eliminate the need for for loops that execute a million times. 但是,Java的设计师意识到了这个问题,这就是为什么他们提供扩展的2D图形API来通常消除执行一百万次循环的需要的原因。 I would recommend having a closer look at the 2D API library, which is designed to set and read bits in a bitmap. 我建议您仔细看看2D API库,该库旨在设置和读取位图中的位。 Depending on what you are really trying to do, there may be much faster ways. 根据您的实际尝试,可能会有更快的方法。 You can set up a bitmap with transparent background, and write your changes to this bitmap, and write the bitmap on top of the previous image. 您可以设置具有透明背景的位图,并将更改写入该位图,然后将该位图写在上一张图像的顶部。 When you write bitmaps on top of bitmaps, you can set up a Paint class which will manipulate the impressed image (eg by applying variable transparency to it). 当您在位图的顶部编写位图时,可以设置一个Paint类,该类将处理印象深刻的图像(例如,通过对其施加可变的透明度)。 The Android 2d Graphics API also supports "Porter-Duff" compositing which provides calls which allow images to be combined in novel ways. Android 2d Graphics API还支持“ Porter-Duff”合成,该合成提供了允许以新颖方式组合图像的调用。 All of these are essentially performed in hardware, and hence are extremely fast. 所有这些基本上都在硬件中执行,因此非常快。

Without knowing what you are trying to do (exactly), I can't tell you how to do it more efficiently, but in a lot of cases there is a far more efficient implementation than the brute force approach you are using. 在不知道您到底想做什么的情况下,我无法告诉您如何更有效地执行此操作,但是在很多情况下,有一种比使用蛮力方法更有效的实现方式。 If there isn't, and you want this real time, I suspect you are stuffed. 如果没有,并且您想要实时显示,我怀疑您已经塞满了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM