十三、OpenCV中的图像的向上采样和向下采样
文章目录
- 一、基本概念
- 二、OpenCV 提供的函数
- 三、示例代码
- 四、扩展:图像金字塔构建示例
- 五、实时摄像头金字塔采样演示
一、基本概念
在 OpenCV 中,图像的向上采样(Upsampling) 和 向下采样(Downsampling) 是常用的图像金字塔(Pyramid)操作,主要用于多分辨率处理(例如目标检测、图像金字塔匹配、金字塔融合等)。
二、OpenCV 提供的函数
OpenCV 提供了两种专用的函数:
pyrUp() // 向上采样(放大)
pyrDown() // 向下采样(缩小)
它们都属于 图像金字塔(Image Pyramid) 操作,会在采样前后自动进行高斯滤波以减少混叠(aliasing)。
函数参数说明:
pyrUp(InputArray src, OutputArray dst, const Size& dstsize = Size(), int borderType = BORDER_DEFAULT);
pyrDown(InputArray src, OutputArray dst, const Size& dstsize = Size(), int borderType = BORDER_DEFAULT);
与 resize() 的区别:
- 如果只是要简单缩放(例如 1.3×、0.75×),推荐用 resize();
- 如果要做图像金字塔(层层上下采样),推荐用 pyrUp/pyrDown。
三、示例代码
向下采样(pyrDown):
#include <opencv2/opencv.hpp>
using namespace cv;int main() {Mat src = imread("test.jpg");if (src.empty()) return -1;Mat dst;pyrDown(src, dst); // 图像缩小一半imshow("Original", src);imshow("Downsampled", dst);waitKey(0);return 0;
}
输出图像尺寸约为原图的一半。
向上采样(pyrUp):
#include <opencv2/opencv.hpp>
using namespace cv;int main() {Mat src = imread("test.jpg");if (src.empty()) return -1;Mat dst;pyrUp(src, dst); // 图像放大一倍imshow("Original", src);imshow("Upsampled", dst);waitKey(0);return 0;
}
输出图像尺寸约为原图的两倍。
四、扩展:图像金字塔构建示例
#include <opencv2/opencv.hpp>
using namespace cv;int main() {Mat src = imread("test.jpg");if (src.empty()) return -1;Mat pyr1, pyr2;pyrDown(src, pyr1);pyrDown(pyr1, pyr2);imshow("Level 0", src);imshow("Level 1", pyr1);imshow("Level 2", pyr2);waitKey(0);return 0;
}
五、实时摄像头金字塔采样演示
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;// 全局变量
int downLevel = 0; // 向下采样层数
int upLevel = 0; // 向上采样层数// 回调函数(当滑动条调整时被调用)
void onChange(int, void*) {// 不需要实现逻辑,主循环中会读取值
}int main() {VideoCapture cap(0); // 打开默认摄像头if (!cap.isOpened()) {cout << "无法打开摄像头!" << endl;return -1;}namedWindow("Pyramid Demo", WINDOW_AUTOSIZE);// 创建滑动条,控制采样层数createTrackbar("Down Level", "Pyramid Demo", &downLevel, 3, onChange);createTrackbar("Up Level", "Pyramid Demo", &upLevel, 3, onChange);while (true) {Mat frame;cap >> frame;if (frame.empty()) break;Mat result = frame.clone();// 向下采样for (int i = 0; i < downLevel; ++i) {pyrDown(result, result);}// 向上采样for (int i = 0; i < upLevel; ++i) {pyrUp(result, result);}// 拼接原图和结果显示Mat show;resize(frame, frame, Size(640, 480));resize(result, result, Size(640, 480));hconcat(frame, result, show);putText(show, "Left: Original | Right: Pyramid Result",Point(20, 30), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 255, 0), 2);imshow("Pyramid Demo", show);char c = (char)waitKey(30);if (c == 27 || c == 'q' || c == 'Q') break; // 按 ESC 或 Q 退出}cap.release();destroyAllWindows();return 0;
}