Why do I get this particular color pattern when using rand()?

后端 未结 2 380
悲哀的现实
悲哀的现实 2021-01-29 19:24

I tried to create an image file, like this:

uint8_t raw_r[pixel_width][pixel_height];
uint8_t raw_g[pixel_width][pixel_height];
uint8_t raw_b[pixel_width][pixel_         


        
2条回答
  •  梦毁少年i
    2021-01-29 19:45

    Many of the calculations that you're doing in your code won't lead to truly random values. Those sharp lines that you're seeing correspond to places where the relative values of your x and y coordinates trade with one another, and when that happens you're using fundamentally different formulas. For example, computing (x + y) % rand() will generally give you back the value x + y, since rand() will (usually) return a number much, much bigger than x + y given that RAND_MAX is usually a fairly large number. In that sense, you shouldn't expect to get back white noise, since the algorithm you're using to generate things is biased away from generating white noise. If you want white noise, just set each pixel to rand(). If you'd like a nice pattern like the one you have above, but with a little bit of randomness tossed in here and there, keep using the code that you have written.

    Additionally, as @pm100 has noted in the comments, the rand function doesn't return truly random numbers, and instead uses a pseudorandom function to produce it values. The default implementation of rand on many systems uses a type of pseudorandom number generator called a linear congruential generator that produces numbers that in short bursts can appear random, but which are decidedly nonrandom in practice. For example, here's an animation from Wikipedia showing how random points in space chosen with a linear congruential generator end up falling into a fixed number of hyperplanes:

    The image

    If you replace x, y, and z coordinates with R, G, and B coordinates, this looks remarkably similar to the output being produced by your program. I suspect that this is probably not the core issue here, since the other aspect mentioned above will probably be much more pronounced.

    If you're looking for higher-quality random numbers, you'll need to use a higher-quality random source. In C, you could consider reading bytes from /dev/urandom/ (on a Linux-like system), which gives fairly uniformly random values. C++ now has a number of good random-number generation primitives in its standard libraries, if that's available to you.

提交回复
热议问题