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

图像缩放示例

作者头像
一棹烟波
发布2018-01-12 16:40:33
9200
发布2018-01-12 16:40:33
举报
文章被收录于专栏:一棹烟波一棹烟波一棹烟波

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

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

代码如下:

  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 删除。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档