OpenCV 有两个函数,用来将图像尺寸缩小一半或扩大一半:
-
pyrDown
-
pyrUp
这两个函数用来形成图像的高斯金字塔(Gaussian pyramid)。其中 pyrDown 用来将图像的尺寸缩小一半。函数原型如下: -
void pyrDown(InputArray src, OutputArray dst, const Size& dstsize=Size());
原理上这个函数是先做一个高斯低通滤波,然后再降采样。第三个参数 dstsize 是输出图像的 size,但是这个 size 不能随便填,只能是输入图像的尺寸的一半,或者一半 ± 1。通常不用填,用默认值就挺好。
-
下面是例子程序:
cv::Mat image = cv::imread(“test.jpg”);
cv::imshow(“ori”, image);
cv::Mat out;
cv::pyrDown(image, out);
cv::imshow(“pyrDown”, out);
pyrUp 将图像放大一倍。函数原型如下: -
void pyrUp( InputArray src, OutputArray dst, const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
下面是一个例子。
cv::Mat image = cv::imread("test.jpg"); cv::imshow("ori", image); cv::Mat out, out2; cv::pyrDown(image, out); cv::imshow("pyrDown", out); cv::pyrUp(out, out2); cv::imshow("pyrUp", out2);
这里需要说明的是 pyrUp 和 pyrDown 都是会损失图像质量的。下面的例子我们重复调用 pyrUp 和 pyrDown 50次。之后的图像会变模糊。
cv::Mat out, out2;
cv::pyrUp(image, out);
cv::pyrDown(out, out2);
for(int i = 0; i < 50; i++)
{
cv::pyrUp(out2, out);
cv::pyrDown(out, out2);
}
cv::imshow("pyrUp+pyrDown", out2);
输出结果如下:
除了这两个之外,还有个 resize 函数,这个函数既能缩小又能放大。
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation = INTER_LINEAR )
- src – 原始图像
- dst – 输出图像
- dsize – 输出图像的大小,当 dsize 设为 0 时则根据 fx 和 fy 自动计算合适的图像大小。
- fx – 水平方向放缩系数,为 0 时则使用 dsize 大小自动计算
- fy – 垂直方向放缩系数,为 0 时则使用 dsize 大小自动计算
- interpolation – 插值方法,可以为:
- CV_INTER_NN - 最近邻插值,
- CV_INTER_LINEAR - 双线性插值 (缺省使用)
- CV_INTER_AREA - 使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 CV_INTER_NN 方法…
- CV_INTER_CUBIC - 立方插值.
下面是一个例子:
cv::Mat out;
cv::resize(image, out, cv::Size(image.cols, image.rows / 2));
cv::imshow("resize", out);
结果如下:
可以看到 resize 函数可以做到图像的任意缩放。