同时填充和剪切图像
此示例显示了如何构造tform
表示简单的剪切转换,然后将其应用于图像。我们探索转换如何影响直线和圆圈,然后将其用作探索可以与图像填充的各种选项一起使用的工具Imtransform
和tformarray
。
步骤1:使用简单剪切变换图像
在二维中,简单的剪切转换映射了一对输入坐标[紫外线]
到一对输出坐标[x y]
有形式
在哪里一种
是一个常数。
任何简单的剪切都是仿射转化的特殊情况。您可以轻松验证
产生值的值X
和y
您从前两个方程式收到的。
环境一种
= 0.45,我们构建了一个仿射tform
结构使用maketform
。
a = 0.45;t = maketform(“仿射”,[1 0 0;A 1 0;0 0 1]);
我们选择,读取和查看和图像进行转换。
a = imread('football.jpg');H1 =图;imshow(a);标题(“原始图像”);
我们选择橙色的阴影作为填充价值。
橙色= [255 127 0]';
我们准备好使用t
转变一种
。我们可以打电话Imtransform
如下:
b = imtransform(a,t,'cutic','fillvalues',橙色);
但这是浪费的,因为我们将沿着列和行沿两种立方插值进行插值。(有了我们的纯剪切变换,我们实际上只需要沿每一行插值。)相反,我们创建和使用一个沿行施加立方插值的重采样器,而只需使用沿列的最近的邻居插值,然后调用Imtransform
并显示结果。
r = makeresampler({'立方体',,,,“最近”},,'填');b = imtransform(a,t,r,“填充”,橙);H2 =图;imshow(b);标题(“剪切图像”);
步骤2:探索转换
转换直线或一系列圆圈的网格tformfwd
是理解转换的好方法(只要它具有前向功能和逆函数)。
定义覆盖原始图像的线条网格,并通过图像显示,然后使用tformfwd
将纯剪切涂在网格中的每一行上,并在剪切图像上显示结果。
[u,v] = meshgrid(0:64:320,0:64:256);[x,y] = tformfwd(t,u,v);灰色= 0.65 * [1 1 1];图(H1);抓住在;线(u,v,'颜色',灰色的);线(u',v','颜色',灰色的);
图(H2);抓住在;线(x,y,'颜色',灰色的);线(x',y','颜色',灰色的);
您可以用一系列圆圈做同样的事情。
灰色= 0.65 * [1 1 1];为了U = 0:64:320为了v = 0:64:256 theta =(0:32)' *(2 * pi / 32);uc = u + 20*cos(theta);vc = v + 20*sin(theta);[XC,YC] = TFORMFWD(T,UC,VC);图(H1);线(UC,VC,'颜色',灰色的);图(H2);线(XC,YC,'颜色',灰色的);结尾结尾
步骤3:比较“填充”,“重复”和“绑定”垫方法
当我们应用剪切转换时,Imtransform
在没有数据的情况下,填充左右的橙色三角形。那是因为我们指定了一种PAD方法'填'
打电话时Makeresampler
。共有五种不同的PAD方法选择('填'
,,,,'复制'
,,,,'边界'
,,,,'圆'
, 和“对称”
)。在这里,我们比较前三个。
首先,更好地了解'填'
选项有效,使用'xdata'
和'ydata'
选项Imtransform
在输出图像周围强制一些额外的空间。
r = makeresampler({'立方体',,,,“最近”},,'填');bf = imtransform(a,t,r,'xdata',[-49 500],'ydata',[-49 400],...“填充”,橙);图,Imshow(BF);标题('pad方法=''填充'');
现在,尝试'复制'
方法(在这种情况下无需指定填充值)。
r = makeresampler({'立方体',,,,“最近”},,'复制');br = imtransform(a,t,r,'xdata',[-49 500],'ydata',[-49 400]);图,imshow(br);标题('pad方法=''replicate''');
并尝试'边界'
方法。
r = makeresampler({'立方体',,,,“最近”},,'边界');bb = imtransform(a,t,r,'xdata',[-49 500],'ydata',[-49 400],...“填充”,橙);图,imshow(bb);标题('pad方法=''绑定'');
结果'填'
和'边界'
看起来非常相似,但是仔细观察,您会发现边缘更光滑'填'
。这是因为输入图像用填充值填充,然后将立方插值施加在边缘上,将填充和图像值混合。相比之下,'边界'
识别输入图像内部和外部之间的严格边界。掉入外面的点被填满了。落入内部的点是插值的,当它们靠近边缘时使用复制。近距离的外观有助于更清楚地显示出来。我们选择XDATA
和YDATA
要将图像右下角附近的点括起来,在输出图像空间中,调整大小“最近”
保留单个像素的外观。
r = makeresampler({'立方体',,,,“最近”},,'填');cf = imtransform(a,t,r,'xdata',[423 439],,'ydata',[245 260],...“填充”,橙);r = makeresampler({'立方体',,,,“最近”},,'边界');cb = imtransform(a,t,r,'xdata',[423 439],,'ydata',[245 260],...“填充”,橙);cf = imresize(cf,12,“最近”);CB = Imresize(CB,12,“最近”);数字;子图(1,2,1);imshow(cf);标题('pad方法=''填充'');子图(1,2,2);Imshow(CB);标题('pad方法=''绑定'');
步骤4:锻炼“圆形”和“对称”垫方法
其余两种垫方法是'圆'
(在每个维度中的循环重复)和“对称”
(用附加的镜像对图像进行圆形重复)。为了显示出更多出现的模式,我们重新定义了转换以将比例切成两半。
thalf = maketform(“仿射”,[1 0;A 1;0 0]/2);r = makeresampler({'立方体',,,,“最近”},,'圆');bc = imtransform(a,thalf,r,'xdata',[-49 500],'ydata',[-49 400],...“填充”,橙);图,Imshow(BC);标题('PAD方法=''圆形'');
r = makeresampler({'立方体',,,,“最近”},,“对称”);bs = imtransform(a,thalf,r,'xdata',[-49 500],'ydata',[-49 400],...“填充”,橙);图,Imshow(BS);标题('pad方法=''对称''');