缩放是处理图像中经常用到的方法,opencv中也专门封装了此类函数,就是cv::resize
,下面先来看一下源码中的函数原型
CV_EXPORTS_W void resize(InputArray src, OutputArray dst,
Size dsize, double fx = 0, double fy = 0,
int interpolation = INTER_LINEAR);
InputArray src
输入图像cv::Mat类型
OutputArray dst
输出图像cv::Mat类型
Size dsize
缩放后的尺寸
double fx = 0
x缩放比例,默认为0
double fy = 0
y缩放比例,默认为0
int interpolation = INTER_LINEAR
插值法,默认为双线性插值
再来看一个例子
#include
using namespace std;
using namespace cv;
int main() {
Mat frame, clone_frame;
frame = imread("D:/cat.jpg", 3);
clone_frame = frame.clone();
cout << "front of the scale image.rows:" << clone_frame.rows << " " << "image.cols:"
<< clone_frame.cols << endl;
double scale = 0.5;
//放缩会导致图像失真,缩小时interpolation使用INTER_AREA,放大时使用INTER_LINEAR减少失真
resize(clone_frame, clone_frame, Size(int(frame.cols * scale),
int(frame.rows * 0.5)), 0, 0,
INTER_AREA);
cout << "behind of the scale image.rows:" << clone_frame.rows << " " << "image.cols:"
<< clone_frame.cols << endl;
imshow("resize_img", clone_frame);
waitKey(0);
return 0;
}
front of the scale image.rows:745 image.cols:746
behind of the scale image.rows:372 image.cols:373
效果显示
注意使用resize进行缩放的时候,会出现图像失真问题,插值法有利于减少失真。
常见插值法
interpolation option | method |
---|---|
INTER_NEAREST | 最近邻插值法 |
INTER_LINEAR | 双线性插值法 |
INTER_AREA | 使用像素区域关系进行重采样,图像抽取时可以优先考虑,它会产生无云纹理的结果。 |
INTER_CUBIC | 4*4像素领域的双三次插值法 |
INTER_LANCZOS4 | 8*8像素领域的Lanczos插值法 |
先来看一下源码中的函数原型
CV_EXPORTS_W void transpose(InputArray src, OutputArray dst);
再来看一下源码中对此函数的描述
The function cv::transpose transposes the matrix src :
\f[\texttt{dst} (i,j) = \texttt{src} (j,i)\f]
@note No complex conjugation is done in case of a complex matrix. It
should be done separately if needed.
@param src input array.
@param dst output array of the same type as src.
这段话描述的重点在第二句话上\f[\texttt{dst} (i,j) = \texttt{src} (j,i)\f]
,这句话介绍了这个函数的功能相当于矩阵的转置,即将矩阵沿着对角线进行翻转。
再来看一下代码的实现和效果
#include
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main() {
Mat frame, clone_frame;
frame = imread("D:/cat.jpg", 3);
clone_frame = frame.clone();
double scale = 0.5;
resize(clone_frame, clone_frame, Size(int(frame.cols * scale),
int(frame.rows * scale)),
0, 0, INTER_AREA);
transpose(clone_frame, clone_frame);
imshow("transpose_frame", clone_frame);
waitKey(0);
return 0;
}
先来看一下源码种rotate的函数原型
CV_EXPORTS_W void rotate(InputArray src, OutputArray dst, int rotateCode);
enum RotateFlags {
ROTATE_90_CLOCKWISE = 0, //!
ROTATE_180 = 1, //!
ROTATE_90_COUNTERCLOCKWISE = 2, //!
};
再来看一下源码中对于函数的描述
/** @brief Rotates a 2D array in multiples of 90 degrees.
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
*/
上面这段话大概意思就是rotate函数能够按照顺时针的方法以三种不同的角度进行旋转,三种角度分别是90度,180度,270度
。rotateCode参数可以取枚举类型RotateFlags中的值,0表示90度,1表示180度,2表示270度
接下来我们使用cv::rotate
来演示一下顺时针旋转180度的操作
#include
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main() {
Mat frame, clone_frame;
frame = imread("D:/cat.jpg", 3);
clone_frame = frame.clone();
double scale = 0.5;
resize(clone_frame, clone_frame, Size(int(frame.cols * scale),
int(frame.rows * scale)),
0, 0, INTER_AREA);
cv::rotate(clone_frame, clone_frame, 1);
imshow("rotate_180_frame", clone_frame);
waitKey(0);
return 0;
}
先来看一下源码中的函数原型
CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode);
再来看一下源码中主要的函数描述
@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.
上面这段话中最后一个paramflipCode
的意思是flipCode可以控制翻转的三种不同的方式,0表示以x轴对称进行翻转,大于0时表示以y轴对称进行翻转,小于0时分别以x轴对称和y轴对称进行翻转。
下面演示一下以x轴,y轴为对称轴和分别以x,y轴对称进行翻转的示例
#include
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main() {
Mat frame, clone_frame;
frame = imread("D:/cat.jpg", 3);
clone_frame = frame.clone();
double scale = 0.5;
resize(clone_frame, clone_frame, Size(int(frame.cols * scale),
int(frame.rows * scale)),
0, 0, INTER_AREA);
//y
flip(clone_frame, clone_frame, 1);
//x,y
//flip(clone_frame,clone_frame,-1);
//x
//flip(clone_frame,clone_frame,0);
imshow("flip_y_frame", clone_frame);
waitKey(0);
return 0;
}