zoukankan      html  css  js  c++  java
  • 【C++】插值函数代码分析学习

    插值函数代码分析学习,用的CImage类load图像。

    // Imagejoint.cpp : 定义控制台应用程序的入口点。
    //
    #include "stdafx.h"
    #include "Imagejoint.h"
    #include "math.h"
    #include <afxwin.h> 
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    #include <atlimage.h>//CImage类
    #include <locale.h>
    
    // The one and only application object
    
    CWinApp theApp;
    
    using namespace std;
    //双三次插值系数
    double fs(double w)
    {    
            double a=-0.5;
            double fs;
            if (abs(w)<=1)
                fs=(a+2)*pow(abs(w),3)-(a+3)*pow(abs(w),2)+1;
            else if (abs(w)>1&&abs(w)<=2)
                fs=a*pow(abs(w),3)-5*a*pow(abs(w),2)+8*a*abs(w)-4*a;
            else
                fs=0;
            return fs;
    }
    
    HRESULT Imagejoint(PBYTE pbSrc,int iWidth,int iHeight,double dbRotate,double dbZoom,PBYTE pbTag);
    
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
    
        int nRetCode = 0;//表示整数类型的函数返回码。n表示整数类型,Ret是Return的缩写,表示返回值,Code表示代码。
        setlocale(LC_ALL,"chs");
        HMODULE hModule = ::GetModuleHandle(NULL);
    
        if (hModule != NULL)
        {
            // initialize MFC and print and error on failure
            CImage cImage;
            HRESULT hResult;
    
            //初始化一些变量
            int        iWidth,iHeight,iBytePerPixel,iPitch;
            int        x,y;
            PBYTE    pbSrc=NULL,pbTag=NULL;//源图、目标图
            PBYTE    pbImage=NULL;//load图像后存在这
            PDWORD    pdwImage=NULL;//用于保存图像
            double    dbRotate=0,dbZoom=0;
    
            do{
                if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
                {
                    // TODO: change error code to suit your needs
                    _tprintf(_T("Fatal Error: MFC initialization failed
    "));
                    nRetCode = 1;
                    break;
                }
                // TODO: code your application's behavior here.
                if(argc<5)
                {
                    _tprintf(_T("使用方法:Imagejoint 源图像文件 旋转角度 缩放倍数 输出文件
    "));
                    nRetCode= -1;
                    break;
                }
    
                _stscanf(argv[2],_T("%lf"),&dbRotate);
                _stscanf(argv[3],_T("%lf"),&dbZoom);
                if(!((dbRotate>=0 && dbRotate<360) && (dbZoom>=0.25 && dbZoom<=16)))
                {
                    _tprintf(_T("“旋转角度” 或 “缩放倍数”参数错误!
    "));
                    nRetCode= -2;
                    break;
                }
                //Load 图像到cImage对象中
                hResult=cImage.Load(argv[1]);
                if(hResult!=ERROR_SUCCESS)
                {
                    _tprintf(_T("源图像文件名错误!
    "));
                    nRetCode= -3;
                    break;
                }
                
                iWidth=cImage.GetWidth();
                iHeight=cImage.GetHeight();
                //分配源图内存
                pbSrc = (PBYTE)malloc(iWidth*iHeight);
                //分配目标图内存
                if(dbZoom>1) pbTag = (PBYTE)malloc(ceil(iWidth*dbZoom)*ceil(iHeight*dbZoom));
                else         pbTag = (PBYTE)malloc(iWidth*iHeight);
                if(pbSrc==NULL || pbTag==NULL )
                {
                    _tprintf(_T("内存申请错误!
    "));
                    nRetCode= -4;
                    break;
                }
                //cImage数据存到pbImage,后再转换为源灰度图pbSrc
                iPitch=cImage.GetPitch();
                iBytePerPixel=(cImage.GetBPP()+7)/8;
                if(iBytePerPixel==3)
                {
                    for(y=0;y<iHeight;y++)
                    {   //load的图像数据放到pbImage
                        pbImage=(PBYTE)(PBYTE(cImage.GetBits())+iPitch*y);//得到的是图像初始像素地址
                        for(x=0;x<iWidth;x++)
                        {
                            //pbImage转换为灰度图pbSrc
                            pbSrc[y*iWidth+x]=(pbImage[3*x]*0.15+pbImage[3*x+1]*0.55+pbImage[3*x+2]*0.3);
                        }
                    }
                }
                cImage.Destroy();
                //TO DO:执行操作
                hResult=Imagejoint(pbSrc,iWidth,iHeight,dbRotate,dbZoom,pbTag);
                if(hResult!=ERROR_SUCCESS)
                {
                    _tprintf(_T("图像处理错误!
    "));
                    nRetCode= -5;
                    break;
                }
    
    
                //处理后保存图像
                iWidth=ceil(iWidth*dbZoom);
                iHeight=ceil(iHeight*dbZoom);
                cImage.Create(iWidth,-iHeight,32);
                iPitch=cImage.GetPitch();
                for(y=0;y<iHeight;y++)
                {
                    pdwImage=(PDWORD)(PBYTE(cImage.GetBits())+iPitch*y);
                    for(x=0;x<iWidth;x++)
                    {
                        pdwImage[x]=pbTag[y*iWidth+x]*0x10101;  
                    }
                }
                //待保存图像文件名
                CString csTagName=argv[4];
                csTagName.Trim();
                csTagName.MakeUpper();
                if(csTagName.Right(4)!=_T(".BMP") ) csTagName.Append(_T(".BMP"));
                hResult=cImage.Save(csTagName);
                if(hResult!=ERROR_SUCCESS)
                {
                    _tprintf(_T("图像结果保存错误!
    "));
                    nRetCode= -5;
                    break;
                }
                _tprintf(_T("图像处理成功!
    "));
                nRetCode= ERROR_SUCCESS;
                break;
            }while(0);
            if(pbSrc) free(pbSrc);
            if(pbTag) free(pbTag);
        }
        else
        {
            //  可以根据需求更改错误提示
            _tprintf(_T("Fatal Error: GetModuleHandle failed
    "));
            nRetCode = 1;
        }
        getchar();    
        return nRetCode;
    }
    
    HRESULT Imagejoint(PBYTE pbSrc,int iWidth,int iHeight,double dbRotate,double dbZoom,PBYTE pbTag)
    {
        int size;
        if(dbZoom>1)
        {
            size=iWidth*iHeight;
        }
        else
        {
            size=ceil(iWidth*dbZoom)*ceil(iHeight*dbZoom);
        }
        //旋转中心为图像中心
        double rx0=iWidth;  
        double ry0=iHeight; 
        double srcx,srcy,u,v;
        int xOr,yOr;
        //int zoom=ceil(dbZoom);
        dbRotate=dbRotate*3.1415926/180.0;
        for (int y=0;y<dbZoom*iHeight;y++)
        {
            for (int x=0;x<dbZoom*iWidth;x++)
            {
                srcx=(double)((x-rx0)*cos(dbRotate) - (y-ry0)*sin(dbRotate) + rx0) ;
                srcy=(double)((x-rx0)*sin(dbRotate) + (y-ry0)*cos(dbRotate) + ry0) ;
                srcx=srcx*1/dbZoom;
                srcy=srcy*1/dbZoom;
                xOr = floor(srcx);
                yOr = floor(srcy);
                u=srcx-xOr;
                v=srcy-yOr;
    
                if( !(srcx>=0 && srcx<=iWidth && srcy>=0 && srcy<=iHeight))
                    {
                        pbTag[y*2*iWidth+x]=0;//255
                    }
                else
                {   
                    double middle=
                        pbSrc[(yOr-1)*iWidth+(xOr-1)]*fs(1+u)*fs(1+v)+
                        pbSrc[(yOr)*iWidth+(xOr-1)]*fs(1+u)*fs(v)+
                        pbSrc[(yOr+1)*iWidth+(xOr-1)]*fs(1+u)*fs(1-v)+
                        pbSrc[(yOr+2)*iWidth+(xOr-1)]*fs(1+u)*fs(2-v)+
                        
                        pbSrc[(yOr-1)*iWidth+(xOr)]*fs(u)*fs(1+v)+
                        pbSrc[(yOr)*iWidth+(xOr)]*fs(u)*fs(v)+
                        pbSrc[(yOr+1)*iWidth+(xOr)]*fs(u)*fs(1-v)+
                        pbSrc[(yOr+2)*iWidth+(xOr)]*fs(u)*fs(2-v)+
    
                        pbSrc[(yOr-1)*iWidth+(xOr+1)]*fs(1-u)*fs(1+v)+
                        pbSrc[(yOr)*iWidth+(xOr+1)]*fs(1-u)*fs(v)+
                        pbSrc[(yOr+1)*iWidth+(xOr+1)]*fs(1-u)*fs(1-v)+
                        pbSrc[(yOr+2)*iWidth+(xOr+1)]*fs(1-u)*fs(2-v)+
    
                        pbSrc[(yOr-1)*iWidth+(xOr+2)]*fs(2-u)*fs(1+v)+
                        pbSrc[(yOr)*iWidth+(xOr+2)]*fs(2-u)*fs(v)+
                        pbSrc[(yOr+1)*iWidth+(xOr+2)]*fs(2-u)*fs(1-v)+
                        pbSrc[(yOr+2)*iWidth+(xOr+2)]*fs(2-u)*fs(2-v);
    
                    if(middle<=255&&middle>=0)
                        pbTag[y*2*iWidth+x]=middle;
                    else if(middle>255)
                        pbTag[y*2*iWidth+x]=255;
                    else 
                        pbTag[y*2*iWidth+x]=0;
                }
            }
        }
        //memcpy(pbTag,pbSrc,size);
        return ERROR_SUCCESS;
    }
  • 相关阅读:
    PAT (Advanced Level) Practice 1071 Speech Patterns (25分)
    PAT (Advanced Level) Practice 1070 Mooncake (25分)
    PAT (Advanced Level) Practice 1069 The Black Hole of Numbers (20分)
    PAT (Advanced Level) Practice 1074 Reversing Linked List (25分)
    PAT (Advanced Level) Practice 1073 Scientific Notation (20分)
    第一次冲刺个人总结01
    构建之法阅读笔记01
    人月神话阅读笔记01
    四则运算2
    学习进度条(软件工程概论1-8周)
  • 原文地址:https://www.cnblogs.com/wxl845235800/p/11142416.html
Copyright © 2011-2022 走看看