-
Notifications
You must be signed in to change notification settings - Fork 633
Improvements related to image dithering and low-bit-depth output #3141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
We have options that allow adding random dither to images before output, which when converting float images to 8 bit or less, can greatly reduce the appearance of banding artifacts. This PR makes a number of improvements: * When the option is used, it should apply dither any time you are reducing an image with > 8 bits/channel to an output with <= 8 bits/channel. Not just from float/half, but also from uint16, for example. (When outputting > 8 bits per channel, there are enough gradations that you tend not to see banding artifacts, so dithering is not necessary for 16 bit output, even if coming from a float data source.) * Change the actual dither we use to blue noise. The old dither just used a hash to add uniformly distributed random numbers to each pixel value before quantization, completely uncorrelated from pixel to pixel. Blue noise is specially constructed to still have a uniform distribution of the output range, but it ensures that spatially, similar values are distributed as far away from each other as possible, rather than having similar values sometimes clumped together. The result is a MUCH NICER appearance. * Of course, this means the we needed to store a blue noise table in the library, and some access routines for it. We incorporate a public domain blue noise texture as a table. * ImageBufAlgo::noise() and `oiiotool --noise` now take "blue" as a noise name to return blue noise. Also, make "white" the (preferred) synonym for "uniform" (to disambiguate the fact that both white and blue noise are uniformly distributed; the difference is that white is independently random for each pixel, whereas blue shapes the spectrum to favor high frequencies, making it better suited for dithering and sampling purposes. * ImageBufAlgo::bluenoise_image() returns a reference to a stored periodic blue noise image. * oiiotool -d would let you say "uint10" or "uint12" to indicate 10 or 12 bit output (for formats that support it), but had no way to ask for less than 8 bit output (for example, TIFF supports that). So we add "uint6", "uint4", "uint2", "uint1" as recognized names for the `-d` option in those rare cases when you specifically want to produce a low bit depth file. And furthermore, if you ask for `--dither` when using lower bit depths, the dither amplitude is adjusted to be right sized for the bit depth you are using. * Many format output modules that support 8 bit output honor the option to dither the output, but in the "built-in plugins" chapter of the docs, most did not list this option in the section that describes which special output options it knows. So now we've added this to the docs for all the output plugins that did support it.
lgritz
added a commit
to lgritz/OpenImageIO
that referenced
this pull request
Oct 24, 2021
…demySoftwareFoundation#3141) We have options that allow adding random dither to images before output, which when converting float images to 8 bit or less, can greatly reduce the appearance of banding artifacts. This PR makes a number of improvements: * When the option is used, it should apply dither any time you are reducing an image with > 8 bits/channel to an output with <= 8 bits/channel. Not just from float/half, but also from uint16, for example. (When outputting > 8 bits per channel, there are enough gradations that you tend not to see banding artifacts, so dithering is not necessary for 16 bit output, even if coming from a float data source.) * Change the actual dither we use to blue noise. The old dither just used a hash to add uniformly distributed random numbers to each pixel value before quantization, completely uncorrelated from pixel to pixel. Blue noise is specially constructed to still have a uniform distribution of the output range, but it ensures that spatially, similar values are distributed as far away from each other as possible, rather than having similar values sometimes clumped together. The result is a MUCH NICER appearance. * Of course, this means the we needed to store a blue noise table in the library, and some access routines for it. We incorporate a public domain blue noise texture as a table. * ImageBufAlgo::noise() and `oiiotool --noise` now take "blue" as a noise name to return blue noise. Also, make "white" the (preferred) synonym for "uniform" (to disambiguate the fact that both white and blue noise are uniformly distributed; the difference is that white is independently random for each pixel, whereas blue shapes the spectrum to favor high frequencies, making it better suited for dithering and sampling purposes. * ImageBufAlgo::bluenoise_image() returns a reference to a stored periodic blue noise image. * oiiotool -d would let you say "uint10" or "uint12" to indicate 10 or 12 bit output (for formats that support it), but had no way to ask for less than 8 bit output (for example, TIFF supports that). So we add "uint6", "uint4", "uint2", "uint1" as recognized names for the `-d` option in those rare cases when you specifically want to produce a low bit depth file. And furthermore, if you ask for `--dither` when using lower bit depths, the dither amplitude is adjusted to be right sized for the bit depth you are using. * Many format output modules that support 8 bit output honor the option to dither the output, but in the "built-in plugins" chapter of the docs, most did not list this option in the section that describes which special output options it knows. So now we've added this to the docs for all the output plugins that did support it.
lgritz
added a commit
to lgritz/OpenImageIO
that referenced
this pull request
Nov 7, 2021
…demySoftwareFoundation#3141) We have options that allow adding random dither to images before output, which when converting float images to 8 bit or less, can greatly reduce the appearance of banding artifacts. This PR makes a number of improvements: * When the option is used, it should apply dither any time you are reducing an image with > 8 bits/channel to an output with <= 8 bits/channel. Not just from float/half, but also from uint16, for example. (When outputting > 8 bits per channel, there are enough gradations that you tend not to see banding artifacts, so dithering is not necessary for 16 bit output, even if coming from a float data source.) * Change the actual dither we use to blue noise. The old dither just used a hash to add uniformly distributed random numbers to each pixel value before quantization, completely uncorrelated from pixel to pixel. Blue noise is specially constructed to still have a uniform distribution of the output range, but it ensures that spatially, similar values are distributed as far away from each other as possible, rather than having similar values sometimes clumped together. The result is a MUCH NICER appearance. * Of course, this means the we needed to store a blue noise table in the library, and some access routines for it. We incorporate a public domain blue noise texture as a table. * ImageBufAlgo::noise() and `oiiotool --noise` now take "blue" as a noise name to return blue noise. Also, make "white" the (preferred) synonym for "uniform" (to disambiguate the fact that both white and blue noise are uniformly distributed; the difference is that white is independently random for each pixel, whereas blue shapes the spectrum to favor high frequencies, making it better suited for dithering and sampling purposes. * ImageBufAlgo::bluenoise_image() returns a reference to a stored periodic blue noise image. * oiiotool -d would let you say "uint10" or "uint12" to indicate 10 or 12 bit output (for formats that support it), but had no way to ask for less than 8 bit output (for example, TIFF supports that). So we add "uint6", "uint4", "uint2", "uint1" as recognized names for the `-d` option in those rare cases when you specifically want to produce a low bit depth file. And furthermore, if you ask for `--dither` when using lower bit depths, the dither amplitude is adjusted to be right sized for the bit depth you are using. * Many format output modules that support 8 bit output honor the option to dither the output, but in the "built-in plugins" chapter of the docs, most did not list this option in the section that describes which special output options it knows. So now we've added this to the docs for all the output plugins that did support it.
lgritz
added a commit
to lgritz/OpenImageIO
that referenced
this pull request
Nov 21, 2021
…demySoftwareFoundation#3141) We have options that allow adding random dither to images before output, which when converting float images to 8 bit or less, can greatly reduce the appearance of banding artifacts. This PR makes a number of improvements: * When the option is used, it should apply dither any time you are reducing an image with > 8 bits/channel to an output with <= 8 bits/channel. Not just from float/half, but also from uint16, for example. (When outputting > 8 bits per channel, there are enough gradations that you tend not to see banding artifacts, so dithering is not necessary for 16 bit output, even if coming from a float data source.) * Change the actual dither we use to blue noise. The old dither just used a hash to add uniformly distributed random numbers to each pixel value before quantization, completely uncorrelated from pixel to pixel. Blue noise is specially constructed to still have a uniform distribution of the output range, but it ensures that spatially, similar values are distributed as far away from each other as possible, rather than having similar values sometimes clumped together. The result is a MUCH NICER appearance. * Of course, this means the we needed to store a blue noise table in the library, and some access routines for it. We incorporate a public domain blue noise texture as a table. * ImageBufAlgo::noise() and `oiiotool --noise` now take "blue" as a noise name to return blue noise. Also, make "white" the (preferred) synonym for "uniform" (to disambiguate the fact that both white and blue noise are uniformly distributed; the difference is that white is independently random for each pixel, whereas blue shapes the spectrum to favor high frequencies, making it better suited for dithering and sampling purposes. * ImageBufAlgo::bluenoise_image() returns a reference to a stored periodic blue noise image. * oiiotool -d would let you say "uint10" or "uint12" to indicate 10 or 12 bit output (for formats that support it), but had no way to ask for less than 8 bit output (for example, TIFF supports that). So we add "uint6", "uint4", "uint2", "uint1" as recognized names for the `-d` option in those rare cases when you specifically want to produce a low bit depth file. And furthermore, if you ask for `--dither` when using lower bit depths, the dither amplitude is adjusted to be right sized for the bit depth you are using. * Many format output modules that support 8 bit output honor the option to dither the output, but in the "built-in plugins" chapter of the docs, most did not list this option in the section that describes which special output options it knows. So now we've added this to the docs for all the output plugins that did support it.
lgritz
added a commit
to lgritz/OpenImageIO
that referenced
this pull request
Nov 22, 2021
…demySoftwareFoundation#3141) We have options that allow adding random dither to images before output, which when converting float images to 8 bit or less, can greatly reduce the appearance of banding artifacts. This PR makes a number of improvements: * When the option is used, it should apply dither any time you are reducing an image with > 8 bits/channel to an output with <= 8 bits/channel. Not just from float/half, but also from uint16, for example. (When outputting > 8 bits per channel, there are enough gradations that you tend not to see banding artifacts, so dithering is not necessary for 16 bit output, even if coming from a float data source.) * Change the actual dither we use to blue noise. The old dither just used a hash to add uniformly distributed random numbers to each pixel value before quantization, completely uncorrelated from pixel to pixel. Blue noise is specially constructed to still have a uniform distribution of the output range, but it ensures that spatially, similar values are distributed as far away from each other as possible, rather than having similar values sometimes clumped together. The result is a MUCH NICER appearance. * Of course, this means the we needed to store a blue noise table in the library, and some access routines for it. We incorporate a public domain blue noise texture as a table. * ImageBufAlgo::noise() and `oiiotool --noise` now take "blue" as a noise name to return blue noise. Also, make "white" the (preferred) synonym for "uniform" (to disambiguate the fact that both white and blue noise are uniformly distributed; the difference is that white is independently random for each pixel, whereas blue shapes the spectrum to favor high frequencies, making it better suited for dithering and sampling purposes. * ImageBufAlgo::bluenoise_image() returns a reference to a stored periodic blue noise image. * oiiotool -d would let you say "uint10" or "uint12" to indicate 10 or 12 bit output (for formats that support it), but had no way to ask for less than 8 bit output (for example, TIFF supports that). So we add "uint6", "uint4", "uint2", "uint1" as recognized names for the `-d` option in those rare cases when you specifically want to produce a low bit depth file. And furthermore, if you ask for `--dither` when using lower bit depths, the dither amplitude is adjusted to be right sized for the bit depth you are using. * Many format output modules that support 8 bit output honor the option to dither the output, but in the "built-in plugins" chapter of the docs, most did not list this option in the section that describes which special output options it knows. So now we've added this to the docs for all the output plugins that did support it.
lgritz
added a commit
to lgritz/OpenImageIO
that referenced
this pull request
Nov 29, 2021
…demySoftwareFoundation#3141) We have options that allow adding random dither to images before output, which when converting float images to 8 bit or less, can greatly reduce the appearance of banding artifacts. This PR makes a number of improvements: * When the option is used, it should apply dither any time you are reducing an image with > 8 bits/channel to an output with <= 8 bits/channel. Not just from float/half, but also from uint16, for example. (When outputting > 8 bits per channel, there are enough gradations that you tend not to see banding artifacts, so dithering is not necessary for 16 bit output, even if coming from a float data source.) * Change the actual dither we use to blue noise. The old dither just used a hash to add uniformly distributed random numbers to each pixel value before quantization, completely uncorrelated from pixel to pixel. Blue noise is specially constructed to still have a uniform distribution of the output range, but it ensures that spatially, similar values are distributed as far away from each other as possible, rather than having similar values sometimes clumped together. The result is a MUCH NICER appearance. * Of course, this means the we needed to store a blue noise table in the library, and some access routines for it. We incorporate a public domain blue noise texture as a table. * ImageBufAlgo::noise() and `oiiotool --noise` now take "blue" as a noise name to return blue noise. Also, make "white" the (preferred) synonym for "uniform" (to disambiguate the fact that both white and blue noise are uniformly distributed; the difference is that white is independently random for each pixel, whereas blue shapes the spectrum to favor high frequencies, making it better suited for dithering and sampling purposes. * ImageBufAlgo::bluenoise_image() returns a reference to a stored periodic blue noise image. * oiiotool -d would let you say "uint10" or "uint12" to indicate 10 or 12 bit output (for formats that support it), but had no way to ask for less than 8 bit output (for example, TIFF supports that). So we add "uint6", "uint4", "uint2", "uint1" as recognized names for the `-d` option in those rare cases when you specifically want to produce a low bit depth file. And furthermore, if you ask for `--dither` when using lower bit depths, the dither amplitude is adjusted to be right sized for the bit depth you are using. * Many format output modules that support 8 bit output honor the option to dither the output, but in the "built-in plugins" chapter of the docs, most did not list this option in the section that describes which special output options it knows. So now we've added this to the docs for all the output plugins that did support it.
lgritz
added a commit
to lgritz/OpenImageIO
that referenced
this pull request
Nov 30, 2021
…demySoftwareFoundation#3141) We have options that allow adding random dither to images before output, which when converting float images to 8 bit or less, can greatly reduce the appearance of banding artifacts. This PR makes a number of improvements: * When the option is used, it should apply dither any time you are reducing an image with > 8 bits/channel to an output with <= 8 bits/channel. Not just from float/half, but also from uint16, for example. (When outputting > 8 bits per channel, there are enough gradations that you tend not to see banding artifacts, so dithering is not necessary for 16 bit output, even if coming from a float data source.) * Change the actual dither we use to blue noise. The old dither just used a hash to add uniformly distributed random numbers to each pixel value before quantization, completely uncorrelated from pixel to pixel. Blue noise is specially constructed to still have a uniform distribution of the output range, but it ensures that spatially, similar values are distributed as far away from each other as possible, rather than having similar values sometimes clumped together. The result is a MUCH NICER appearance. * Of course, this means the we needed to store a blue noise table in the library, and some access routines for it. We incorporate a public domain blue noise texture as a table. * ImageBufAlgo::noise() and `oiiotool --noise` now take "blue" as a noise name to return blue noise. Also, make "white" the (preferred) synonym for "uniform" (to disambiguate the fact that both white and blue noise are uniformly distributed; the difference is that white is independently random for each pixel, whereas blue shapes the spectrum to favor high frequencies, making it better suited for dithering and sampling purposes. * ImageBufAlgo::bluenoise_image() returns a reference to a stored periodic blue noise image. * oiiotool -d would let you say "uint10" or "uint12" to indicate 10 or 12 bit output (for formats that support it), but had no way to ask for less than 8 bit output (for example, TIFF supports that). So we add "uint6", "uint4", "uint2", "uint1" as recognized names for the `-d` option in those rare cases when you specifically want to produce a low bit depth file. And furthermore, if you ask for `--dither` when using lower bit depths, the dither amplitude is adjusted to be right sized for the bit depth you are using. * Many format output modules that support 8 bit output honor the option to dither the output, but in the "built-in plugins" chapter of the docs, most did not list this option in the section that describes which special output options it knows. So now we've added this to the docs for all the output plugins that did support it.
lgritz
added a commit
to lgritz/OpenImageIO
that referenced
this pull request
Dec 1, 2021
…demySoftwareFoundation#3141) We have options that allow adding random dither to images before output, which when converting float images to 8 bit or less, can greatly reduce the appearance of banding artifacts. This PR makes a number of improvements: * When the option is used, it should apply dither any time you are reducing an image with > 8 bits/channel to an output with <= 8 bits/channel. Not just from float/half, but also from uint16, for example. (When outputting > 8 bits per channel, there are enough gradations that you tend not to see banding artifacts, so dithering is not necessary for 16 bit output, even if coming from a float data source.) * Change the actual dither we use to blue noise. The old dither just used a hash to add uniformly distributed random numbers to each pixel value before quantization, completely uncorrelated from pixel to pixel. Blue noise is specially constructed to still have a uniform distribution of the output range, but it ensures that spatially, similar values are distributed as far away from each other as possible, rather than having similar values sometimes clumped together. The result is a MUCH NICER appearance. * Of course, this means the we needed to store a blue noise table in the library, and some access routines for it. We incorporate a public domain blue noise texture as a table. * ImageBufAlgo::noise() and `oiiotool --noise` now take "blue" as a noise name to return blue noise. Also, make "white" the (preferred) synonym for "uniform" (to disambiguate the fact that both white and blue noise are uniformly distributed; the difference is that white is independently random for each pixel, whereas blue shapes the spectrum to favor high frequencies, making it better suited for dithering and sampling purposes. * ImageBufAlgo::bluenoise_image() returns a reference to a stored periodic blue noise image. * oiiotool -d would let you say "uint10" or "uint12" to indicate 10 or 12 bit output (for formats that support it), but had no way to ask for less than 8 bit output (for example, TIFF supports that). So we add "uint6", "uint4", "uint2", "uint1" as recognized names for the `-d` option in those rare cases when you specifically want to produce a low bit depth file. And furthermore, if you ask for `--dither` when using lower bit depths, the dither amplitude is adjusted to be right sized for the bit depth you are using. * Many format output modules that support 8 bit output honor the option to dither the output, but in the "built-in plugins" chapter of the docs, most did not list this option in the section that describes which special output options it knows. So now we've added this to the docs for all the output plugins that did support it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
We have options that allow adding random dither to images before
output, which when converting float images to 8 bit or less, can
greatly reduce the appearance of banding artifacts. This PR makes a
number of improvements:
When the option is used, it should apply dither any time you are
reducing an image with > 8 bits/channel to an output with <= 8
bits/channel. Not just from float/half, but also from uint16, for
example. (When outputting > 8 bits per channel, there are enough
gradations that you tend not to see banding artifacts, so dithering
is not necessary for 16 bit output, even if coming from a float data
source.)
Change the actual dither we use to blue noise. The old dither just
used a hash to add uniformly distributed random numbers to each
pixel value before quantization, completely uncorrelated from pixel
to pixel. Blue noise is specially constructed to still have a
uniform distribution of the output range, but it ensures that
spatially, similar values are distributed as far away from each
other as possible, rather than having similar values sometimes
clumped together. The result is a MUCH NICER appearance.
Of course, this means the we needed to store a blue noise table in
the library, and some access routines for it. We incorporate a
public domain blue noise texture as a table.
ImageBufAlgo::noise() and
oiiotool --noise
now take "blue" as anoise name to return blue noise. Also, make "white" the (preferred)
synonym for "uniform" (to disambiguate the fact that both white and
blue noise are uniformly distributed; the difference is that white
is independently random for each pixel, whereas blue shapes the
spectrum to favor high frequencies, making it better suited for
dithering and sampling purposes.
ImageBufAlgo::bluenoise_image() returns a reference to a stored
periodic blue noise image.
oiiotool -d would let you say "uint10" or "uint12" to indicate 10 or
12 bit output (for formats that support it), but had no way to ask
for less than 8 bit output (for example, TIFF supports that). So we
add "uint6", "uint4", "uint2", "uint1" as recognized names for the
-d
option in those rare cases when you specifically want toproduce a low bit depth file. And furthermore, if you ask for
--dither
when using lower bit depths, the dither amplitude isadjusted to be right sized for the bit depth you are using.
Many format output modules that support 8 bit output honor the
option to dither the output, but in the "built-in plugins" chapter
of the docs, most did not list this option in the section that
describes which special output options it knows. So now we've added
this to the docs for all the output plugins that did support it.