{"id":74,"date":"2006-08-01T07:00:48","date_gmt":"2006-08-01T11:00:48","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=74"},"modified":"2019-10-22T14:02:11","modified_gmt":"2019-10-22T18:02:11","slug":"spatial-transformations-controlling-the-input-and-output-grids-with-imtransform","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2006\/08\/01\/spatial-transformations-controlling-the-input-and-output-grids-with-imtransform\/","title":{"rendered":"Spatial transformations: Controlling the input and output grids with imtransform"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p>The function <tt>imtransform<\/tt> has several optional parameters that allow you to fine-tune its behavior.  Today's topic is about the parameters that let\r\n         you control where the input image lives in input space, as well as the location and spacing of the output space pixel grid.\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#1\">Input image location<\/a><\/li>\r\n         <li><a href=\"#4\">Output space pixel grid<\/a><\/li>\r\n         <li><a href=\"#5\">Example<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Input image location<a name=\"1\"><\/a><\/h3>\r\n   <p><tt>imtransform<\/tt> assumes that an M-by-N input image lives in input space inside a rectangle spanning from 0.5 to M+0.5 horizontally, and from\r\n      0.5 to N+0.5 vertically.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">I = checkerboard(1,4);\r\nimshow(I, <span style=\"color: #A020F0\">'initialmag'<\/span>, <span style=\"color: #A020F0\">'fit'<\/span>)\r\naxis <span style=\"color: #A020F0\">on<\/span>\r\nbox <span style=\"color: #A020F0\">on<\/span>\r\nset(gca, <span style=\"color: #A020F0\">'XTick'<\/span>, [1 8], <span style=\"color: #A020F0\">'YTick'<\/span>, [1 8])\r\nxlabel(<span style=\"color: #A020F0\">'u axis'<\/span>)\r\nylabel(<span style=\"color: #A020F0\">'v axis'<\/span>)\r\ntitle(<span style=\"color: #A020F0\">'8-by-8 image'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/73\/imtransform_grid_control_01.png\"> <p>What if you want the input image to be in some other location? Sometimes, for example, it's convenient to place the center\r\n      of the image at the input-space origin.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\"><span style=\"color: #228B22\">% imshow doesn't know about u-v space, just x-y space, so its parameters<\/span>\r\n<span style=\"color: #228B22\">% are called XData and YData.<\/span>\r\nimshow(I, <span style=\"color: #A020F0\">'XData'<\/span>, [-3.5 3.5], <span style=\"color: #A020F0\">'YData'<\/span>, [-3.5 3.5], <span style=\"color: #A020F0\">'initialmag'<\/span>, <span style=\"color: #A020F0\">'fit'<\/span>)\r\naxis <span style=\"color: #A020F0\">on<\/span>\r\nbox <span style=\"color: #A020F0\">on<\/span>\r\nset(gca, <span style=\"color: #A020F0\">'XTick'<\/span>, [-3.5 0 3.5], <span style=\"color: #A020F0\">'YTick'<\/span>, [-3.5 0 3.5])\r\nxlabel(<span style=\"color: #A020F0\">'u axis'<\/span>)\r\nylabel(<span style=\"color: #A020F0\">'v axis'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/73\/imtransform_grid_control_02.png\"> <p>You can place imtransform's input image where you want in <i>u-v<\/i> space by specifying the UData and VData parameters.  UData is a two-element vector.  Its first value is the <i>u<\/i>-coordinate of the first column of the input image.  Its second value is the <i>u<\/i>-coordinate of the last column. Similarly, VData is a two-element vector containing the <i>v<\/i>-coordinates of the first and last rows of the input image.\r\n   <\/p>\r\n   <p>To place the center of an M-by-N image at the origin, specify UData to be <tt>[1 N] - (N+1)\/2<\/tt> and VData to be <tt>[1 M] - (M+1)\/2<\/tt>.\r\n   <\/p>\r\n   <h3>Output space pixel grid<a name=\"4\"><\/a><\/h3>\r\n   <p><tt>imtransform<\/tt> determines the bounding rectangle of the transformed image in output space and then overlays a pixel grid on that rectangle.\r\n       The pixels in the output grid have the same size as the input image pixels.\r\n   <\/p>\r\n   <p>You can modify the grid location and pixel size by specifying the XData, YData, and Size parameters in the call to imtransform.<\/p>\r\n   <p>XData and YData are similar to UData and VData.  XData is a two-element vector containing the <i>x<\/i>-coordinates of the first and last columns of the output image.  YData is a two-element vector containing the <i>y<\/i>-coordinates of the first and last rows of the output image.\r\n   <\/p>\r\n   <p>The Size parameter is a two-element vector specifying how many rows and columns are in the output space grid.<\/p>\r\n   <h3>Example<a name=\"5\"><\/a><\/h3>\r\n   <p>Here's your task: Position an input image centered at the origin and extending from -1 to 1 in the horizontal and vertical\r\n      directions.  Apply a 45 degree rotation to it.  Compute the output image only inside a square extending from -0.8 to 0.8 horizontally\r\n      and vertically.  Also, compute the output image using only one-eighth as many pixels (in each direction) as the image input.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">I = imread(<span style=\"color: #A020F0\">'pout.tif'<\/span>);\r\nimshow(I)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/73\/imtransform_grid_control_03.png\"> <pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">T = [1 -sin(pi\/4) 0; sin(pi\/4) 1 0; 0 0 1];\r\ntform = maketform(<span style=\"color: #A020F0\">'affine'<\/span>, T);\r\n\r\nudata = [-1 1];\r\nvdata = [-1 1];\r\n\r\nxdata = [-0.8 0.8];\r\nydata = [-0.8 0.8];\r\noutput_size = round(size(I)\/8);\r\n\r\nJ = imtransform(I, tform, <span style=\"color: #A020F0\">'UData'<\/span>, udata, <span style=\"color: #A020F0\">'VData'<\/span>, vdata, <span style=\"color: #0000FF\">...<\/span>\r\n    <span style=\"color: #A020F0\">'XData'<\/span>, xdata, <span style=\"color: #A020F0\">'YData'<\/span>, ydata, <span style=\"color: #A020F0\">'Size'<\/span>, output_size);\r\n\r\nimshow(J)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/73\/imtransform_grid_control_04.png\"> <p>In an upcoming post I'm going to demonstrate how to define and apply custom spatial transformations.  This post will include\r\n      more examples illustrating the use of UData, VData, XData, and YData.\r\n   <\/p>\r\n<script language=\"JavaScript\"> \r\n<!--\r\n    function grabCode_74() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='74 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 74';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        author = 'Steve Eddins';\r\n        copyright = 'Copyright 2006 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n      \r\n      d.title = title + ' (MATLAB code)';\r\n      d.close();\r\n      }   \r\n-->\r\n      <\/script>\r\n<noscript>\r\n<em>A JavaScript-enabled browser is required to use the \"Get the MATLAB code\" link.<\/em>\r\n<\/noscript>\r\n<p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_74()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code<\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.2<br><\/p>\r\n<\/div>\r\n<!--\r\n74 ##### SOURCE BEGIN #####\r\n%% Spatial transformations: Controlling the input and output grids with imtransform\r\n% The function <https:\/\/www.mathworks.com\/help\/images\/index.htmlimtransform.html \r\n% |imtransform|> has several optional parameters that allow you\r\n% to fine-tune its behavior.  Today's topic is about the parameters that\r\n% let you control where the input image lives in input space, as well as\r\n% the location and spacing of the output space pixel grid.\r\n\r\n%% Input image location\r\n% |imtransform| assumes that an M-by-N input image lives in input\r\n% space inside a rectangle spanning from 0.5 to M+0.5 horizontally, and\r\n% from 0.5 to N+0.5 vertically.\r\n\r\nI = checkerboard(1,4);\r\nimshow(I, 'initialmag', 'fit')\r\naxis on\r\nbox on\r\nset(gca, 'XTick', [1 8], 'YTick', [1 8])\r\nxlabel('u axis')\r\nylabel('v axis')\r\ntitle('8-by-8 image')\r\n\r\n%%\r\n% What if you want the input image to be in some other location?\r\n% Sometimes, for example, it's convenient to place the center of the image\r\n% at the input-space origin.\r\n\r\n% imshow doesn't know about u-v space, just x-y space, so its parameters\r\n% are called XData and YData.\r\nimshow(I, 'XData', [-3.5 3.5], 'YData', [-3.5 3.5], 'initialmag', 'fit')\r\naxis on\r\nbox on\r\nset(gca, 'XTick', [-3.5 0 3.5], 'YTick', [-3.5 0 3.5])\r\nxlabel('u axis')\r\nylabel('v axis')\r\n\r\n%%\r\n% You can place imtransform's input image where you want in _u-v_ space\r\n% by specifying the UData and VData parameters.  UData is a two-element\r\n% vector.  Its first value is the _u_-coordinate of the first column of the\r\n% input image.  Its second value is the _u_-coordinate of the last column.\r\n% Similarly, VData is a two-element vector containing the _v_-coordinates of\r\n% the first and last rows of the input image.\r\n%\r\n% To place the center of an M-by-N image at the origin, specify UData to be\r\n% |[1 N] - (N+1)\/2| and VData to be |[1 M] - (M+1)\/2|.\r\n\r\n%% Output space pixel grid\r\n% |imtransform| determines the bounding rectangle of the transformed image in\r\n% output space and then overlays a pixel grid on that rectangle.  The\r\n% pixels in the output grid have the same size as the input image pixels.\r\n%\r\n% You can modify the grid location and pixel size by specifying the XData,\r\n% YData, and Size parameters in the call to imtransform.\r\n%\r\n% XData and YData are similar to UData and VData.  XData is a two-element\r\n% vector containing the _x_-coordinates of the first and last columns of\r\n% the output image.  YData is a two-element vector containing the\r\n% _y_-coordinates of the first and last rows of the output image.\r\n%\r\n% The Size parameter is a two-element vector specifying how many rows and\r\n% columns are in the output space grid.\r\n\r\n%% Example\r\n% Here's your task: Position an input image centered at the origin and\r\n% extending from -1 to 1 in the horizontal and vertical directions.  Apply\r\n% a 45 degree rotation to it.  Compute the output image only inside a square\r\n% extending from -0.8 to 0.8 horizontally and vertically.  Also, compute the\r\n% output image using only one-eighth as many pixels (in each direction) as the\r\n% image input.\r\n\r\nI = imread('pout.tif');\r\nimshow(I)\r\n\r\n%%\r\n\r\nT = [1 -sin(pi\/4) 0; sin(pi\/4) 1 0; 0 0 1];\r\ntform = maketform('affine', T);\r\n\r\nudata = [-1 1];\r\nvdata = [-1 1];\r\n\r\nxdata = [-0.8 0.8];\r\nydata = [-0.8 0.8];\r\noutput_size = round(size(I)\/8);\r\n\r\nJ = imtransform(I, tform, 'UData', udata, 'VData', vdata, ...\r\n    'XData', xdata, 'YData', ydata, 'Size', output_size);\r\n\r\nimshow(J)\r\n\r\n%%\r\n% In an upcoming post I'm going to demonstrate how to define and apply\r\n% custom spatial transformations.  This post will include more examples \r\n% illustrating the use of UData, VData, XData, and YData.\r\n\r\n\r\n\r\n\r\n\r\n\r\n##### SOURCE END ##### 74\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n      The function imtransform has several optional parameters that allow you to fine-tune its behavior.  Today's topic is about the parameters that let\r\n         you control where the input... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2006\/08\/01\/spatial-transformations-controlling-the-input-and-output-grids-with-imtransform\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[10],"tags":[50,186,182,80,76,36,62,188,34,190,52,94,96],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/74"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=74"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/74\/revisions"}],"predecessor-version":[{"id":2197,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/74\/revisions\/2197"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=74"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=74"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=74"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}