图像缩放示例

二维图像的缩放属于仿射变换或者透视变换的范畴,一般可以通过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 }

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

时间: 2024-10-10 07:16:12

图像缩放示例的相关文章

图像缩放算法

图像缩放算法较多,下面仅以最邻近插值算法和双线性插值算法作介绍. 如下图1所示,表示原始图像和缩放以后的图像. 图1 图像缩放(原始图像à缩放图像) 图像缩放就是将原始图像中的点经过某一算法映射到目标图像的点的行为,即要找到目标图像中的点p1对应在原始图像中点p0,简单而言就是找点p0. 假设: 原始图像src的分辨率为(srcW * srcH): 目标图像dst的分辨率为(dstW * dstH). 那么: 原始图像宽与目标图像宽的比例 原始图像高与目标图像高的比例 由 所以,原始图像中的点p

【Android】21.4 图片动画缩放示例

分类:C#.Android.VS2015: 创建日期:2016-03-21 一.简介 该例子演示如何动画缩放图片,实现类似"点击看大图"的效果. 二.示例 1.运行截图    2.设计步骤 (1)添加图片 在Resources/no-dpi文件夹下添加4张图片(2个缩略图,2个大图). (2)添加ch2104MyImageButton.cs using Android.Content; using Android.Widget; using System.Drawing; using

图像缩放_OpenCv

图像缩放是一种比较简单的图像处理操作,这里给出opencv中的代码, opencv的版本C语言接口 int resize_c() { const char *pstrImageName = "lena.jpg"; const char *pstrSaveImageName = "lena缩放图.jpg"; const char *pstrWindowsSrcTitle = "原图"; const char *pstrWindowsDstTitle

opencv2 矩阵方式 resize图像缩放代码(转载)

http://blog.sina.com.cn/s/blog_74a459380101r0yx.html opencv2 矩阵方式 resize图像缩放代码(转载) (2014-05-16 09:55:35) 转载▼   分类: Opencv_Function 最近学习opencv的时候遇到的一些技术问题,拿出来分享一下.opencv1和opencv2最大的区别就是c++支持,这使得网上有些资料是opencv1的c语言写的,而有些人喜欢c++,当然接口函数也就不同了.下面是一个c++的openc

图像处理之基础---图像缩放中的一些 灰度插值算法

在图像缩放,旋转等一些图像处理中,对图像进行插值是不可缺少的一个步骤,下面对一些常用的插值算法进行介绍: 1.最近邻插值 这种插值方法是最简单的一种插值算法,图像输出的像素值的大小直接设为与其最邻近的点的大小即可,这个算法最简单,不需要多说,可以表示为 f(x,y) = g(  round(x)  ,   round(y)  ) 原图                                                                                  

视频图像处理基础知识0(双线性插值算法进行图像缩放)

双线性插值(说的很明白) 来自:http://www.cnblogs.com/linkr/p/3630902.html http://www.cnblogs.com/linkr/p/3630902.html 双线性插值,这个名字咋一听很高大上的样纸,再在维基百科上一查(见文末,我去,一堆的公式吓死人),像俺这种半文盲,看到公式脑子就懵的类型,真心给跪.虽然看着好复杂,但仔细一看道理再简单不过了,所以还是自己梳理一下好. 双线性插值,顾名思义就是两个方向的线性插值加起来(这解释过于简单粗暴,哈哈)

图像编程学习笔记7——图像缩放

假设放大因子为ratio,(为了避免新图过大或过小,我们在程序中限制0.25≤ratio≤4),缩放(zoom)的变换矩阵很简单: (2.13) 缩放变换的源代码如下,因为和转置的那段程序很类似,程序中的注释就简单一些. [cpp] view plaincopy /** * 函数名: zoom * 参  数: ratio -- 缩放率 * 功  能: 对图片进行水平和垂直镜像操作 *         只保存原图大小的图像数据,如果没有就用白色填充 */ void zoom(double rati

[转载]双线性插值算法进行图像缩放及性能效果优化

原文地址:双线性插值算法进行图像缩放及性能效果优化 一)转自http://handspeaker.iteye.com/blog/1545126 最近在编程时用到了双线性插值算法,对图像进行缩放.网上有很多这方面的资料,介绍的也算明白.但是,这些文章只介绍了算法,并没有具体说怎么实现以及怎么实现最好,举个例子,你可以按照网上文章的算法自己写一个双线性插值程序,用它对一张图片进行处理,然后再用matlab或者openCV的resize函数对同一张图片进行处理,得到的结果是不一样的,如果源图片较小,效

实现基于最近邻内插和双线性内插的图像缩放

平时我们写图像处理的代码时,如果需要缩放图片,我们都是直接调用图像库的resize函数来完成图像的缩放.作为一个机器视觉或者图像处理算法的工作者,图像缩放代码的实现应该是必须掌握的.在众多图像缩放算法中,最近邻内插算法和双线性内插算法最为基本和常见,所以这篇文章就说一说如何用c++实现这两种算法下的 http://pic.cnhubei.com/space.php?uid=1132&do=album&id=823167http://pic.cnhubei.com/space.php?uid