📄 399-404.html
字号:
<HTML>
<HEAD>
<META name=vsisbn content="1558515682"><META name=vstitle content="Java Digital Signal Processing"><META name=vsauthor content="Douglas A. Lyon"><META name=vsimprint content="M&T Books"><META name=vspublisher content="IDG Books Worldwide, Inc."><META name=vspubdate content="11/01/97"><META name=vscategory content="Web and Software Development: Programming, Scripting, and Markup Languages: Java"><TITLE>Java Digital Signal Processing:Image Processing in Java</TITLE>
<!-- HEADER --><STYLE type="text/css"> <!-- A:hover { color : Red; } --></STYLE><META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
<!--ISBN=1558515682//-->
<!--TITLE=Java Digital Signal Processing//-->
<!--AUTHOR=Douglas A. Lyon//-->
<!--PUBLISHER=IDG Books Worldwide, Inc.//-->
<!--IMPRINT=M & T Books//-->
<!--CHAPTER=9//-->
<!--PAGES=399-404//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="393-399.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="404-406.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<P>This code is a concatenation of two transformations—<I>trans1</I> and <I>trans2</I>—into a single transformation matrix, <I>trans3</I>. The matrix product is also called <I>compounding</I>, <I>catenation</I>, <I>concatenation</I>, or <I>composition</I>. Once the transform is formulated, it can be applied to all points in the scene.</P>
<P>Several policy issues must be resolved to implement matrix compounding.</P>
<P>We have allocated the memory for a transformation matrix using a static method in the <I>Mat3</I> class. The memory allocation is dynamic and possibly wasteful. This might be OK, however, because the number of transformation matrices may be small relative to the number of points that require transformation. When we are finished with the transformation matrix, we should set it to null so that the garbage collector can reclaim the storage.</P>
<P>It is probably good policy to keep a copy of the master object and apply the composite transform to all the points each time. Incrementally transforming the points on an integer coordinate system (such as an image plane) will distort the image. For example, suppose that I wanted to rotate an image by 50( in 10-degree increments. The progression of the image is shown in Figure 9.18.</P>
<P><A NAME="Fig18"></A><A HREF="javascript:displayWindow('images/09-18.jpg',307,451 )"><IMG SRC="images/09-18t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/09-18.jpg',307,451)"><FONT COLOR="#000077"><B>Figure 9.18</B></FONT></A> Incremental rotation in an integral coordinate system.</P>
<P>Figure 9.18 shows that when the result of a rotation is used to supply data for the transform input, the result gets distorted and the error accumulates through the transforms. To reduce the distortion, we start with the original data and recompute the transformation matrix. The same 50 degree rotation can be performed, without accumulating distortion, as shown in Figure 9.19.
</P>
<P><A NAME="Fig19"></A><A HREF="javascript:displayWindow('images/09-19.jpg',310,141 )"><IMG SRC="images/09-19t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/09-19.jpg',310,141)"><FONT COLOR="#000077"><B>Figure 9.19</B></FONT></A> Non-incremental rotation in an integral coordinate system.</P>
<P>An interesting aspect of the distortion is the aesthetic quality of an image after the incremental rotation. Figure 9.20 shows what happens to the hapless mandrill after a 360 degree rotation is performed in 18 steps of 20 degrees each.
</P>
<P><A NAME="Fig20"></A><A HREF="javascript:displayWindow('images/09-20.jpg',152,156 )"><IMG SRC="images/09-20t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/09-20.jpg',152,156)"><FONT COLOR="#000077"><B>Figure 9.20</B></FONT></A> Mandrill after 18 incremental rotations of 20 degrees each.</P>
<P>The matrix form for the scaling is as follows:
</P>
<P ALIGN="CENTER"><IMG SRC="images/09-58d.jpg"></P>
<P>(9.37)
</P>
<P>Here is the Java implementation of Equation 9.37:</P>
<!-- CODE SNIP //-->
<PRE>
public static Mat3 scaling(point s) {
double m[][] = new double[3][3];
m[0][0] = s.x;
m[1][1] = s.y;
m[2][2] = 1;
return new Mat3(m);
}
</PRE>
<!-- END CODE SNIP //-->
<P>Like successive translations, successive scalings are multiplicative:
</P>
<!-- CODE //-->
<PRE>
public static void main(String args[]) {
Mat3 trans1 = Mat3.scaling(new point(2,3));
Mat3 trans2 = Mat3.scaling(new point(1,2));
Mat3 trans3 = trans1.multiply(trans2);
trans1.print();
System.out.println(“ * “ );
trans2.print();
System.out.println(“ = “);
trans3.print();
}
</PRE>
<!-- END CODE //-->
<P>Here are the results:
</P>
<!-- CODE //-->
<PRE>
2 0 0
0 3 0
0 0 1
*
1 0 0
0 2 0
0 0 1
=
2 0 0
0 6 0
0 0 1
</PRE>
<!-- END CODE //-->
<P>Figure 9.21 shows the mandrill with a 3:1 zoom out followed by a 3:1 zoom in. This effect was first created optically by systems such as the Blockpix processor [Manning]. Our empirical tests show that the color gamut produced by Blockpix processors has a wider range than that produced by color monitors.
</P>
<P><A NAME="Fig21"></A><A HREF="javascript:displayWindow('images/09-21.jpg',321,138 )"><IMG SRC="images/09-21t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/09-21.jpg',321,138)"><FONT COLOR="#000077"><B>Figure 9.21</B></FONT></A> Original mandrill (left), zoom out 3:1, and zoom in 3:1.</P>
<P>The matrix form for the rotation is as follows:
</P>
<P ALIGN="CENTER"><IMG SRC="images/09-59d.jpg"></P>
<P>(9.38)
</P>
<P>The Java implementation of Equation 9.38 follows:</P>
<!-- CODE //-->
<PRE>
public static Mat3 rotation(double theta) {
double m[][] = new double[3][3];
double cas = Math.cos(theta);
double sas = Math.sin(theta);
m[0][0] = cas;
m[1][1] = cas;
m[0][1] = -sas;
m[1][0] = sas;
return new Mat3(m);
}
</PRE>
<!-- END CODE //-->
<BLOCKQUOTE>
<P><FONT SIZE="-1"><HR><B>NOTE: </B>The <I>Math.sin</I> and <I>Math.cos</I> functions in Java use radians for input.<HR></FONT>
</BLOCKQUOTE>
<P>Consider this example:
</P>
<!-- CODE SNIP //-->
<PRE>
public static void main(String args[]) {
Mat3 trans3 = Mat3.rotation(90 * piOn180);
trans3.print();
}
</PRE>
<!-- END CODE SNIP //-->
<P>The preceding code produces this output:
</P>
<!-- CODE SNIP //-->
<PRE>
0 -1 0
1 0 0
0 0 0
</PRE>
<!-- END CODE SNIP //-->
<P>The rotation and translation transforms are rigid-body transformations, because they do not distort the object. Scale is not a rigid-body transformation, because scaling in the x and y directions may be different.
</P>
<P><I>Affine transformations</I> consist of sequences of rotation, translation, scale, and shear operations. Affine transformations preserve the parallelism of lines but not lengths or angles.</P>
<P>Shear can go in the x or y direction. For example, the shear transform in the x direction is given by the following:</P>
<P ALIGN="CENTER"><IMG SRC="images/09-60d.jpg"></P>
<P>(9.39)
</P>
<P>The shear transform in the y direction is given by</P>
<P ALIGN="CENTER"><IMG SRC="images/09-61d.jpg"></P>
<P>(9.40)
</P>
<P>An implementation for the construction of a shear matrix follows:</P>
<!-- CODE //-->
<PRE>
public static Mat3 shear(point sh) {
double m[][] = new double[3][3];
m[0][0] = 1;
m[1][1] = 1;
m[2][2] = 1;
m[0][1] = sh.x;
m[1][0] = sh.y;
return new Mat3(m);
}
</PRE>
<!-- END CODE //-->
<P>The following shows an example of the shear method being invoked:
</P>
<!-- CODE SNIP //-->
<PRE>
public static void main(String args[]) {
Mat3 trans1 = Mat3.shear(new point(1,2));
trans1.print();
}
</PRE>
<!-- END CODE SNIP //-->
<P>The output follows:
</P>
<!-- CODE SNIP //-->
<PRE>
1 1 0
2 1 0
0 0 1
</PRE>
<!-- END CODE SNIP //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="393-399.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="404-406.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<hr width="90%" size="1" noshade><div align="center"><font face="Verdana,sans-serif" size="1">Copyright © <a href="/reference/idgbooks00001.html">IDG Books Worldwide, Inc.</a></font></div>
<!-- all of the reference materials (books) have the footer and subfoot reveresed --><!-- reference_subfoot = footer --><!-- reference_footer = subfoot --></BODY></HTML><!-- END FOOTER -->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -