# 图像几何变化

## 图像几何变换

• translation
2D的平移，${x}^{\prime }=x+t$$x'=x+t$
${\overline{x}}^{\prime }=\left[\begin{array}{cc}I& t\\ 0& 1\end{array}\right]\overline{x}$
• rotation+translation
2D刚性运动，${x}^{\prime }=Rx+t$$x'=Rx+t$

正交旋转矩阵，欧式距离保持不变

• scaled rotation
“相似”变化，${x}^{\prime }=sRx+t$$x'=sRx+t$, $s$$s$代表尺度因子

${x}^{\prime }=\left[\begin{array}{cc}sR& t\end{array}\right]\overline{x}=\left[\begin{array}{ccc}a& -b& {t}_{x}\\ b& a& {t}_{y}\end{array}\right]\overline{x}$
相似变换保持直线间的夹角不变

• stretch/squash
改变图像的aspect ratio

${x}^{\prime }={s}_{x}x+{t}_{x}$
${y}^{\prime }={s}_{y}y+{t}_{y}$

• affine
仿射变换写作${x}^{\prime }=A\overline{x}$$x'=A\bar{x}$,$A$$A$是一个$3×4$$3\times4$的矩阵

${x}^{\prime }=\left[\begin{array}{cccc}{a}_{00}& {a}_{01}& {a}_{02}& {a}_{03}\\ {a}_{10}& {a}_{11}& {a}_{12}& {a}_{13}\\ {a}_{20}& {a}_{21}& {a}_{22}& {a}_{23}\end{array}\right]\overline{x}$

- projective

${\stackrel{~}{x}}^{\prime }=\stackrel{~}{H}\stackrel{~}{x},$
${x}^{\prime }=\frac{{h}_{00}x+{h}_{01}y+{h}_{02}}{{h}_{20}x+{h}_{21}y+{h}_{22}}$
${y}^{\prime }=\frac{{h}_{10}x+{h}_{11}y+{h}_{12}}{{h}_{20}x+{h}_{21}y+{h}_{22}}$

- 双线性内插
${x}^{\prime }={a}_{0}+{a}_{1}x+{a}_{2}y+{a}_{6}xy$
${y}^{\prime }={a}_{3}+{a}_{4}x+{a}_{5}y+{a}_{7}xy$

## 图像校正

function H = standardHoughTransform(BW,theta,rho)

coder.inline('always');
coder.internal.prefer_const(BW,theta,rho);

rhoLength   = coder.internal.indexInt(length(rho));
thetaLength = coder.internal.indexInt(length(theta));

firstRho = rho(1);
[numRow,numCol] = size(BW);

% Allocate space for H and initialize to 0
H = zeros(rhoLength,thetaLength);

% Allocate space for cos/sin lookup tables
cost = coder.nullcopy(zeros(thetaLength,1));
sint = coder.nullcopy(zeros(thetaLength,1));

% Pre-compute the sin and cos tables
for i = 1:thetaLength
cost(i) = cos(theta(i) * pi/180);
sint(i) = sin(theta(i) * pi/180);
end

% Compute the factor for converting back to the rho matrix index
slope = double(rhoLength-1) / double(rho(rhoLength) - firstRho);

% Compute the Hough transform
for n = 1:numCol
for m = 1:numRow
if BW(m,n) % if pixel is on
for thetaIdx = 1:thetaLength
% rho = x*cos(theta) + y*sin(theta)
myRho = (n-1) * cost(thetaIdx) + (m-1) * sint(thetaIdx);
% convert to bin index
rhoIdx = roundAndCastInt(slope*(myRho - firstRho)) + 1;
% accumulate
H(rhoIdx,thetaIdx) = H(rhoIdx,thetaIdx)+1;
end
end
end
end

%--------------------------------------------------------------------------
function y = roundAndCastInt(x)

coder.inline('always');
coder.internal.prefer_const(x);

% Only works if x >= 0
y = coder.internal.indexInt(x+0.5);