前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >图像缩放示例

图像缩放示例

作者头像
一棹烟波
发布于 2018-01-12 08:40:33
发布于 2018-01-12 08:40:33
98100
代码可运行
举报
文章被收录于专栏:一棹烟波一棹烟波
运行总次数:0
代码可运行

二维图像的缩放属于仿射变换或者透视变换的范畴,一般可以通过OpenCV的warpAffine()或者warpPerspective()函数实现。

出于兴趣,根据仿射变换公式自己简单写了一个函数实现图像的缩放,缩放中心设置为图像中心。

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  1 #include <iostream>
  2 #include <string>
  3 #include <opencv2/opencv.hpp>
  4 
  5 using namespace std;
  6 using namespace cv;
  7 
  8 void zoomInAndOut(const float scale, const Mat srcImg, Mat &dstImg)
  9 {
 10     Mat M=Mat::eye(3,3,CV_32FC1);
 11     int imgHeight=srcImg.rows;
 12     int imgWidth=srcImg.cols;
 13 
 14     uchar* pSrcData = (uchar*)srcImg.data;
 15     uchar* pDstData = (uchar*)dstImg.data;
 16 
 17     Point2f center(imgWidth / 2.0, imgHeight / 2.0);
 18     //计算仿射矩阵
 19     M.at<float>(0, 0) = scale;
 20     M.at<float>(0, 2) = (1 - scale)*center.x;
 21     M.at<float>(1, 1) = scale;
 22     M.at<float>(1, 2) = (1 - scale)*center.y;
 23 
 24     float a11 = M.at<float>(0, 0);
 25     float a12 = M.at<float>(0, 1);
 26     float a13 = M.at<float>(0, 2);
 27     float a21 = M.at<float>(1, 0);
 28     float a22 = M.at<float>(1, 1);
 29     float a23 = M.at<float>(1, 2);
 30     float a31 = M.at<float>(2, 0);
 31     float a32 = M.at<float>(2, 1);
 32     float a33 = M.at<float>(2, 2);
 33 
 34     float bx = a11*a22 - a21*a12;
 35     float by = a12*a21 - a11*a22;
 36     if ( abs(bx) > 1e-3 && abs(by) > 1e-3)
 37     {
 38         bx = 1.0 / bx;
 39         by = 1.0 / by;
 40         float cx = a13*a22 - a23*a12;
 41         float cy = a13*a21 - a23*a11;
 42 
 43         for (int j =0; j < imgHeight; j++)
 44         {
 45             for (int i = 0; i < imgWidth; i++)
 46             {
 47                 float u = (a22*i - a12*j - cx) *bx;
 48                 float v = (a21*i - a11*j - cy) *by;
 49 
 50                 int u0 = floor(u);
 51                 int v0 = floor(v);
 52                 int u1 = floor(u0 + 1);
 53                 int v1 = floor(v0 + 1);
 54                 if (u0 >= 0 && v0 >= 0 && u1 < imgWidth && v1 < imgHeight)
 55                 {
 56                     float dx = u - u0;
 57                     float dy = v - v0;
 58                     float weight1 = (1 - dx)*(1 - dy);
 59                     float weight2 = dx*(1 - dy);
 60                     float weight3 = (1 - dx)*dy;
 61                     float weight4 = dx*dy;
 62 
 63                     pDstData[j*imgWidth * 3 + i * 3 + 0] = weight1*pSrcData[v0*imgWidth * 3 + u0 * 3 + 0] +
 64                         weight2*pSrcData[v0*imgWidth * 3 + u1 * 3 + 0] +
 65                         weight3*pSrcData[v1*imgWidth * 3 + u0 * 3 + 0] +
 66                         weight4*pSrcData[v1*imgWidth * 3 + u1 * 3 + 0];
 67                     pDstData[j*imgWidth * 3 + i * 3 + 1] = weight1*pSrcData[v0*imgWidth * 3 + u0 * 3 + 1] +
 68                         weight2*pSrcData[v0*imgWidth * 3 + u1 * 3 + 1] +
 69                         weight3*pSrcData[v1*imgWidth * 3 + u0 * 3 + 1] +
 70                         weight4*pSrcData[v1*imgWidth * 3 + u1 * 3 + 1];
 71                     pDstData[j*imgWidth * 3 + i * 3 + 2] = weight1*pSrcData[v0*imgWidth * 3 + u0 * 3 + 2] +
 72                         weight2*pSrcData[v0*imgWidth * 3 + u1 * 3 + 2] +
 73                         weight3*pSrcData[v1*imgWidth * 3 + u0 * 3 + 2] +
 74                         weight4*pSrcData[v1*imgWidth * 3 + u1 * 3 + 2];
 75                 }
 76                 else
 77                 {
 78                     pDstData[j*imgWidth * 3 + i * 3 + 0] =0;
 79                     pDstData[j*imgWidth * 3 + i * 3 + 1] =0;
 80                     pDstData[j*imgWidth * 3 + i * 3 + 2] =0;
 81                 }
 82                     
 83             }
 84         }
 85     }
 86 }
 87 
 88 void main()
 89 {
 90     string imgPath="data/source_images/";
 91     Mat srcImg = imread(imgPath+"moon.jpg");
 92     pyrDown(srcImg, srcImg);
 93     pyrDown(srcImg, srcImg);
 94 
 95     Mat dstImg = srcImg.clone();
 96     dstImg.setTo(0);
 97 
 98     namedWindow("showImg");
 99     imshow("showImg", srcImg);
100     waitKey(10);
101 
102     float scale = 0;
103     while (scale <= 2)
104     {
105         scale += 0.1;
106         zoomInAndOut(scale, srcImg, dstImg);
107 
108         imshow("showImg", dstImg);
109         waitKey(10);
110     }
111 
112 }

代码中采用反向映射方法,使用用双线性插值技术得到目标图像像素值

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-08-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
OpenCV鼠标滑轮事件
鼠标的滑轮事件实现图像的缩放很方便,具体在回调函数中如下写: 其中scale可以在外部定义为全局变量,通过响应CV_EVENT_MOUSEWHEEL滑轮事件获取Scale的具体值。 获取Scale值需要关注两个问题,滑轮滑动的方向和滑动量的大小。滑动方向通过getMouseWheelDelta(flags)获取,当返回值>0时,表示向前滑动;当返回值<0时,表示向后滑动。滑动量根据滑动方向自行设置相应的滑动步长即可。 void onMouse(int event, int x, int y, int fla
一棹烟波
2018/01/12
2.5K0
图像添加径向畸变
通常摄像机的镜头都会有镜头畸变,尤其是广角镜头,在做图像处理中往往会通过摄像机标定获取镜头的畸变系数,然后进行畸变校正。而在某些特殊的情况下,你可能会需要往图像中加入畸变,下面简单实现了一个向无畸变图
一棹烟波
2018/01/12
2.4K1
图像添加径向畸变
二维图像的三维旋转
三维坐标系中,已知三个欧拉角alpha,beta,gamma,分别为绕x轴旋转alpha角度,绕y轴旋转beta角度,绕z轴旋转gamma角度。则旋转矩阵Rotation的求法如下: Mat Rot=Mat::eye(3,3, CV_32FC1); Rot.at<float>(0, 0) = cos(beta) * cos(gamma); Rot.at<float>(0, 1) = cos(beta) * sin(gamma); Rot.at<float>(0, 2) = -sin
一棹烟波
2018/01/12
2K0
二维图像的三维旋转
利用视差图合成新视点
利用视差图合成新视点,视差图一般通过图像匹配获取,以middlebury上的一张图为例,左边为原图(左图像),右边为对应视差图(灰度图)。 1. 正向映射: 简单的利用左视点原图和视差图进行视点合成,
一棹烟波
2018/01/12
2.4K0
利用视差图合成新视点
深度学习AI美颜系列——人像静态/动态贴纸特效算法实现
人像静态/动态贴纸特效几乎已经是所有图像视频处理类/直播类app的必需品了,这个功能看起来复杂,实际上很简单,本文将给大家做个详细的讲解。
AI算法与图像处理
2019/11/09
2.2K0
深度学习AI美颜系列——人像静态/动态贴纸特效算法实现
仿射变换与透视变换
仿射变换保证物体形状的“平直性”和“平行性”。透视变换不能保证物体形状的“平行性”。仿射变换是透视变换的特殊形式。 将透视变换写成3*3矩阵形式,即为M; 以下面这张图为例,实现仿射变换,包括旋转,平
一棹烟波
2018/01/12
1.3K0
仿射变换与透视变换
OpenCV3.4两种立体匹配算法效果对比
 以OpenCV自带的Aloe图像对为例: 1.BM算法(Block Matching) 参数设置如下: int numberOfDisparities = ((imgSize.width /
一棹烟波
2018/03/19
4.9K1
OpenCV3.4两种立体匹配算法效果对比
数值计算方法 Chapter5. 解线性方程组的直接法
Gauss-Jordan消元法和上述Gauss消元法本质上是一样的,不过Gauss消元法是将一般矩阵转换成三角矩阵,而Gauss-Jordan消元法是将一般矩阵转换成对角矩阵。
codename_cys
2022/05/30
1K0
OpenCV 角点检测(二) Harrise
Harrise算子是在Moravec算子的基础上改进得到的,Moravec角点检测算子见链接:http://blog.csdn.net/chaipp0607/article/details/54649235
chaibubble
2022/05/07
2390
OpenCV 角点检测(二) Harrise
【算法学习】减治 · 分治 · 变治
普卢塔克说,萨特斯为了告诉他的士兵坚忍和智慧比蛮力更重要的道理,把两匹马带到他们面前,然后让两个人拔光马的尾毛。一个人是魁梧的大力士,他用力地拔了又拔,但一点效果也没有;另一个人是一个精美的、长相矫捷的裁缝,他微笑着,每次拔掉一根毛,很快就把尾巴拔得光秃秃的。
短短的路走走停停
2019/11/04
1.6K0
图像拼接
photoshop 中有将多张重叠图像配准的功能,本文记录 OpenCV 实现方法。 任务描述 将两张具有重叠部分的图像拼接为一张连续的图像 image.png 实现思路 特征点匹配 统计两张图像 SIFT 特征点 特征点匹配 根据匹配的特征点计算透视变换矩阵 重构画布 计算重映射 x y 坐标 图像重映射 实现代码 import numpy as np import cv2 # read img1 and img2 img1 = cv2.imread('1.png') img2 = cv2.
为为为什么
2022/08/09
1.4K0
图像拼接
OpenCV角点检测源代码分析(Harris和ShiTomasi角点)
OpenCV中常用的角点检测为Harris角点和ShiTomasi角点。 以OpenCV源代码文件 .\opencv\sources\samples\cpp\tutorial_code\TrackingMotion\cornerDetector_Demo.cpp为例,主要分析其中的这两种角点检测源代码。角点检测数学原理请参考我之前转载的一篇博客 http://www.cnblogs.com/riddick/p/7645904.html,分析的很详细,不再赘述。本文主要分析其源代码: 1. Harris角点检
一棹烟波
2018/03/19
2K0
OpenCV角点检测源代码分析(Harris和ShiTomasi角点)
OpenCV 利用滚动条在不缩小的情况下显示大型图片
最近由于项目需要,要在不缩小的情况下显示一张2500*2000大小的图片,找到了一篇博客写的非常好,是邹老师写于2011年的: http://blog.csdn.net/chenyusiyuan/article/details/6565424
chaibubble
2022/05/07
7140
OpenCV 利用滚动条在不缩小的情况下显示大型图片
Matlab系列之符号运算(下)
上一篇主要对符号对象进行了一些生成和使用的基本操作,然后本篇将介绍符号矩阵、微积分、积分变换以及符号方程的求解,具体内容就往下慢慢看了。
狂人V
2020/10/10
1.3K0
Matlab系列之符号运算(下)
基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现
我在之前的文章《基于均值坐标(Mean-Value Coordinates)的图像融合算法的具体实现》中,根据《Coordinates for Instant Image Cloning》这篇论文,详细论述了图像融合中泊松融合算法的优化算法——均值坐标(Mean-Value Coordinates)融合算法的具体实现。其实在这篇论文中,还提出了两种优化实现,能够进一步提升效率,这里就论述一下其优化算法的具体实现。
charlee44
2020/03/21
1.2K0
opencv——访问图像元素(imagedata widthstep)
怎么访问图像元素 (坐标起点相对于图像原点 image origin 从 0 开始,或者是左上角 (img->origin=IPL_ORIGIN_TL) 或者是左下角 (img->origin=IPL_ORIGIN_BL)
全栈程序员站长
2022/08/15
6290
OpenGL: 如何利用 Shader 实现 RGBA 到 NV21 图像格式转换?(全网首次开源)
之前写过一篇 OpenGL 使用 shader 实现 RGBA 转 YUYV 的文章,有几位读者大人在后台建议写一篇 shader 实现 RGBA 转 NV21 的文章,因为在实践中 NV21 格式用的比较多,于是我今天把这篇文章放出来。
字节流动
2021/11/01
2.7K0
OpenGL: 如何利用 Shader 实现 RGBA 到 NV21 图像格式转换?(全网首次开源)
Canny算法解析,opencv源码实现及实例[通俗易懂]
Canny边缘检测算子是John F. Canny于 1986 年开发出来的一个多级边缘检测算法。
全栈程序员站长
2022/09/02
2.3K0
图像处理-图像分割-大津法
最大类间方差法是1979年由日本学者大津提出的,是一种自适应阈值确定的方法,又叫大津法,简称OTSU
AomanHao
2022/01/14
5520
OpenCV 删除轮廓的方法(一)
一种比较方便的删除轮廓的处理方式,是我刚刚学习到的一个方法,在这之前,如果我想删除一个不需要的轮廓,用的方法是将该轮廓填充为背景色,之前的博客提到过,在countours容器中,如果把轮廓填充为背景色,那么只是视觉上看不到该轮廓,但是实际上还存在在容器中。所以之前总是要填充之后从新copyto一下,然后重新找一遍轮廓,达到删除轮廓的效果。这种方式实在是low。 [见之前的博客http://blog.csdn.net/chaipp0607/article/details/52858661 代码如下:
chaibubble
2022/05/07
4410
OpenCV 删除轮廓的方法(一)
相关推荐
OpenCV鼠标滑轮事件
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文