solution to Program 4.3?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

solution to Program 4.3?

Yisong Zhen
Dear all,

I just read the book 'Digital Image Processing - An Algorithmic
Introduction using Java'.  There is an assignment on program 4.3 which ask
to finish a task to compute the histogram of 8-bit-gray-scale image and
display it.. I finished the left part and completed the code to create the
histogram image. But failed (compiled successfully) and the result did not
show histogram as expected. Here is the code:

the red colored is my own code for this project. Since my understanding of
Java and imageJ is limited, please give me some suggestions of why there is
no output image of histogram. Thanks in advance.

Yisong

//

import ij.ImagePlus;
import ij.plugin.filter.PlugInFilter;
import ij.process.ByteProcessor;
import ij.process.ImageProcessor;

/*
 * This plugin demonstrates how to create and display a
 * new byte image
 */

public class Create_New_Image implements PlugInFilter {
String title = null;

public int setup(String arg, ImagePlus im) {
title = im.getTitle();
 return DOES_8G + NO_CHANGES;
}

public void run(ImageProcessor ip) {
 int w = 256;
int h = 100;
int[] hist = ip.getHistogram();
     int[] hist2= new int[256];
 ImageProcessor histIp = new ByteProcessor(w, h);
 histIp.setValue(255); // white = 255
histIp.fill();

// draw the histogram values as black bars in ip2 here,
// for example, using histIp.putpixel(u,v,0)
 // ...
int max = hist[0];
for (int i =1;i<hist.length;i++) {
 if(hist[i] > max) {
max = hist[i];
 }
}
 // shrink to 0.8 of the original;
for(int i=0;i<hist2.length;i++){
 hist2[i]= (hist[i]/max)*4*100/5;
}
 for(int i=0;i<hist2.length;i++){
 for(int j= 100 - hist2[i];j<h;j++){
histIp.putPixel(i,hist2[j],0);
 }
 }
 // display histogram:
String hTitle = "Histogram of " + title;
 ImagePlus histIm = new ImagePlus(hTitle, histIp);
histIm.show();
//histIm.updateAndDraw();
 }
}

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: solution to Program 4.3?

Rasband, Wayne (NIH/NIMH) [E]
On Jul 20, 2013, at 8:20 AM, Yisong Zhen wrote:

> Dear all,
>
> I just read the book 'Digital Image Processing - An Algorithmic
> Introduction using Java'.  There is an assignment on program 4.3 which ask
> to finish a task to compute the histogram of 8-bit-gray-scale image and
> display it.. I finished the left part and completed the code to create the
> histogram image. But failed (compiled successfully) and the result did not
> show histogram as expected. Here is the code:
>
> the red colored is my own code for this project. Since my understanding of
> Java and imageJ is limited, please give me some suggestions of why there is
> no output image of histogram. Thanks in advance.

One reason there is no output is that the plugin is drawing in white on a white background. Here is a version that works with all image types. It uses the histogram returned by getStatistics() because that histogram always has 256 bins. It implements the PlugIn interface because it is not a filter and because the PlugIn interface is simpler.

import ij.*;
import ij.plugin.PlugIn;
import ij.process.*;
import java.awt.Color;

public class Create_New_Image implements PlugIn {

    public void run(String arg) {
        ImagePlus imp = IJ.getImage();
        int w = 256;
        int h = 100;
        ImageStatistics stats = imp.getStatistics();
        int[] hist = stats.histogram;
        ImageProcessor histIp = new ByteProcessor(w, h);
        histIp.setColor(Color.white);
        histIp.fill();
        histIp.setColor(Color.black);
        int max = hist[stats.mode];
        double scale = (double)h/max;
        for (int i=0; i<hist.length; i++)
            histIp.drawLine(i, h, i, h-(int)(hist[i]*scale));
        String title = "Histogram of " + imp.getTitle();
        new ImagePlus(title, histIp).show();
    }

}


> import ij.ImagePlus;
> import ij.plugin.filter.PlugInFilter;
> import ij.process.ByteProcessor;
> import ij.process.ImageProcessor;
>
> /*
> * This plugin demonstrates how to create and display a
> * new byte image
> */
>
> public class Create_New_Image implements PlugInFilter {
> String title = null;
>
> public int setup(String arg, ImagePlus im) {
> title = im.getTitle();
> return DOES_8G + NO_CHANGES;
> }
>
> public void run(ImageProcessor ip) {
> int w = 256;
> int h = 100;
> int[] hist = ip.getHistogram();
>     int[] hist2= new int[256];
> ImageProcessor histIp = new ByteProcessor(w, h);
> histIp.setValue(255); // white = 255
> histIp.fill();
>
> // draw the histogram values as black bars in ip2 here,
> // for example, using histIp.putpixel(u,v,0)
> // ...
> int max = hist[0];
> for (int i =1;i<hist.length;i++) {
> if(hist[i] > max) {
> max = hist[i];
> }
> }
> // shrink to 0.8 of the original;
> for(int i=0;i<hist2.length;i++){
> hist2[i]= (hist[i]/max)*4*100/5;
> }
> for(int i=0;i<hist2.length;i++){
> for(int j= 100 - hist2[i];j<h;j++){
> histIp.putPixel(i,hist2[j],0);
> }
> }
> // display histogram:
> String hTitle = "Histogram of " + title;
> ImagePlus histIm = new ImagePlus(hTitle, histIp);
> histIm.show();
> //histIm.updateAndDraw();
> }
> }

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: solution to Program 4.3?

Yisong Zhen
Dear Wayne,

The program4.3 in the book does set the background to white
(histIp.setValue(255)), but I then change the pixel value of the
corresponding histogram  by using the method , histIp.putPixel(u,v,0). My
understanding is that in this way, I change white color to black in
correspond region. You code about this histogram task is beautiful, but I
do want to know why I am wrong. Any further suggestion is greatly
appreciated.

Yisong

On Sun, Jul 21, 2013 at 3:21 AM, Rasband, Wayne (NIH/NIMH) [E] <
[hidden email]> wrote:

> On Jul 20, 2013, at 8:20 AM, Yisong Zhen wrote:
>
> > Dear all,
> >
> > I just read the book 'Digital Image Processing - An Algorithmic
> > Introduction using Java'.  There is an assignment on program 4.3 which
> ask
> > to finish a task to compute the histogram of 8-bit-gray-scale image and
> > display it.. I finished the left part and completed the code to create
> the
> > histogram image. But failed (compiled successfully) and the result did
> not
> > show histogram as expected. Here is the code:
> >
> > the red colored is my own code for this project. Since my understanding
> of
> > Java and imageJ is limited, please give me some suggestions of why there
> is
> > no output image of histogram. Thanks in advance.
>
> One reason there is no output is that the plugin is drawing in white on a
> white background. Here is a version that works with all image types. It
> uses the histogram returned by getStatistics() because that histogram
> always has 256 bins. It implements the PlugIn interface because it is not a
> filter and because the PlugIn interface is simpler.
>
> import ij.*;
> import ij.plugin.PlugIn;
> import ij.process.*;
> import java.awt.Color;
>
> public class Create_New_Image implements PlugIn {
>
>     public void run(String arg) {
>         ImagePlus imp = IJ.getImage();
>         int w = 256;
>         int h = 100;
>         ImageStatistics stats = imp.getStatistics();
>         int[] hist = stats.histogram;
>         ImageProcessor histIp = new ByteProcessor(w, h);
>         histIp.setColor(Color.white);
>         histIp.fill();
>         histIp.setColor(Color.black);
>         int max = hist[stats.mode];
>         double scale = (double)h/max;
>         for (int i=0; i<hist.length; i++)
>             histIp.drawLine(i, h, i, h-(int)(hist[i]*scale));
>         String title = "Histogram of " + imp.getTitle();
>         new ImagePlus(title, histIp).show();
>     }
>
> }
>
>
> > import ij.ImagePlus;
> > import ij.plugin.filter.PlugInFilter;
> > import ij.process.ByteProcessor;
> > import ij.process.ImageProcessor;
> >
> > /*
> > * This plugin demonstrates how to create and display a
> > * new byte image
> > */
> >
> > public class Create_New_Image implements PlugInFilter {
> > String title = null;
> >
> > public int setup(String arg, ImagePlus im) {
> > title = im.getTitle();
> > return DOES_8G + NO_CHANGES;
> > }
> >
> > public void run(ImageProcessor ip) {
> > int w = 256;
> > int h = 100;
> > int[] hist = ip.getHistogram();
> >     int[] hist2= new int[256];
> > ImageProcessor histIp = new ByteProcessor(w, h);
> > histIp.setValue(255); // white = 255
> > histIp.fill();
> >
> > // draw the histogram values as black bars in ip2 here,
> > // for example, using histIp.putpixel(u,v,0)
> > // ...
> > int max = hist[0];
> > for (int i =1;i<hist.length;i++) {
> > if(hist[i] > max) {
> > max = hist[i];
> > }
> > }
> > // shrink to 0.8 of the original;
> > for(int i=0;i<hist2.length;i++){
> > hist2[i]= (hist[i]/max)*4*100/5;
> > }
> > for(int i=0;i<hist2.length;i++){
> > for(int j= 100 - hist2[i];j<h;j++){
> > histIp.putPixel(i,hist2[j],0);
> > }
> > }
> > // display histogram:
> > String hTitle = "Histogram of " + title;
> > ImagePlus histIm = new ImagePlus(hTitle, histIp);
> > histIm.show();
> > //histIm.updateAndDraw();
> > }
> > }
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: solution to Program 4.3?

Burger Wilhelm
Hello Yisong,

your code contained two errors (the complete plugin is listed below):

a) The expression (hist[i] / max) * 4 * 100 / 5 is evaluated left to right and with integer arithmetic, since all operands are of type int. Thus the sub-expression hist[i] / max evaluates to either 0 (mostly) or 1, because hist[i] <= max (a very frequent mistake in Java, also see the related note on p. 457 in the book).

b) For drawing the histogram bars with putPixel() you should use putPixel(i, j, 0) instead of putPixel(i, hist2[j], 0), i.e., modify the pixel at position (i, j).

Note that this is only meant as an instructional example, the version suggested by Wayne is of course more compact and efficient. If you have additional questions on issues concerning our book please feel free to send them directly to [hidden email].

Hope this helps.
--Wilhelm

// -------------------------------------------------------------
import ij.ImagePlus;
import ij.plugin.filter.PlugInFilter;
import ij.process.ByteProcessor;
import ij.process.ImageProcessor;
public class Create_New_Image implements PlugInFilter {
 String title = null;
 public int setup(String arg, ImagePlus im) {
  title = im.getTitle();
  return DOES_8G + NO_CHANGES;
 }
 public void run(ImageProcessor ip) {
  int w = 256;
  int h = 100;
  int[] hist = ip.getHistogram();
  int[] hist2 = new int[256];
  ImageProcessor histIp = new ByteProcessor(w, h);
  histIp.setValue(255); // white = 255
  histIp.fill();
  // draw the histogram values as black bars in ip2 here,
  // for example, using histIp.putpixel(u,v,0)
  // ...
  int max = hist[0];
  for (int i = 1; i < hist.length; i++) {
   if (hist[i] > max) {
    max = hist[i];
   }
  }
  // shrink to 0.8 of the original;
  for (int i = 0; i < hist2.length; i++) {
   //hist2[i] = (hist[i] / max) * 4 * 100 / 5;
   hist2[i] = hist[i]  * 100 / max; // <---- CHANGED
  }
  for (int i = 0; i < hist2.length; i++) {
   for (int j = 100 - hist2[i]; j < h; j++) {
    //histIp.putPixel(i,hist2[j],0);
    histIp.putPixel(i, j, 0); // <---- CHANGED
   }
  }
  // display histogram:
  String hTitle = "Histogram of " + title;
  ImagePlus histIm = new ImagePlus(hTitle, histIp);
  histIm.show();
 }
}
// -------------------------------------------------------------


________________________________________
From: ImageJ Interest Group [[hidden email]] On Behalf Of Yisong Zhen [[hidden email]]
Sent: Sunday, July 21, 2013 04:26
To: [hidden email]
Subject: Re: solution to Program 4.3?

Dear Wayne,

The program4.3 in the book does set the background to white
(histIp.setValue(255)), but I then change the pixel value of the
corresponding histogram  by using the method , histIp.putPixel(u,v,0). My
understanding is that in this way, I change white color to black in
correspond region. You code about this histogram task is beautiful, but I
do want to know why I am wrong. Any further suggestion is greatly
appreciated.

Yisong

On Sun, Jul 21, 2013 at 3:21 AM, Rasband, Wayne (NIH/NIMH) [E] <
[hidden email]> wrote:

> On Jul 20, 2013, at 8:20 AM, Yisong Zhen wrote:
>
> > Dear all,
> >
> > I just read the book 'Digital Image Processing - An Algorithmic
> > Introduction using Java'.  There is an assignment on program 4.3 which
> ask
> > to finish a task to compute the histogram of 8-bit-gray-scale image and
> > display it.. I finished the left part and completed the code to create
> the
> > histogram image. But failed (compiled successfully) and the result did
> not
> > show histogram as expected. Here is the code:
> >
> > the red colored is my own code for this project. Since my understanding
> of
> > Java and imageJ is limited, please give me some suggestions of why there
> is
> > no output image of histogram. Thanks in advance.
>
> One reason there is no output is that the plugin is drawing in white on a
> white background. Here is a version that works with all image types. It
> uses the histogram returned by getStatistics() because that histogram
> always has 256 bins. It implements the PlugIn interface because it is not a
> filter and because the PlugIn interface is simpler.
>
> import ij.*;
> import ij.plugin.PlugIn;
> import ij.process.*;
> import java.awt.Color;
>
> public class Create_New_Image implements PlugIn {
>
>     public void run(String arg) {
>         ImagePlus imp = IJ.getImage();
>         int w = 256;
>         int h = 100;
>         ImageStatistics stats = imp.getStatistics();
>         int[] hist = stats.histogram;
>         ImageProcessor histIp = new ByteProcessor(w, h);
>         histIp.setColor(Color.white);
>         histIp.fill();
>         histIp.setColor(Color.black);
>         int max = hist[stats.mode];
>         double scale = (double)h/max;
>         for (int i=0; i<hist.length; i++)
>             histIp.drawLine(i, h, i, h-(int)(hist[i]*scale));
>         String title = "Histogram of " + imp.getTitle();
>         new ImagePlus(title, histIp).show();
>     }
>
> }
>
>
> > import ij.ImagePlus;
> > import ij.plugin.filter.PlugInFilter;
> > import ij.process.ByteProcessor;
> > import ij.process.ImageProcessor;
> >
> > /*
> > * This plugin demonstrates how to create and display a
> > * new byte image
> > */
> >
> > public class Create_New_Image implements PlugInFilter {
> > String title = null;
> >
> > public int setup(String arg, ImagePlus im) {
> > title = im.getTitle();
> > return DOES_8G + NO_CHANGES;
> > }
> >
> > public void run(ImageProcessor ip) {
> > int w = 256;
> > int h = 100;
> > int[] hist = ip.getHistogram();
> >     int[] hist2= new int[256];
> > ImageProcessor histIp = new ByteProcessor(w, h);
> > histIp.setValue(255); // white = 255
> > histIp.fill();
> >
> > // draw the histogram values as black bars in ip2 here,
> > // for example, using histIp.putpixel(u,v,0)
> > // ...
> > int max = hist[0];
> > for (int i =1;i<hist.length;i++) {
> > if(hist[i] > max) {
> > max = hist[i];
> > }
> > }
> > // shrink to 0.8 of the original;
> > for(int i=0;i<hist2.length;i++){
> > hist2[i]= (hist[i]/max)*4*100/5;
> > }
> > for(int i=0;i<hist2.length;i++){
> > for(int j= 100 - hist2[i];j<h;j++){
> > histIp.putPixel(i,hist2[j],0);
> > }
> > }
> > // display histogram:
> > String hTitle = "Histogram of " + title;
> > ImagePlus histIm = new ImagePlus(hTitle, histIp);
> > histIm.show();
> > //histIm.updateAndDraw();
> > }
> > }
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: solution to Program 4.3?

hhhhhhh
In reply to this post by Yisong Zhen
How to implement exercise 4.3 without knowing the original image value? I mean if you don't know the size of the image, how to break it into 10 different ranges?