# 4. 图像几何学
前文有述,将图像对象视作矩阵,对图像进行几何变换,如裁剪,拼接,缩放,实质是对图像矩阵的元素进行数量操作。
## 常用函数
### 裁剪
在计算机视觉中,通常将处理得到有价值的区域称作ROI(region of interest),进行裁剪时,其实是将ROI的坐标作为索引提取出来。
裁剪没有独立的函数,图像裁剪通过直接使用原图像对象中的索引进行截取。
### 拼接
拼接分为横向拼接函数(hconcat),纵向拼接函数(vconcat)
```C++
//横向拼接
void cv::hconcat ( const Mat * src,
size_t nsrc,
OutputArray dst
)
/**
@brief Applies horizontal concatenation to given matrices.
简介 将水平连接应用于给定矩阵。
The function horizontally concatenates two or more cv::Mat matrices (with the same number of rows).
该函数水平连接两个或多个cv::Mat矩阵(行数相同)。
*/
cv::Mat matArray[] = { cv::Mat(4, 1, CV_8UC1, cv::Scalar(1)),
cv::Mat(4, 1, CV_8UC1, cv::Scalar(2)),
cv::Mat(4, 1, CV_8UC1, cv::Scalar(3)),};
cv::Mat out;
cv::hconcat( matArray, 3, out );
//out:
//[1, 2, 3;
// 1, 2, 3;
// 1, 2, 3;
// 1, 2, 3]
/**
@param src input array or vector of matrices. all of the matrices must have the same number of rows and the same depth.
@param nsrc number of matrices in src.
@param dst output array. It has the same number of rows and depth as the src, and the sum of cols of the src.
@sa cv::vconcat(const Mat*, size_t, OutputArray),
@sa cv::vconcat(InputArrayOfArrays, OutputArray) and
@sa cv::vconcat(InputArray, InputArray, OutputArray)
*/
void cv::hconcat ( InputArray src1,
InputArray src2,
OutputArray dst
)
/**
@overload
*/
cv::Mat_<float> A = (cv::Mat_<float>(3, 2) << 1, 4,
2, 5,
3, 6);
cv::Mat_<float> B = (cv::Mat_<float>(3, 2) << 7, 10,
8, 11,
9, 12);
cv::Mat C;
cv::hconcat(A, B, C);
//C:
//[1, 4, 7, 10;
// 2, 5, 8, 11;
// 3, 6, 9, 12]
/*
@param src1 first input array to be considered for horizontal concatenation.
@param src2 second input array to be considered for horizontal concatenation.
@param dst output array. It has the same number of rows and depth as the src1 and src2, and the sum of cols of the src1 and src2.
*/
void cv::hconcat ( InputArrayOfArrays src,
OutputArray dst
)
/**
@overload
*/
std::vector<cv::Mat> matrices = { cv::Mat(4, 1, CV_8UC1, cv::Scalar(1)),
cv::Mat(4, 1, CV_8UC1, cv::Scalar(2)),
cv::Mat(4, 1, CV_8UC1, cv::Scalar(3)),};
cv::Mat out;
cv::hconcat( matrices, out );
//out:
//[1, 2, 3;
// 1, 2, 3;
// 1, 2, 3;
// 1, 2, 3]
/*
@param src input array or vector of matrices. all of the matrices must have the same number of rows and the same depth.
@param dst output array. It has the same number of rows and depth as the src, and the sum of cols of the src same depth.
*/
```
```C++
//纵向拼接
void cv::vconcat ( const Mat * src,
size_t nsrc,
OutputArray dst
)
/**
@brief Applies vertical concatenation to given matrices.
简介 对给定矩阵应用垂直连接。
The function vertically concatenates two or more cv::Mat matrices (with the same number of cols).
该函数垂直连接两个或多个cv::Mat矩阵(具有相同的列数)。
*/
cv::Mat matArray[] = { cv::Mat(1, 4, CV_8UC1, cv::Scalar(1)),
cv::Mat(1, 4, CV_8UC1, cv::Scalar(2)),
cv::Mat(1, 4, CV_8UC1, cv::Scalar(3)),};
cv::Mat out;
cv::vconcat( matArray, 3, out );
//out:
//[1, 1, 1, 1;
// 2, 2, 2, 2;
// 3, 3, 3, 3]
/*
@param src input array or vector of matrices. all of the matrices must have the same number of cols and the same depth.
@param nsrc number of matrices in src.
@param dst output array. It has the same number of cols and depth as the src, and the sum of rows of the src.
@sa cv::hconcat(const Mat*, size_t, OutputArray),
@sa cv::hconcat(InputArrayOfArrays, OutputArray) and
@sa cv::hconcat(InputArray, InputArray, OutputArray)
*/
void cv::vconcat ( InputArray src1,
InputArray src2,
OutputArray dst
)
/**
@overload
*/
cv::Mat_<float> A = (cv::Mat_<float>(3, 2) << 1, 7,
2, 8,
3, 9);
cv::Mat_<float> B = (cv::Mat_<float>(3, 2) << 4, 10,
5, 11,
6, 12);
cv::Mat C;
cv::vconcat(A, B, C);
//C:
//[1, 7;
// 2, 8;
// 3, 9;
// 4, 10;
// 5, 11;
// 6, 12]
/*
@param src1 first input array to be considered for vertical concatenation.
@param src2 second input array to be considered for vertical concatenation.
@param dst output array. It has the same number of cols and depth as the src1 and src2, and the sum of rows of the src1 and src2.
*/
void cv::vconcat ( InputArrayOfArrays src,
OutputArray dst
)
/**
@overload
*/
std::vector<cv::Mat> matrices = { cv::Mat(1, 4, CV_8UC1, cv::Scalar(1)),
cv::Mat(1, 4, CV_8UC1, cv::Scalar(2)),
cv::Mat(1, 4, CV_8UC1, cv::Scalar(3)),};
cv::Mat out;
cv::vconcat( matrices, out );
//out:
//[1, 1, 1, 1;
// 2, 2, 2, 2;
// 3, 3, 3, 3]
/*
@param src input array or vector of matrices. all of the matrices must have the same number of cols and the same depth
@param dst output array. It has the same number of cols and depth as the src, and the sum of rows of the src.
same depth.
*/
```
### 翻转
```c++
void cv::flip ( InputArray src,
OutputArray dst,
int flipCode
)
/**
@brief Flips a 2D array around vertical, horizontal, or both axes.
简介 围绕垂直、水平或两个轴翻转二维阵列。
The function cv::flip flips the array in one of three different ways (row
and column indices are 0-based):
函数cv::flip以三种不同方式之一翻转阵列(行和列索引是基于0的)
*/
```
```[tex]
\texttt{dst} _{ij} =
\left\{
\begin{array}{l l}
\texttt{src} _{\texttt{src.rows}-i-1,j} & if\; \texttt{flipCode} = 0 \\
\texttt{src} _{i, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} > 0 \\
\texttt{src} _{ \texttt{src.rows} -i-1, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} < 0 \\
\end{array}
\right.
```
```C++
/*
The example scenarios of using the function are the following:
使用该函数的示例场景如下:
* Vertical flipping of the image (flipCode == 0) to switch between
top-left and bottom-left image origin. This is a typical operation
in video processing on Microsoft Windows\* OS.
** 垂直翻转图像(flipCode==0)以在左上角和左下角图像原点之间切换。这是Microsoft
Windows*操作系统上视频处理的典型操作。
* Horizontal flipping of the image with the subsequent horizontal
shift and absolute difference calculation to check for a
vertical-axis symmetry (flipCode \> 0).
** 水平翻转图像,随后进行水平移动和绝对差计算,以检查垂直轴对称性(flipCode>0)。
* Simultaneous horizontal and vertical flipping of the image with
the subsequent shift and absolute difference calculation to check
for a central symmetry (flipCode \< 0).
** 同时水平和垂直翻转图像,随后进行移位和绝对差计算,以检查中心对称(flipCode<0)。
* Reversing the order of point arrays (flipCode \> 0 or flipCode == 0).
** 颠倒点阵列的顺序(flipCode>0或flipCode==0)。
@param src input array.
@param dst output array of the same size and type as src.
@param flipCode a flag to specify how to flip the array; 0 means flipping around the x-axis and positive value (for example, 1) means flipping around y-axis. Negative value (for example, -1) means flipping around both axes.
@sa transpose , repeat , completeSymm
*/
```
### 缩放
```C++
void cv::resize ( InputArray src,
OutputArray dst,
Size dsize,
double fx = 0,
double fy = 0,
int interpolation = INTER_LINEAR
)
/**
@brief Resizes an image.
简介 调整图像的大小
The function resize resizes the image src down to or up to the specified size. Note that the initial dst type or size are not taken into account. Instead, the size and type are derived from the `src`,`dsize`,`fx`, and `fy`. If you want to resize src so that it fits the pre-created dst, you may call the function as follows:
函数resize将图像src的大小调整为指定大小。请注意,未考虑初始dst类型或大小。相反,大小和类型是从'src'、'dsize'、'fx'和'fy'派生的。如果要调整src的大小,使其适合预先创建的dst, 您可以按如下方式调用该函数:
*/
// explicitly specify dsize=dst.size(); fx and fy will be computed from that.
resize(src, dst, dst.size(), 0, 0, interpolation);
/*
If you want to decimate the image by factor of 2 in each direction, you can call the function this way:
如果要按每个方向上的2倍抽取图像,可以调用以下函数:
*/
// specify fx and fy and let the function compute the destination image size.
resize(src, dst, Size(), 0.5, 0.5, interpolation);
/*
To shrink an image, it will generally look best with #INTER_AREA interpolation, whereas to enlarge an image, it will generally look best with INTER_CUBIC (slow) or #INTER_LINEAR (faster but still looks OK).
要缩小图像,通常使用#INTER_AREA插值效果最好,而要放大图像,通常使用#INTER_CUBIC (slow)(慢速)或#INTER_LINEAR插值效果最好(速度更快,但看起来仍然可以)。
@param src input image.
@param dst output image; it has the size dsize (when it is non-zero) or the size computed from src.size(), fx, and fy; the type of dst is the same as of src.
@param dsize output image size; if it equals zero, Either dsize or both fx and fy must be non-zero.
@param fx scale factor along the horizontal axis;
@param fy scale factor along the vertical axis;
@param interpolation interpolation method, see #InterpolationFlags
@sa warpAffine, warpPerspective, remap
*/
```
```[tex]
\begin{matrix}
\texttt{dsize}&=&& \texttt{Size(round(fx*src.cols), round(fy*src.rows))} & if\ & \texttt{dsize}=0\\
\texttt{dx}&=&&\texttt{(double)dsize.width/src.cols} & if\ & \texttt{dx} = 0\\
\texttt{dy}&=&&\texttt{(double)dsize.height/src.rows} & if\ & \texttt{dy} = 0\\
\end{matrix}
```
### 旋转
这个旋转的作用很鸡肋,只可以旋转90°、180°、270°,任意角度的旋转参考后面的[仿射变换](#####仿射变换)章节
```C++
void cv::rotate ( InputArray src,
OutputArray dst,
int rotateCode
)
/**
@brief Rotates a 2D array in multiples of 90 degrees.
简介 以90度的倍数旋转二维阵列。
The function cv::rotate rotates the array in one of three different ways:
* Rotate by 90 degrees clockwise (rotateCode = ROTATE_90_CLOCKWISE).
* Rotate by 180 degrees clockwise (rotateCode = ROTATE_180).
* Rotate by 270 degrees clockwise (rotateCode = ROTATE_90_COUNTERCLOCKWISE).
@param src input array.
@param dst output array of the same type as src. The size is the same with ROTATE_180, and the rows and cols are switched for ROTATE_90_CLOCKWISE and ROTATE_90_COUNTERCLOCKWISE.
@param rotateCode an enum to specify how to rotate the array; see the enum #RotateFlags
@sa transpose , repeat , completeSymm, flip, RotateFlags
*/
enum RotateFlags {
ROTATE_90_CLOCKWISE = 0, //!<Rotate 90 degrees clockwise
ROTATE_180 = 1, //!<Rotate 180 degrees clockwise
ROTATE_90_COUNTERCLOCKWISE = 2, //!<Rotate 270 degrees clockwise
};
```
### 图像位运算
位运算一般在二值化图像中使用,每个像素的值为1或0,可以进行数字运算。
>[info] 与、或、非、异或
| A | B | and | or | (A)not | xor |
| ---- | ---- | ---- | ---- | ------ | ---- |
| 0 | 0 | 0 | 0 | 1 | 0 |
| 0 | 1 | 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 | 0 | 0 |
常用的只有bitwise_and 按位与函数
```C++
void cv::bitwise_and ( InputArray src1,
InputArray src2,
OutputArray dst,
InputArray mask = noArray()
)
/**
@brief computes bitwise conjunction of the two arrays (dst = src1 & src2) Calculates the per-element bit-wise conjunction of two arrays or an array and a scalar.
简介 计算两个数组(dst=src1&src2)的按位合取计算两个数组或一个数组和一个标量的每元素按位合取。
The function cv::bitwise_and calculates the per-element bit-wise logical conjunction for:
函数cv::bitwise_and 计算以下各项的每元素逐位逻辑连接:
*/
```
* Two arrays when `$ \texttt{src1} $` and `$ \texttt{src2} $` have the same size:
```[tex]
\texttt{dst}(I) = \texttt{src1}(I) \wedge \texttt{src2}(I) \quad \texttt{if mask} (I) \ne 0
```
* An array and a scalar when `$ \texttt{src2} $` is constructed from Scalar or has
the same number of elements as `src1.channels()`:
```[tex]
\texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} \quad \texttt{if mask} (I) \ne0
```
* A scalar and an array when `$ \texttt{src1} $` is constructed from Scalar or has
the same number of elements as `src2.channels()`:
```[tex]
\texttt{dst} (I) = \texttt{src1} \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0
```
```C++
/*
In case of floating-point arrays, their machine-specific bit representations (usually IEEE754-compliant) are used for the operation. In case of multi-channel arrays, each channel is processed independently. In the second and third cases above, the scalar is first converted to the array type.
对于浮点数组,其特定于机器的位表示(通常符合IEEE754)用于操作。对于多通道阵列,每个通道都是独立处理的。在上面的第二和第三种情况下,标量首先转换为数组类型。
@param src1 first input array or a scalar.
@param src2 second input array or a scalar.
@param dst output array that has the same size and type as the input arrays.
@param mask optional operation mask, 8-bit single channel array, that specifies elements of the output array to be changed.
*/
```
其余的还有`bitwise_not`、`bitwise_or`、 `bitwise_xor`