OpenCV4入门教程021:像素插值实现缩放

索引地址:系列索引

基本的像素操作介绍完毕之后,我们来看一下图像插值,即在图像某一点的周围通过算法获取一个新的像素点数据插入,实现扩展图片的尺寸:

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// 功能:代码 4-1 最近邻插值实现
// 作者:朱伟 zhu1988wei@163.com
// 来源:《OpenCV图像处理编程实例》
// 博客:http://blog.csdn.net/zhuwei1988
// 更新:2016-8-1
// 说明:版权所有,引用或摘录请联系作者,并按照上面格式注明出处,谢谢。//
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;

// 实现最近邻插值图像缩放
cv::Mat nNeighbourInterpolation(cv::Mat srcImage) {
// 判断输入有效性
CV_Assert(srcImage.data != NULL);
int rows = srcImage.rows;
int cols = srcImage.cols;
// 构建目标图像
cv::Mat dstImage = cv::Mat(cv::Size(150, 150), srcImage.type(), cv::Scalar::all(0));
int dstRows = dstImage.rows;
int dstCols = dstImage.cols;
// 坐标转换 求取缩放倍数
float cx = (float)cols / dstCols;
float ry = (float)rows / dstRows;
std::cout << "cx: " << cx << "ry:" << ry << std::endl;
// 遍历图像完成缩放操作
for (int i = 0; i < dstCols; i++) {
// 取整获取目标图像在源图像对应坐标
int ix = floor(i * cx);
for (int j = 0; j < dstRows; j++) {
int jy = floor(j * ry);
// 边界处理 防止指针越界
if (ix > cols - 1)
ix = cols - 1;
if (jy > rows - 1)
jy = rows - 1;
// 映射矩阵
dstImage.at<cv::Vec3b>(j, i) = srcImage.at<cv::Vec3b>(jy, ix);
}
}
return dstImage;
}

int main() {
// 图像源获取及验证
cv::Mat srcImage = cv::imread("lena.jpg");
if (!srcImage.data)
return -1;
// 最近邻插值缩放操作
cv::Mat dstImage = nNeighbourInterpolation(srcImage);
cv::imshow("srcImage", srcImage);
cv::imshow("dstImage", dstImage);
cv::waitKey(0);
return 0;
}

floor,指地板。floor函数,其功能是“向下取整”,或者说“向下舍入”、“向零取舍”,即取不大于x的最大整数,与“四舍五入”不同,下取整是直接取按照数轴上最接近要求值的左边值,即不大于要求值的最大的那个整数值。

测试结果:

pix


OpenCV4入门教程021:像素插值实现缩放
https://blog.jackeylea.com/opencv/scale-image-by-pixel-interpolation/
作者
JackeyLea
发布于
2020年9月24日
许可协议