GithubHelp home page GithubHelp logo

Comments (9)

lessthanoptimal avatar lessthanoptimal commented on May 14, 2024

Having trouble understand. Can you clarify/give an example?

from boofcv.

thhart avatar thhart commented on May 14, 2024

Please check code below. It produces following output:

I8: 3
I16: 1
F32: 3

Either I misunderstand your concept or there is something wrong. I expect 1 for all types.

ImageBase singleBand = GeneralizedImageOps.createSingleBand(ImageDataType.I8, 10, 10); BufferedImage image = ConvertBufferedImage.convertTo(singleBand, null, false); System.err.println("I8: " + image.getSampleModel().getNumBands()); singleBand = GeneralizedImageOps.createSingleBand(ImageDataType.I16, 10, 10); image = ConvertBufferedImage.convertTo(singleBand, null, false); System.err.println("I16: " + image.getSampleModel().getNumBands()); singleBand = GeneralizedImageOps.createSingleBand(ImageDataType.F32, 10, 10); image = ConvertBufferedImage.convertTo(singleBand, null, false); System.err.println("F32: " + image.getSampleModel().getNumBands());

from boofcv.

lessthanoptimal avatar lessthanoptimal commented on May 14, 2024

Ok I understand. You've run into a case that was missed. I'm not sure what to do with F32 images. There really isn't an equivalent BufferedImage. Maybe TYPE_INT_RGB so that positive and negative numberse can be colorized? TYPE_BYTE_GRAY since it's just a single band? Throw an exception since there is no reasonable default?

from boofcv.

thhart avatar thhart commented on May 14, 2024

How about this:
I8 is mapped to TYPE_BYTE_GRAY
i16 is mapped to TYPE_USHORT_GRAY
F32 is mapped to TYPE_USHORT_GRAY

IMHO TYPE_INT_RGB is not better at all because it also has "only" 8 bit per color. So it is waste of memory then.

from boofcv.

lessthanoptimal avatar lessthanoptimal commented on May 14, 2024

what do you do with 16bit BufferedImages? It's a bit of a weird format. Most of the time I convert a float into a BufferedImage because I want to visualize it, so having an RGB format makes more sense

from boofcv.

lessthanoptimal avatar lessthanoptimal commented on May 14, 2024

I'm now leaning towards an exception since it's probably application specific what you want.

from boofcv.

thhart avatar thhart commented on May 14, 2024

Hi Peter, I have written a little test to understand the issue. As far as I can see the USHORT_GRAY is really the best option because it has 16 bit for the gray scale and really this information. INT_RGB reserves 8 bit per band so you have only a 8 bit gray scale there but three 9 times bigger data which makes it inefficient to handle/paint also.
I have created a sample gray scale gradient and pushed this into several BufferedImages as shown below.

gradient

TYPE_3BYTE_BGR, type: 5, bands: 3, bits: 24
first pixel value: 255.0
last pixel value: 0.0
TYPE_BYTE_GRAY, type: 10, bands: 1, bits: 8
first pixel value: 255.0
last pixel value: 0.0
TYPE_INT_RGB, type: 1, bands: 3, bits: 24
first pixel value: 255.0
last pixel value: 0.0
TYPE_USHORT_GRAY, type: 11, bands: 1, bits: 16
first pixel value: 65535.0
last pixel value: 0.0

    private void loadImages() throws IOException {
      BufferedImage read = ImageIO.read(new File("gradient.png"));
      printImageInfo("TYPE_3BYTE_BGR", read);
      ImageIO.write(read, "png", new File("typeCustom.png"));
      final BufferedImage gray = pushToFormat(read, BufferedImage.TYPE_BYTE_GRAY);
      printImageInfo("TYPE_BYTE_GRAY", gray);
      ImageIO.write(gray, "png", new File("typeByteGray.png"));
      final BufferedImage rgb = pushToFormat(read, BufferedImage.TYPE_INT_RGB);
      printImageInfo("TYPE_INT_RGB", rgb);
      ImageIO.write(rgb, "png", new File("typeIntRgb.png"));
      final BufferedImage ushort = pushToFormat(read, BufferedImage.TYPE_USHORT_GRAY);
      printImageInfo("TYPE_USHORT_GRAY", ushort);
      ImageIO.write(ushort, "png", new File("typeShortGray.png"));
   }
   private BufferedImage pushToFormat(BufferedImage read, int type) {
      final BufferedImage li = new BufferedImage(read.getWidth(), read.getHeight(), type);
      li.getGraphics().drawImage(read, 0,0, null);
      return li;
   }
   private void printImageInfo(String name, BufferedImage read) {
      System.err.println(name + ", type: " + read.getType() + ", bands: " + read.getSampleModel().getNumBands() + ", bits: " + read.getColorModel().getPixelSize());
      System.err.println("first pixel value: " + read.getData().getPixel(0,0, (double[])null)[0]);
      System.err.println("last pixel value: " + read.getData().getPixel(read.getWidth() - 1, 0, (double[])null)[0]);
   }

from boofcv.

lessthanoptimal avatar lessthanoptimal commented on May 14, 2024

But it doesn't handle negative numbers. I tend to use RGB for floats when
visualizing. I use one band for positive numbers and another for negative
numbers. Really what I'm proposing is that there's no default and an error
message will pop up with two suggestions, 16bit gray or RGB. Plus to take
advantage of that full change of numbers you would need to massage the data
first. People will often scale a gray input image to have intensities from
0 to 1 for floats. if it's feature intensity then the range is positive
and negative and has an arbitrary upper and lower limit.
ConvertBufferedImage doesn't do any of that. It's a dumb type cast.

On Fri, Jun 26, 2015 at 2:47 AM, thhart [email protected] wrote:

Hi Peter, I have written a little test to understand the issue. As far as
I can see the USHORT_GRAY is really the best option because it has 16 bit
for the gray scale and really this information. INT_RGB reserves 8 bit per
band so you have only a 8 bit gray scale there but three 9 times bigger
data which makes it inefficient to handle/paint also.
I have created a sample gray scale gradient and pushed this into several
BufferedImages as shown below.

[image: gradient]
https://cloud.githubusercontent.com/assets/2632538/8374781/7c6ade9e-1bf8-11e5-924d-7eea2c9dc7d1.png

TYPE_3BYTE_BGR, type: 5, bands: 3, bits: 24
first pixel value: 255.0
last pixel value: 0.0
TYPE_BYTE_GRAY, type: 10, bands: 1, bits: 8
first pixel value: 255.0
last pixel value: 0.0
TYPE_INT_RGB, type: 1, bands: 3, bits: 24
first pixel value: 255.0
last pixel value: 0.0
TYPE_USHORT_GRAY, type: 11, bands: 1, bits: 16
first pixel value: 65535.0
last pixel value: 0.0

private void loadImages() throws IOException {
  BufferedImage read = ImageIO.read(new File("gradient.png"));
  printImageInfo("TYPE_3BYTE_BGR", read);
  ImageIO.write(read, "png", new File("typeCustom.png"));
  final BufferedImage gray = pushToFormat(read, BufferedImage.TYPE_BYTE_GRAY);
  printImageInfo("TYPE_BYTE_GRAY", gray);
  ImageIO.write(gray, "png", new File("typeByteGray.png"));
  final BufferedImage rgb = pushToFormat(read, BufferedImage.TYPE_INT_RGB);
  printImageInfo("TYPE_INT_RGB", rgb);
  ImageIO.write(rgb, "png", new File("typeIntRgb.png"));
  final BufferedImage ushort = pushToFormat(read, BufferedImage.TYPE_USHORT_GRAY);
  printImageInfo("TYPE_USHORT_GRAY", ushort);
  ImageIO.write(ushort, "png", new File("/tmp/typeShortGray.png"));

}

private BufferedImage pushToFormat(BufferedImage read, int type) {
final BufferedImage li = new BufferedImage(read.getWidth(), read.getHeight(), type);
li.getGraphics().drawImage(read, 0,0, null);
return li;
}

private void printImageInfo(String name, BufferedImage read) {
System.err.println(name + ", type: " + read.getType() + ", bands: " + read.getSampleModel().getNumBands() + ", bits: " + read.getColorModel().getPixelSize());
System.err.println("first pixel value: " + read.getData().getPixel(0,0, (double[])null)[0]);
System.err.println("last pixel value: " + read.getData().getPixel(read.getWidth() - 1, 0, (double[])null)[0]);
}


Reply to this email directly or view it on GitHub
#28 (comment)
.

"Now, now my good man, this is no time for making enemies." — Voltaire
(1694-1778), on his deathbed in response to a priest asking that he
renounce Satan.

from boofcv.

lessthanoptimal avatar lessthanoptimal commented on May 14, 2024

Well that broke a lot of stuff. For maintaining some backwards compatibility TYPE_BYTE_GRAY seems to be the best default.

  1. It's single band like the input
  2. Has the implicit assumption that the input can be converted into a BufferedImage, which is most often the case if the pixel value range is 0 to 255
  3. TYPE_USHORT_GRAY rendered images way too dark

If you need anything special just provide your own BufferedImage instead of null. That's what everything in VisualizeImageData does, which is where I put all the application specific convert for visualization.

from boofcv.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.