<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE document PUBLIC "-//CNX//DTD CNXML 0.5 plus MathML//EN" "http://cnx.rice.edu/cnxml/0.5/DTD/cnxml_mathml.dtd">
<document xmlns="http://cnx.rice.edu/cnxml" xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="new11">
  <name>Geometric Transformation of Images using Spline-Interpolation</name>
  <metadata>
  <md:version>2.1</md:version>
  <md:created>2003/05/05</md:created>
  <md:revised>2003/05/07</md:revised>
  <md:authorlist>
      <md:author id="sujesh">
      <md:firstname>Sujesh</md:firstname>
      
      <md:surname>Sreedharan</md:surname>
      <md:email>sujesh@rice.edu</md:email>
    </md:author>
  </md:authorlist>

  <md:maintainerlist>
    <md:maintainer id="ixmocane">
      <md:firstname>Alena</md:firstname>
      <md:othername>Ixmocane</md:othername>
      <md:surname>Scott</md:surname>
      <md:email>oetting@stat.rice.edu</md:email>
    </md:maintainer>
    <md:maintainer id="sujesh">
      <md:firstname>Sujesh</md:firstname>
      
      <md:surname>Sreedharan</md:surname>
      <md:email>sujesh@rice.edu</md:email>
    </md:maintainer>
    <md:maintainer id="rebecca">
      <md:firstname>Rebecca</md:firstname>
      
      <md:surname>Willett</md:surname>
      <md:email>willett@rice.edu</md:email>
    </md:maintainer>
    <md:maintainer id="jago">
      <md:firstname>Adan</md:firstname>
      
      <md:surname>Galvan</md:surname>
      <md:email>jago@rice.edu</md:email>
    </md:maintainer>
    <md:maintainer id="charlet">
      <md:firstname>Charlet</md:firstname>
      
      <md:surname>Reedstrom</md:surname>
      <md:email>charlet@rice.edu</md:email>
    </md:maintainer>
  </md:maintainerlist>
  
  <md:keywordlist>
    <md:keyword>B-splines</md:keyword>
    <md:keyword>Image transforms</md:keyword>
    <md:keyword>interpolation</md:keyword>
    <md:keyword>splines</md:keyword>
  </md:keywordlist>

  <md:abstract>To perform geometric transforms on discrete images such as a rotation or zooming we need to first fit the discrete data to a continuous function. This can be done using splines. B-splines can be used to interpolate and form the continuos image from the discrete samples.</md:abstract>
</metadata>

  <content>
    <para id="intro">
      Here we illustrate the use of splines in two-dimensions for
      transforming discrete images. When we apply a transformation
      (such as rotation or zooming) it becomes necessary to know the
      image intensity at a location in between the sample points. This
      is an interpolation problem and <cnxn document="m11153" strength="8">splines</cnxn> come in handy.
    </para>

    <section id="sec1">
      <name>Spline Tensor Product Basis</name>
      <para id="para1">
	We extend the 1D B-spline basis to 2D using tensor products
	<m:math>
	  <m:apply>
	    <m:power/>
	    <m:apply>
	      <m:ci type="fn">φ</m:ci>
	      <m:list>
		<m:ci>x</m:ci>
		<m:ci>y</m:ci>
	      </m:list>
	    </m:apply>
	    <m:ci>n</m:ci>
	  </m:apply>
	</m:math> defined as

	<equation id="eqn1">
	  <m:math>
	    <m:apply>
	      <m:eq/>
	      <m:apply>
		<m:power/>
		<m:apply>
		  <m:ci type="fn">φ</m:ci>
		  <m:apply>
		    <m:minus/>
		    <m:ci>x</m:ci>
		    <m:ci>k</m:ci>
		  </m:apply>
		  <m:apply>
		    <m:minus/>
		    <m:ci>y</m:ci>
		    <m:ci>l</m:ci>
		  </m:apply>
		</m:apply>
		<m:ci>n</m:ci>
	      </m:apply>
	      <m:apply>
		<m:times/>
		<m:apply>
		  <m:power/>
		  <m:apply>
		    <m:ci type="fn">β</m:ci>
		    <m:apply>
		      <m:minus/>
		      <m:ci>x</m:ci>
		      <m:ci>k</m:ci>
		    </m:apply>
		  </m:apply>
		  <m:ci>n</m:ci>
		</m:apply>
		<m:apply>
		  <m:power/>
		  <m:apply>
		    <m:ci type="fn">β</m:ci>
		    <m:apply>
		      <m:minus/>
		      <m:ci>y</m:ci>
		      <m:ci>l</m:ci>
		    </m:apply>
		  </m:apply>
		  <m:ci>n</m:ci>
		</m:apply>
	      </m:apply>
	    </m:apply>
	  </m:math>
	</equation>

	Using these bases we can interpolate a discrete image 
	<m:math>
	  <m:apply>
	    <m:ci type="fn">f</m:ci>
	    <m:list>
	      <m:ci>k</m:ci>
	      <m:ci>l</m:ci>
	    </m:list>
	  </m:apply>
	</m:math>
	and come up with a continuous function 
	<m:math>
	  <m:apply>
	    <m:ci type="fn">f</m:ci>
	    <m:list>
	      <m:ci>x</m:ci>
	      <m:ci>y</m:ci>
	    </m:list>
	  </m:apply>
	</m:math> over 
	<m:math>
	  <m:apply>
	    <m:power/>
	    <m:reals/>
	    <m:cn>2</m:cn>
	  </m:apply>
	</m:math>.  

	<equation id="eqn2">
	  <m:math>
	    <m:apply>
	      <m:eq/>
	      <m:apply>
		<m:ci type="fn">f</m:ci>
		<m:list>
		  <m:ci>x</m:ci>
		  <m:ci>y</m:ci>
		</m:list>
	      </m:apply>
	      <m:apply>
		<m:sum/>
		<m:bvar><m:ci>k</m:ci></m:bvar>
		<m:domainofapplication>
		  <m:ci>k</m:ci>
		</m:domainofapplication>
		<m:apply>
		  <m:sum/>
		  <m:bvar><m:ci>l</m:ci></m:bvar>
		  <m:domainofapplication>
		    <m:ci>l</m:ci>
		  </m:domainofapplication>
		  <m:apply>
		    <m:times/>
		    <m:apply>
		      <m:ci type="fn">c</m:ci>
		      <m:list>
			<m:ci>k</m:ci>
			<m:ci>l</m:ci>
		      </m:list>
		    </m:apply>
		    <m:apply>
		      <m:power/>
		      <m:apply>
			<m:ci type="fn">β</m:ci>
			<m:apply>
			  <m:minus/>
			  <m:ci>x</m:ci>
			  <m:ci>k</m:ci>
			</m:apply>
		      </m:apply>
		      <m:ci>n</m:ci>
		    </m:apply>
		    <m:apply>
		      <m:power/>
		      <m:apply>
			<m:ci type="fn">β</m:ci>
			<m:apply>
			  <m:minus/>
			  <m:ci>y</m:ci>
			  <m:ci>l</m:ci>
			</m:apply>
		      </m:apply>
		      <m:ci>n</m:ci>
		    </m:apply>
		  </m:apply>
		</m:apply>
	      </m:apply>
	    </m:apply>
	  </m:math>
	</equation>

	The coefficients 
	<m:math>
	  <m:apply>
	    <m:ci type="fn">c</m:ci>
	    <m:list>
	      <m:ci>k</m:ci>
	      <m:ci>l</m:ci>
	    </m:list>
	  </m:apply>
	</m:math> are obtained by fitting the discrete image to the 2D
	spline basis.
      </para>
    </section>

    <section id="sec2">
      <name>Image Transformation</name>
      <para id="para2">
	Let
	<m:math>
	  <m:apply>
	    <m:eq/>
	    <m:list>
	      <m:ci>x</m:ci>
	      <m:ci>y</m:ci>
	    </m:list>
	    <m:apply>
	      <m:ci type="fn">G</m:ci>
	      <m:list>
		<m:ci>u</m:ci>
		<m:ci>v</m:ci>
	      </m:list>
	    </m:apply>
	  </m:apply>
	</m:math> be the transformation (rotation, scaling) of the
	domain, where 
	<m:math>
	  <m:list>
	    <m:ci>u</m:ci>
	    <m:ci>v</m:ci>
	  </m:list>
	</m:math> describe the transformed plane and 
	<m:math>
	  <m:list>
	    <m:ci>x</m:ci>
	    <m:ci>y</m:ci>
	  </m:list>
	</m:math>
	the original image plane. Then our problem is to find the
	samples of the transformed image
	<m:math>
	  <m:apply>
	    <m:ci type="fn">g</m:ci>
	    <m:list>
	      <m:ci>m</m:ci>
	      <m:ci>n</m:ci>
	    </m:list>
	  </m:apply>
	</m:math> from the samples of original image
	<m:math>
	  <m:apply>
	    <m:ci type="fn">f</m:ci>
	    <m:list>
	      <m:ci>k</m:ci>
	      <m:ci>l</m:ci>
	    </m:list>
	  </m:apply>
	</m:math>. Here is how we go about it:
	<list id="list1">
	  <item>
	    Calculate 
	    <m:math>
	      <m:apply>
		<m:ci type="fn">c</m:ci>
		<m:list>
		  <m:ci>k</m:ci>
		  <m:ci>l</m:ci>
		</m:list>
	      </m:apply>
	    </m:math> from the pixel values 
	    <m:math>
	      <m:apply>
		<m:ci type="fn">f</m:ci>
		<m:list>
		  <m:ci>k</m:ci>
		  <m:ci>l</m:ci>
		</m:list>
	      </m:apply>
	    </m:math>
	  </item>
	  <item>
	    For each 
	    <m:math>
	      <m:list>
		<m:ci>m</m:ci>
	    <m:ci>n</m:ci>
	      </m:list>
	    </m:math> on transformed image find corresponding source
	    location
	    <m:math>
	      <m:list>
		<m:ci>x</m:ci>
		<m:ci>y</m:ci>
	      </m:list>
	    </m:math>
	  </item>
	  <item>
	    Compute 
	    <m:math>
	      <m:apply>
		<m:ci type="fn">f</m:ci>
		<m:list>
		  <m:ci>x</m:ci>
		  <m:ci>y</m:ci>
		</m:list>
	      </m:apply>
	    </m:math> using the spline model, now 
	    <m:math>
	      <m:apply>
		<m:eq/>
		<m:apply>
		  <m:ci type="fn">g</m:ci>
		  <m:list>
		    <m:ci>m</m:ci>
		    <m:ci>n</m:ci>
		  </m:list>
		</m:apply>
		<m:apply>
		  <m:ci type="fn">f</m:ci>
		  <m:list>
		    <m:ci>x</m:ci>
		    <m:ci>y</m:ci>
		  </m:list>
		</m:apply>
	      </m:apply>
	    </m:math>
	  </item>
	</list>
      </para>

      <example id="ex1">
	<para id="para3">
	  In <cnxn target="fig1" strength="9"/> we look at the
	  rotation of an image by certain angle and compare the fits
	  using 
	  <m:math>
	    <m:apply>
	      <m:power/>
	      <m:apply>
		<m:ci type="fn">φ</m:ci>
		<m:list>
		  <m:ci>m</m:ci>
		  <m:ci>n</m:ci>
		</m:list>
	      </m:apply>
	      <m:ci>n</m:ci>
	    </m:apply>
	  </m:math>

	  <m:math>
	    <m:apply>
	      <m:eq/>
	      <m:ci>n</m:ci>
	      <m:cn>0</m:cn>
	    </m:apply>
	  </m:math> (nearest neighbour), 
	  <m:math>
	    <m:apply>
	      <m:eq/>
	      <m:ci>n</m:ci>
	      <m:cn>1</m:cn>
	    </m:apply>
	  </m:math> (bilinear), 
	  <m:math>
	    <m:apply>
	      <m:eq/>
	      <m:ci>n</m:ci>
	      <m:cn>3</m:cn>
	    </m:apply>
	  </m:math> (bicubic).
	</para>

	<figure id="fig1">
	  <media type="image/png" src="thello.png"/>
	  <caption>
	    Illustration of how the jagged edges appear in nearest
	    neighbour interpolation and they progressively smooth out
	    in higher order spline-interpolation. Bicubic spline
	    interpolation is highly popular as cubic splines appear
	    smooth to the human eye.
	  </caption>
	</figure>
      </example>
    </section>
	
  </content>
</document>
