📄 389-393.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=389-393//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="386-389.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="393-399.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<P>The lines are numbered for reference only. Line 1 reads the linear algebra package into Maple. Line 2 reads the C-language generator. Lines 3 and 4 create arrays whose indexes start at zero. Line 5 converts the <I>a</I> array into a <I>matrix</I> type, forms the inverse symbolically, and sets the answer to <I>b</I>. Line 6 outputs the following code:</P>
<!-- CODE //-->
<PRE>
public Mat3 invert() {
double b[] [] = new double [3][3];
double t4 = a[0][0]*a[1][1];
double t6 = a[0][0]*a[1][2];
double t8 = a[0][1]*a[1][0];
double t10 = a[0][2]*a[1][0];
double t12 = a[0][1]*a[2][0];
double t14 = a[0][2]*a[2][0];
double t17 =
1/(-t4*a[2][2]+t6*a[2][1]+t8*a[2][2]
-t10*a[2][1]-t12*a[1][2]+t14*a
[1][1]);
b[0][0] = -(a[1][1]*a[2][2]-a[1][2]*a[2][1])*t17;
b[0][1] = -(-a[0][1]*a[2][2]+a[0][2]*a[2][1])*t17;
b[0][2] = (-a[0][1]*a[1][2]+a[0][2]*a[1][1])*t17;
b[1][0] = (a[1][0]*a[2][2]-a[1][2]*a[2][0])*t17;
b[1][1] = (-a[0][0]*a[2][2]+t14)*t17;
b[1][2] = -(-t6+t10)*t17;
b[2][0] = (-a[1][0]*a[2][1]+a[1][1]*a[2][0])*t17;
b[2][1] = -(-a[0][0]*a[2][1]+t12)*t17;
b[2][2] = (-t4+t8)*t17;
return new Mat3(b);
}
</PRE>
<!-- END CODE //-->
<P>We find this code pretty handy. Maple automatically unwinds <I>for</I> loops, generates auxiliary variables, and saves a lot of typing. The declaration of <I>double</I> for the temporary variables (<I>tnn</I>) that Maple generates must be done by hand.</P>
<P>The technique of using Maple extends well into other matrix operations. In Maple, for example, we can unwind the <I>for</I> loops in a multiplication:</P>
<!-- CODE SNIP //-->
<PRE>
C(multiply(matrix(b),matrix(a)),optimized):
</PRE>
<!-- END CODE SNIP //-->
<P>The optimized output is reformatted and annotated:
</P>
<!-- CODE //-->
<PRE>
public Mat3 multiply(Mat3 bmat3) {
double WW [][] = new double[3][3];
double b [][] = bmat3.getArray();
WW[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0];
WW[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1];
WW[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2];
WW[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0];
WW[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1];
WW[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2];
WW[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0];
WW[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1];
WW[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2];
return (new Mat3(WW));
}
</PRE>
<!-- END CODE //-->
<P>Generating Java code is not totally automatic. Some human intervention is required—adding the method entry points and returns—but most of the hard work is done by Maple. The following Maple code will generate Java code for any <I>N</I>, where <I>N</I> is an integer greater than 1:</P>
<!-- CODE //-->
<PRE>
readlib(linalg):
readlib(C):
multn := proc(N)
local a, b, c, v;
a := array(0..N,0..N);
b := array(0..N,0..N);
c := array(0..N,0..N);
v := vector([seq(vec[i],i=0..N)]);
print(v);
c := multiply(matrix(a),matrix(b));
print(`Mult N by N times N by N`); print(N+1);
C(c, optimized);
print(`Mult N by N times N by 1`); print(N+1);
c := multiply(matrix(a),v);
C(c, optimized);
c := inverse(matrix(a));
print(‘inverse’); print(N);
C(c, optimized);
end;
</PRE>
<!-- END CODE //-->
<P>The time Maple takes to perform the <I>multn</I> procedure increases quadratically with increasing <I>N,</I> so this technique will not be practical for all sizes of <I>N</I>. Also, we have not optimized for especially sparse matrices, such as rotation matrices that occur in computer graphics and robotics.</P>
<H3><A NAME="Heading26"></A><FONT COLOR="#000077">Image Geometry</FONT></H3>
<P>Now let’s look at the derivation and implementation of elementary 2-D image transformation using matrix multiplication. We will cover the operations of translation, rotation, scale, and shear, using 3x3 matrix multiplications. To perform these operations, we make extensive use of the <I>Mat3</I> class derived in the previous section.</P>
<H4 ALIGN="LEFT"><A NAME="Heading27"></A><FONT COLOR="#000077">Two-Dimensional Translation</FONT></H4>
<P>To translate a point, <I>p</I>, whose coordinates are (<I>p</I>.<I>x</I>,<I>p</I>.<I>y</I>) plane by an amount, <I>t</I>, whose offset is given by, (<I>t</I>.<I>x</I>,<I>t</I>.<I>y</I>) use the following:</P>
<P ALIGN="CENTER"><IMG SRC="images/09-36d.jpg"></P>
<P>(9.22)
</P>
<P>In Java notation:</P>
<!-- CODE SNIP //-->
<PRE>
pPrime = p.add(t);
</PRE>
<!-- END CODE SNIP //-->
<P>An implementation of this translation can be found in the <I>point</I> class, which resides in the <I>lyon</I> package:</P>
<!-- CODE //-->
<PRE>
public class point extends Computation {
double x = 0;
double y = 0;
...
public point add(point t) {
return new point(x + t.x, y + t.y);
}
...
</PRE>
<!-- END CODE //-->
<P>This implementation is particularly slow because a new point is allocated every time an addition is performed. We use such code for illustration only.
</P>
<H4 ALIGN="LEFT"><A NAME="Heading28"></A><FONT COLOR="#000077">Two-Dimensional Scaling</FONT></H4>
<P>To scale a point, <I>p</I>, whose coordinates are (<I>p</I>.<I>x</I>,<I>p</I>.<I>y</I>) plane by an amount, <I>t</I>, whose scale is given by, (<I>s</I>.<I>x</I>,<I>s</I>.<I>y</I>) use the following:</P>
<P ALIGN="CENTER"><IMG SRC="images/09-37d.jpg"></P>
<P>(9.23)
</P>
<P>To scale about a point, <I>t</I>, translate to the origin, perform the scaling and then translate back. This process can be represented by the following:</P>
<P ALIGN="CENTER"><IMG SRC="images/09-38d.jpg"></P>
<P>(9.24)
</P>
<P>In Java, we can express Equations 9.24 and 9.23 by overloading a method in the <I>point</I> class:</P>
<!-- CODE SNIP //-->
<PRE>
public point scale(point s) {
return new point(x * s.x, y * s.y);
}
</PRE>
<!-- END CODE SNIP //-->
<P>In the following implementation of Equation 9.24, we scale about point <I>t</I>.</P>
<!-- CODE SNIP //-->
<PRE>
public point scale(point s, point t) {
return new point((x - t.x) * s.x + t.x, (y - t.y)* s.y+t.y);
}
</PRE>
<!-- END CODE SNIP //-->
<P>Because Equation 9.23 scales about the origin, the point will move relative to the origin. Furthermore, if scaling were uniform, the amount of scaling in each dimension would be equal.
</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="386-389.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="393-399.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 + -