选择随机像素的性能

Performance of selecting random pixels

我是从 Rust 开始学习的,来自一种更高级的语言,有些东西对我来说很新鲜。我正在尝试 select 图像中的随机黑色像素并将其填充为白色。继续直到图像的给定部分变成白色。我正在使用 image 板条箱进行像素操作。

我做了一个天真的实现。我创建了一个新向量,遍历图像中的所有像素,select 那些黑色的像素,然后使用 rand crate:

从向量中选择一个随机索引
fn seed_pixel(img: &RgbImage) -> [u32; 2] {
    let mut empty_pixels: Vec<[u32; 2]> = Vec::new();
    for (x, y, pixel) in img.enumerate_pixels() {
        if pixel[0] == 0 {
            empty_pixels.push([x, y])
        }
    }

    let mut rng = rand::thread_rng();
    return *empty_pixels.choose(&mut rng).unwrap();
}

可以,但是效率太离谱了。对于更大的图像(2000 像素 x 1000 像素),大约需要 0.17 秒,而且由于我需要多次执行此操作,因此加起来很快。有没有更有效的方法来做到这一点?关于这些问题,我可以阅读任何资源吗?

@ChristophRackwitz 已经提出了一个建议(保留 HashSet 个黑色像素,只计算一次),我想添加三个:

  • 如果您要用桶填充相邻像素,如果左侧的像素也是黑色,则不要添加像素
  • 不生成所有黑色像素的列表,而是从图像中的随机位置开始并从那里搜索下一个黑色像素(但确保按照与 enumerate_pixels 相同的顺序搜索return 像素 - 确保图像访问是线性内存扫描)
  • 不生成像素列表,但只记住一个像素。每当遇到黑色像素时,以 1 / number_of_found_black_pixels.
  • 的概率用找到的像素替换记住的像素

前两个想法改变了哪些像素 more/less 可能被选中(第一个偏向于黑色的高区域而不是宽阔的区域,第二个偏向于 non-black 像素的长延伸之后的黑色像素),所以你需要接受它。

您需要对自己进行基准测试,其中哪些是个好主意,以及您的 seed_pixel 功能是否真的是问题的核心。