zoukankan      html  css  js  c++  java
  • 图像缩放示例

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

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

    --------------------------------- 业精于勤而荒于嬉 行成于思而毁于随 ---------------------------------
  • 相关阅读:
    如释重负(纪——写完作业论文)
    安装sql2005中文版时提示系统配置检查器失败,消息为“性能监视器计数器检查失败”
    Get ConnectString Form Web.config
    如何在ASP.NET中实现防盗链[转]
    Authentication and Authorization
    上传大步的自唱Music,绝对好听!
    "某个程序安装已在安装计算机上创建挂起的文件操作" 解决办法
    WebM给我们带来什么?H.264又给我们带来什么?Google不支持H.264对未来会产生怎样的影响? 人工智能
    机器学习初探 人工智能
    函数式编程学习之路(九) 人工智能
  • 原文地址:https://www.cnblogs.com/riddick/p/7420526.html
Copyright © 2011-2022 走看看