【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\n"));
                nRetCode = 1;
                break;
            }
            // TODO: code your application's behavior here.
            if(argc<5)
            {
                _tprintf(_T("使用方法:Imagejoint 源圖像文件 旋轉角度 縮放倍數 輸出文件\n"));
                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("“旋轉角度” 或 “縮放倍數”參數錯誤!\n"));
                nRetCode= -2;
                break;
            }
            //Load 圖像到cImage對象中
            hResult=cImage.Load(argv[1]);
            if(hResult!=ERROR_SUCCESS)
            {
                _tprintf(_T("源圖像文件名錯誤!\n"));
                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("內存申請錯誤!\n"));
                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("圖像處理錯誤!\n"));
                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("圖像結果保存錯誤!\n"));
                nRetCode= -5;
                break;
            }
            _tprintf(_T("圖像處理成功!\n"));
            nRetCode= ERROR_SUCCESS;
            break;
        }while(0);
        if(pbSrc) free(pbSrc);
        if(pbTag) free(pbTag);
    }
    else
    {
        //  可以根據需求更改錯誤提示
        _tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
        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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM