📄 image enhancement.htm
字号:
each of the constants and offsets arrays.
<P>The pixel values of the destination image are defined by the following
pseudocode:
<P><PRE> constant = (constants.length < dstNumBands) ?
constants[0] : constants[b];
offset = (offsets.length < dstNumBands) ?
offsets[0] : offsets[b];
dst[x][y][b] = src[x][y][b]*constant + offset;
</PRE>The pixel arithmetic is performed using the data type of the destination
image. By default, the destination will have the same data type as the source
image unless an <CODE>ImageLayout</CODE> containing a <CODE>SampleModel</CODE>
with a different data type is supplied as a rendering hint.
<P>The values of the lowest and highest pixel amplitudes must be known. This
information can be acquired through the <CODE>Extrema</CODE> operation (see <A
href="http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Analysis.doc.html#54907">Section
9.3, "Finding the Extrema of an Image</A>").
<P>The following equations show the relationships between the extrema and the
scale and offset factors.
<P>
<P><A name=59303>
<UL>
<TABLE>
<TBODY>
<TR>
<TD width=430><IMG
src="Image Enhancement.files/Image-enhance.doc.anc9.gif"> </TD>
<TD>(7.1)</TD></TR></TBODY></TABLE></UL></A>
<P><A name=59312>
<UL>
<TABLE>
<TBODY>
<TR>
<TD width=430><IMG
src="Image Enhancement.files/Image-enhance.doc.anc10.gif"> </TD>
<TD>(7.2)</TD></TR></TBODY></TABLE></UL></A>
<DL><A name=59319>
<DT>
<DD>where <EM>max</EM>(<EM>b</EM>) and <EM>min</EM>(<EM>b</EM>) are the
largest and smallest pixel values in the band, respectively. </A>
<P></P></DD></DL>The <CODE>rescale</CODE> operation takes one rendered or
renderable source image and two parameters:
<P>
<TABLE cellPadding=3 border=3>
<CAPTION><FONT size=-1><B></B></FONT></CAPTION>
<TBODY>
<TR vAlign=top>
<TH><A name=61691>Parameter </A>
<TH><A name=61693>Type </A>
<TH><A name=61695>Description </A>
<TR vAlign=top>
<TD><A name=61697>constants</A><BR>
<TD><A name=61699>double</A><BR>
<TD><A name=61701>The per-band constants to multiply by.</A><BR>
<TR vAlign=top>
<TD><A name=61703>offsets</A><BR>
<TD><A name=61705>double</A><BR>
<TD><A name=61707>The per-band offsets to be
added.</A><BR></TR></TBODY></TABLE>
<P><A name=70862>
<H2>7.5 <IMG src="Image Enhancement.files/space.gif">Histogram
Equalization</H2></A>An image histogram is an analytic tool used to measure
the amplitude distribution of pixels within an image. For example, a histogram
can be used to provide a count of the number of pixels at amplitude 0, the
number at amplitude 1, and so on. By analyzing the distribution of pixel
amplitudes, you can gain some information about the visual appearance of an
image. A high-contrast image contains a wide distribution of pixel counts
covering the entire amplitude range. A low contrast image has most of the
pixel amplitudes congregated in a relatively narrow range.
<P>See <A
href="http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Analysis.doc.html#54836">Section
9.4, "Histogram Generation</A>," for information on how to generate a
histogram for an image. The next two sections describe JAI operations that use
an image histogram to enhance an image's appearance.
<P><A name=70864>
<H3>7.5.1 <IMG src="Image Enhancement.files/space.gif">Piecewise Linear
Mapping</H3></A>The <CODE>Piecewise</CODE> operation performs a piecewise
linear mapping of an image's pixel values. The piecewise linear mapping is
described by a set of breakpoints that are provided as an array of the form:
<P><PRE> float breakPoints[N][2][numBreakPoints]
</PRE>
<DL><A name=70922>
<DT>
<DD>where the value of <EM>N</EM> may be either unity or the number of bands
in the source image. </A>
<P></P></DD></DL>If <EM>N</EM> is unity, the same set of breakpoints will be
applied to all bands in the image. The abscissas of the supplied breakpoints
must be monotonically increasing.
<P>The pixel values of the destination image are defined by the following
pseudocode:
<P><PRE> if(src[x][y][b] < breakPoints[b][0][0])
dst[x][y][b] = breakPoints[b][1][0]);
} else if(src[x][y][b] > breakPoints[b][0][numBreakPoints-1]) {
dst[x][y][b] = breakPoints[b][1][numBreakPoints-1]);
} else {
int i = 0;
while(breakPoints[b][0][i+1] < src[x][y][b]) {
i++;
}
dst[x][y][b] = breakPoints[b][1][i] +
(src[x][y][b] - breakPoints[b][0][i])*
(breakPoints[b][1][i+1] - breakPoints[b][1][i])/
(breakPoints[b][0][i+1] - breakPoints[b][0][i]);
</PRE>The <CODE>Piecewise</CODE> operation takes one rendered or renderable
source image and one parameter:
<P>
<TABLE cellPadding=3 border=3>
<CAPTION><FONT size=-1><B></B></FONT></CAPTION>
<TBODY>
<TR vAlign=top>
<TH><A name=71037>Parameter </A>
<TH><A name=71039>Type </A>
<TH><A name=71041>Description </A>
<TR vAlign=top>
<TD><A name=71043>breakPoints</A><BR>
<TD><A name=71045>Float</A><BR>
<TD><A name=71047>The breakpoint array.</A><BR></TR></TBODY></TABLE>
<P><A
href="http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Image-enhance.doc.html#74848">Listing
7-1</A> shows a code sample of a <CODE>Piecewise</CODE> operation, showing
only the construction of the piecewise-mapped image and the operation. The
generation of the source image, fmt, is not shown.
<P><CAPTION><FONT size=-1><B><A name=74848>
<CENTER><FONT size=-1><B><I>Listing 7-1 </I><IMG
src="Image Enhancement.files/sm-blank.gif" border=0> Example Piecewise
Operation</B></FONT></CENTER></A>
<P></B></FONT></CAPTION>
<HR>
<TR valign="top"><TD><PRE> // Create a piecewise-mapped image emphasizing low values.
float[][][] bp = new float[numBands][2][];
for(int b = 0; b < numBands; b++) {
bp[b][0] = new float[] {0.0F, 32.0F, 64.0F, 255.0F};
bp[b][1] = new float[] {0.0F, 64.0F, 112.0F, 255.0F};
}
</PRE><TR valign="top"><TD><PRE> // Create the Piecewise operation.
RenderedOp pw = JAI.create("piecewise", fmt, bp);
</PRE>
<HR>
<P><A name=71727>
<H3>7.5.2 <IMG src="Image Enhancement.files/space.gif">Histogram
Matching</H3></A>It is sometimes desirable to transform an image so that its
histogram matches that of a specified functional form. The
<CODE>MatchCDF</CODE> operation performs a piecewise linear mapping of the
pixel values of an image such that the cumulative distribution function (CDF)
of the destination image matches as closely as possible a specified cumulative
distribution function.
<P>The CDF of an image is its area-normalized threshold area function. The
desired CDF for the <CODE>MatchCDF</CODE> operation is described by an array
of the form:
<P><PRE> float CDF[numBands][numBins[b]]
</PRE>
<DL><A name=71396>
<DT>
<DD>where <CODE>numBins</CODE> denotes the number of bins in the histogram
of the source image for band <EM>b</EM>. </A>
<P></P></DD></DL>Each element in the array <CODE>CDF[b]</CODE> must be
non-negative, the array must represent a non-decreasing sequence, and the last
element of the array must be 1.0F. The source image must have a
<CODE>Histogram</CODE> object available via its <CODE>getProperty</CODE>
method.
<P>The <CODE>MatchCDF</CODE> operation takes one rendered or renderable source
image and one parameter:
<P>
<TABLE cellPadding=3 border=3>
<CAPTION><FONT size=-1><B></B></FONT></CAPTION>
<TBODY>
<TR vAlign=top>
<TH><A name=71456>Parameter </A>
<TH><A name=71458>Type </A>
<TH><A name=71460>Description </A>
<TR vAlign=top>
<TD><A name=71462>CDF</A><BR>
<TD><A name=71464>Float</A><BR>
<TD><A name=71466>The desired cumulative distribution
function.</A><BR></TR></TBODY></TABLE>
<P>The operation requires that the image histogram be available.
<P><A
href="http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Image-enhance.doc.html#74900">Listing
7-2</A> shows a code sample of a <CODE>MatchCDF</CODE> operation, showing only
the histogram operation, construction of two different CDFs, and the
operations that use them.
<P><CAPTION><FONT size=-1><B><A name=74900>
<CENTER><FONT size=-1><B><I>Listing 7-2 </I><IMG
src="Image Enhancement.files/sm-blank.gif" border=0> Example MatchCDF
Operation </B></FONT></CENTER></A>
<P></B></FONT></CAPTION>
<HR>
<TR valign="top"><TD><PRE> // Retrieves a histogram for the image.
private static Histogram getHistogram(RenderedOp img,
int binCount) {
</PRE><TR valign="top"><TD><PRE> // Get the band count.
int numBands = img.getSampleModel().getNumBands();
</PRE><TR valign="top"><TD><PRE> // Allocate histogram memory.
int[] numBins = new int[numBands];
double[] lowValue = new double[numBands];
double[] highValue = new double[numBands];
for(int i = 0; i < numBands; i++) {
numBins[i] = binCount;
lowValue[i] = 0.0;
highValue[i] = 255.0;
}
</PRE><TR valign="top"><TD><PRE> // Create the Histogram object.
Histogram hist = new Histogram(numBins, lowValue, highValue);
</PRE><TR valign="top"><TD><PRE> // Set the ROI to the entire image.
ROIShape roi = new ROIShape(img.getBounds());
</PRE><TR valign="top"><TD><PRE> // Create the histogram op.
RenderedOp histImage =
JAI.create("histogram", img,
hist, roi, new Integer(1), new Integer(1));
</PRE><TR valign="top"><TD><PRE> // Retrieve the histogram.
hist = (Histogram)histImage.getProperty("histogram");
</PRE><TR valign="top"><TD><PRE> return hist;
}
</PRE><TR valign="top"><TD><PRE> // Create an equalization CDF.
float[][] CDFeq = new float[numBands][];
for(int b = 0; b < numBands; b++) {
CDFeq[b] = new float[binCount];
for(int i = 0; i < binCount; i++) {
CDFeq[b][i] = (float)(i+1)/(float)binCount;
}
}
</PRE><TR valign="top"><TD><PRE> // Create a normalization CDF.
double[] mean = new double[] {128.0, 128.0, 128.0};
double[] stDev = new double[] {64.0, 64.0, 64.0};
float[][] CDFnorm = new float[numBands][];
for(int b = 0; b < numBands; b++) {
CDFnorm[b] = new float[binCount];
double mu = mean[b];
double twoSigmaSquared = 2.0*stDev[b]*stDev[b];
CDFnorm[b][0] =
(float)Math.exp(-mu*mu/twoSigmaSquared);
for(int i = 1; i < binCount; i++) {
double deviation = i - mu;
CDFnorm[b][i] = CDFnorm[b][i-1] +
(float)Math.exp(-deviation*deviation/twoSigmaSquared);
}
}
for(int b = 0; b < numBands; b++) {
double CDFnormLast = CDFnorm[b][binCount-1];
for(int i = 0; i < binCount; i++) {
CDFnorm[b][i] /= CDFnormLast;
}
}
</PRE><TR valign="top"><TD><PRE> // Create a histogram-equalized image.
RenderedOp eq = JAI.create("matchcdf", fmt, CDFeq);
</PRE><TR valign="top"><TD><PRE> // Create a histogram-normalized image.
RenderedOp nm = JAI.create("matchcdf", fmt, CDFnorm);
</PRE>
<HR>
<P><A name=71424>
<H2>7.6 <IMG src="Image Enhancement.files/space.gif">Lookup Table
Modification</H2></A>The lookup table modification provides a non-linear
amplitude transformation. Non-linear amplitude transformation is useful if you
have a non-linear amplitude response difference between the sensor that
captures the image data and the display.
<P>The lookup table modification mechanism allows you to arbitrarily convert
between the source image byte, short, or integer pixel value and one or more
output values. The output value can be a byte, short, integer, float, or
double image pixel.
<P>The input pixel value acts as an address to the lookup table inputs, as
shown in <A
href="http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Image-enhance.doc.html#51273">Figure
7-8</A>. Each location in the lookup table stores the desired output value for
that particular address.
<P><A name=51271>
<HR>
<CENTER><IMG src="Image Enhancement.files/Image-enhance.doc.anc.gif"></CENTER>
<HR>
</A><A name=51273>
<CENTER><FONT size=-1><B><I>Figure 7-8 </I><IMG
src="Image Enhancement.files/sm-blank.gif" border=0> Lookup
Table</B></FONT></CENTER></A>
<P>The lookup table is first loaded with the necessary data. <A
href="http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Image-enhance.doc.html#51279">Table
7-2</A> shows a partial listing of an example lookup table. In this example,
the input values range from 0 to 255. The output values provide a scaled
square root transformation between the input and output, according to the
following equation:
<P>
<DL><A name=51325>
<DT>
<DD><IMG src="Image Enhancement.files/Image-enhance.doc.anc1.gif">
<P>
<TABLE cellPadding=3 border=3>
<CAPTION><FONT size=-1><B><A name=51279><I>Table 7-2 </I><IMG
src="Image Enhancement.files/sm-blank.gif" border=0> Example Lookup Table
</A></B></FONT></CAPTION>
<TBODY>
<TR vAlign=top>
<TH><A name=51283>Input </A>
<TH><A name=51285>Output </A>
<TR vAlign=top>
<TD><A name=51287>0</A><BR>
<TD><A name=51289>0</A><BR>
<TR vAlign=top>
<TD><A name=51291>1</A><BR>
<TD><A name=51293>16</A><BR>
<TR vAlign=top>
<TD><A name=51295>2</A><BR>
<TD><A name=51297>23</A><BR>
<TR vAlign=top>
<TD><A name=51299>3</A><BR>
<TD><A name=51301>28</A><BR>
<TR vAlign=top>
<TD><A name=51303>.</A><BR>
<TD><A name=51305>.</A><BR>
<TR vAlign=top>
<TD><A name=51307>253</A><BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -