可以在不到 2 遍的时间内将 Java 中的图像归一化?

Possible to normalize image in Java in less than 2 passes?

我想标准化图像 - 将图像中的每种颜色除以观察到的最暗颜色。目前,我通过在图像中循环两次来做到这一点:一次选择最暗的整体颜色,然后一次将每种颜色除以该颜色。

我不禁觉得必须有一种更有效的方法来做到这一点。一般来说,我对图像处理还比较陌生 - 我是否遗漏了一些明显的东西?

考虑只有一个 #000000 黑色像素的图像。您的第一遍将失败并被零除。您应该阅读图像格式规范并查找使用过的调色板或任何有用的数据并使用此公式:

new_color=(old_color-OLD_MIN)*(NEW_MAX-NEW_MIN)/(OLD_MAX-OLD_MIN)+NEW_MIN   

当您第一次遍历循环时,您可以复制每种颜色(我们称之为 copyOfImage 数组)。跟踪迄今为止观察到的最暗颜色及其索引。在通过循环迭代时复制每种颜色后,将原始图像中的这种颜色除以目前观察到的最暗颜色。当您找到新的最暗颜色时,您将替换旧颜色并跟踪新的最暗颜色的索引。

当您到达图像第一次迭代的末尾时,原始图像中的每种颜色都将除以我们达到该颜色时已知的最暗颜色。此外,您将获得最暗颜色所在位置的索引(我们称之为 darkestColorIndex)和最暗颜色以及编辑前的图像副本。

现在,从 darkestColorIndex 到图像末尾的所有颜色都将被正确编辑,因为从 darkestColorIndex 到图像末尾的所有颜色都将除以正确的最暗颜色。但是,您仍然需要将 0 编辑为 darkestColorIndex。因此,从 0 到 darkestColorIndex,将 originalImage[i] 替换为 copyOfImage[i]/darkestColor(其中 i 是当前索引)。

您根据图像的大小增加了 space 复杂度,如果在图像的最后一个索引处找到最暗的颜色,算法可能仍需要最多迭代图像 2 次.但是,如果在第一个索引中找到它,则只需要遍历它 1 次。平均而言,它可能必须遍历图像 1.5 次。