• Opencv下双线性插值法进行图像放缩


    关于图像放缩的算法有很多,本文主要介绍双线性插值法进行图像放缩,本文参考了: http://www.cnblogs.com/funny-world/p/3162003.html

    我们设源图像src的大小为m*N,目标图像的大小为a*b。无论是放大还是缩小,我们所遵循的原则就是对于目标图像的像素点 f(i,j),我们在源图像当中找到其对应点 f(x,y)。

    其算法为:i/x=m/a  j/y=n/b 因此我们可以得到:x=i*(m/a)     y=j*(n/b)

    但是为了使放缩的效果更好,可以使两个图片的几何中心重合,所以我们可以:x=(i+0.5)*(m/a)-0.5   y=(j+0.5)*(n/b)-0.5

    通过这样算法,我们便可以在源图像当中找到目标图像的对应点了,但是这样计算 x,y 很可能是float型,因此我们需要继续对 x,y进行处理

    我们可以找到 于P(所求的点)最为临近的四个点 Q11 ,Q12 ,Q21,Q22 ,通过下面的算法进行处理:


     f(R1)=(X2-X)/(X2-X1)*f(Q11)+(X-X1)/(X2-X1)*f(Q21)


     f(R2)=(X2-X)/(X2-X1)*f(Q12)+(X-X1)/(X2-X1)*f(Q22)


     f(i,j)=(Y2-Y)/(Y2-Y1)f(R1)+(Y-Y1)/(Y2-Y1)*f(R2)

     通过这样的处理,我们便可以计算出目标图像法 f(i,j)的像素值了,从而可以求出目标图像.

    下面是Opencv的代码:

    #include<opencv2opencv.hpp>
    #include<opencv2corecore.hpp>
    #include<opencv2highguihighgui.hpp>
    
    using namespace std;
    using namespace cv;
    
    int main(){
        Mat src;
        src=imread("G:/save1.jpg",1);    //输入图片;
        if(src.empty()){
            return -1;
        }
        Mat dist=Mat((2*src.rows),(2*src.cols),CV_32FC3);        //目标图片,将原图放大两倍;
    
        //遍历目标图片的点,将目标图片的归溯到原图的点当中,若结果为浮点型,则按照算法计算;
        //归溯算法,原图大小为a*b,目标图大小m*n,i/x=a/m,j/y=b/n;
    
        float x,y;
        int Q11[2],Q21[2],Q12[2],Q22[2];          //Q11 Q12 Q21 Q22分别对应着与P点最为临近的四个点,P点为目标图点还原到原图的点的对应位置;
        float R1[3],R2[3];
        for(int i=0;i<dist.rows-1;i++){           //这里减2是因为对于(src.rows-1,src.cols-1)的位置对应的是(dist.rows-2,dits.cols-2),再大一点就会超过内存。
            for(int j=0;j<dist.cols-1;j++){
                x=(i+0.5)*0.5-0.5;               //通过加减0.5,将像素点移到中心点的位置,使放缩效果更好。
                y=(j+0.5)*0.5-0.5;
    
                Q11[0]=(int)x;
                Q12[0]=(int)x;
                Q21[0]=(int)x+1;
                Q22[0]=(int)x+1;
    
                Q11[1]=(int) y;
                Q21[1]=(int) y;
                Q12[1]=(int) y+1;
                Q22[1]=(int) y+1;
    
                // 插值法算法如下:
                // X1=(int)x; X2=(int)x+1; Y1=(int)y; Y2=(int)y+1;
                // f(R1)=(X2-X)/(X2-X1)*f(Q11)+(X-X1)/(X2-X1)*f(Q21);
                // f(R2)=(X2-X)/(X2-X1)*f(Q12)+(X-X1)/(X2-X1)*f(Q22);
                // f(i,j)=(Y2-Y)/(Y2-Y1)f(R1)+(Y-Y1)/(Y2-Y1)*f(R2);
                for(int m=0;m<3;m++){
                    R1[m]=((Q21[0]-x)*src.at<Vec3b>(Q11[0],Q11[1])[m])+((x-Q11[0])*src.at<Vec3b>(Q21[0],Q21[1])[m]);
                    R2[m]=((Q21[0]-x)*src.at<Vec3b>(Q12[0],Q12[1])[m])+((x-Q11[0])*src.at<Vec3b>(Q22[0],Q22[1])[m]);
                    dist.at<Vec3f>(i,j)[m]=(Q12[1]-y)*R1[m]+(y-Q11[1])*R2[m];
                }
            }
        }
        imwrite("G:/save.jpg",dist);          //输出图片;
    }
    View Code
  • 相关阅读:
    深入理解TCP协议及其源代码
    Socket与系统调用深度分析
    构建调试Linux内核网络代码的环境MenuOS系统
    基于java的socket简单聊天编程
    ping命令研究报告
    什么是JMM?
    ssm框架整合,个人学习记录
    Intellij idea兼容 Eclipse 快捷键 (仅个人学习回顾,防止遗忘)
    java基础随记 持续完善中
    win10 安装Ubuntu子系统 整合排坑
  • 原文地址:https://www.cnblogs.com/code-wangjun/p/5956233.html
Copyright © 2020-2023  润新知