• 拼接备忘(随笔记)


     for (int y=0;y<1024;y++)
        {
            for (int x=0;x<1280;x++)
            {
    
                srcx=(double)(newWidth/2-middleInFinalx+x)/dbZoom;
                srcy=(double)(newHeight/2-middleInFinaly+y)/dbZoom ;

    逐渐放大的中心。(615,730)。

    if( !(srcx>=xl && srcx<=xr && srcy>=yu && srcy<=yd))

    外圈设为:但是这样外圈的放大中心在图中间。需要将两个放大中心合在一起,而内圈和外圈图中心位置有偏差。

    关键在于把偏差修正!

    srcx=(double)(1.5*newWidth-middleInFinalx+x-25*dbZoom)/(3*dbZoom);//补偏差
    srcy=(double)(1.5*newHeight-middleInFinaly+y+218*dbZoom)/(3*dbZoom);//此处映射公式为外圈比内圈放大倍数=3。原来是2。

    未完待续。

    // Imagejoint.cpp : 定义控制台应用程序的入口点。
    //
    #include "stdafx.h"
    #include "Imagejoint.h"
    #include <afxwin.h> 
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    #include <atlimage.h>//CImage类
    #include <locale.h>
    #include "math.h"
    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 pbSrc1,PBYTE pbSrc2,int iWidth,int iHeight,double dbZoom,PBYTE pbFinal,PBYTE pbMiddle1,PBYTE pbMiddle2);
    
    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)
        {
    
            HRESULT hResult1,hResult2;
            //初始化一些变量
            int        iWidth,iHeight,iBytePerPixel,iPitch;
            int        x,y;
            PBYTE    pbSrc1=NULL,pbSrc2=NULL,pbFinal=NULL;//源图、目标图
            PBYTE    pbMiddle1=NULL,pbMiddle2=NULL;
            PBYTE    pbImage=NULL;//load图像后存在这
            PDWORD    pdwImage=NULL;//用于保存图像
            int frame_num=1;
            double    dbZoom=1.25;
    
            //起始放大倍数,需要注意!过小外图都填不下。
            for(dbZoom=0.7;dbZoom<=1.50;dbZoom+=0.15)
            {
                
                CImage cImage_far;
                CImage cImage_near;
    
                CString farsrc= "1.bmp";
                CString nearsrc = "1650.bmp";
    
                LPCTSTR filename1 = (LPCTSTR)farsrc;
                LPCTSTR filename2 = (LPCTSTR)nearsrc;
      
                if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
                {
                    // TODO: change error code to suit your needs
                    _tprintf(_T("Fatal Error: MFC initialization failed
    "));
                    nRetCode = 1;
                    
                }
                //Load 图像到cImage对象中
                hResult1=cImage_far.Load(filename1);
                hResult2=cImage_near.Load(filename2);
                if(hResult1!=ERROR_SUCCESS||hResult2!=ERROR_SUCCESS)
                {
                    _tprintf(_T("源图像文件名错误!
    "));
                    nRetCode= -3;
                  
                }
                
                iWidth=cImage_far.GetWidth();
                iHeight=cImage_far.GetHeight();
                //分配源图内存
                pbSrc1 = (PBYTE)malloc(iWidth*iHeight);
                pbSrc2 = (PBYTE)malloc(iWidth*iHeight);
                //分配目标图内存
                pbFinal = (PBYTE)malloc(1280*1024);
                pbMiddle1=(PBYTE)malloc(1280*1024);
                pbMiddle2=(PBYTE)malloc(1280*1024);
    
                if(pbSrc1==NULL||pbSrc2==NULL || pbFinal==NULL )
                {
                    _tprintf(_T("内存申请错误!
    "));
                    nRetCode= -4;
                   
                }
                //cImage数据存到pbImage,后再转换为源灰度图pbSrc
                iPitch=cImage_far.GetPitch();
                iBytePerPixel=(cImage_far.GetBPP()+7)/8;
                if(iBytePerPixel==3)
                {
                    for(y=0;y<iHeight;y++)
                    {   //load的图像数据放到pbImage
                        pbImage=(PBYTE)(PBYTE(cImage_far.GetBits())+iPitch*y);//得到的是图像初始像素地址
                        for(x=0;x<iWidth;x++)
                        {
                            //pbImage转换为灰度图pbSrc
                            pbSrc1[y*iWidth+x]=(pbImage[3*x]*0.15+pbImage[3*x+1]*0.55+pbImage[3*x+2]*0.3);
                        }
                    }
                }
                cImage_far.Destroy();
    
                iPitch=cImage_near.GetPitch();
                iBytePerPixel=(cImage_near.GetBPP()+7)/8;
                if(iBytePerPixel==3)
                {
                    for(y=0;y<iHeight;y++)
                    {   //load的图像数据放到pbImage
                        pbImage=(PBYTE)(PBYTE(cImage_near.GetBits())+iPitch*y);//得到的是图像初始像素地址
                        for(x=0;x<iWidth;x++)
                        {
                            //pbImage转换为灰度图pbSrc
                            pbSrc2[y*iWidth+x]=(pbImage[3*x]*0.15+pbImage[3*x+1]*0.55+pbImage[3*x+2]*0.3);
                        }
                    }
                }
                cImage_near.Destroy();
    
                //执行操作
                hResult1=Imagejoint(pbSrc1,pbSrc2,iWidth,iHeight,dbZoom,pbFinal,pbMiddle1,pbMiddle2);
                if(hResult1!=ERROR_SUCCESS)
                {
                    _tprintf(_T("图像处理错误!
    "));
                    nRetCode= -5;
                   
                }
                //处理后保存图像
                iWidth=1280;
                iHeight=1024;
                cImage_far.Create(iWidth,-iHeight,32);
                iPitch=cImage_far.GetPitch();
                for(y=0;y<iHeight;y++)
                {
                    pdwImage=(PDWORD)(PBYTE(cImage_far.GetBits())+iPitch*y);
                    for(x=0;x<iWidth;x++)
                    {
                        pdwImage[x]=pbFinal[y*iWidth+x]*0x10101;  
                    }
                }
                //可预存待保存图像文件名
                CString name1="D:/文件及下载相关/桌面/模拟变焦拼接/Matlab_code/result/";
                CString name2;
                //这里要随着帧数改动
                name2.Format(_T("%d"),frame_num);
                CString csTagName;
                csTagName=name1+name2;
                
                csTagName.Trim();
                csTagName.MakeUpper();
                if(csTagName.Right(4)!=_T(".bmp") ) csTagName.Append(_T(".bmp"));
                hResult1=cImage_far.Save(csTagName);
                if(hResult1!=ERROR_SUCCESS)
                {
                    _tprintf(_T("图像结果保存错误!
    "));
                    nRetCode= -5;
                   
                }
                _tprintf(_T("图像处理成功!
    "));
                nRetCode= ERROR_SUCCESS;
    
                if(pbSrc1) free(pbSrc1);
                if(pbSrc2) free(pbSrc2);
                if(pbFinal) free(pbFinal);
                
                //dbZoom=dbZoom+0.0070;
                //dbZoom=dbZoom+0.25;
                frame_num++;
            }//对应+=0.25倍数的for循环。
    
        }
        else
        {
            _tprintf(_T("Fatal Error: GetModuleHandle failed
    "));
            nRetCode = 1;
        }
        getchar();    
        return nRetCode;
    }
    
    HRESULT Imagejoint(PBYTE pbSrc1,PBYTE pbSrc2,int iWidth,int iHeight,double dbZoom,PBYTE pbFinal,PBYTE pbMiddle1,PBYTE pbMiddle2)
    {
        double phase[33]={0};//16相位,包含端点存在33个距离
        for (int i=0;i<33;i++)
        {
            double i2=1.0*i;
            phase[i]=fs(i2/16);
        }
        double count_a=0;
        double count_b=0;
        double count=0;
        double w=1;
    
        //Matlab中测试获取定值(34:541 -Y,41:728 -X),需要微调。
        //int xl=41,xr=720,yu=34,yd=541;//原768*576大小图像中,存在内容的部分。
        int xl=1,xr=752,yu=1,yd=574;
        int transition=25;//渐变像素过渡设置
    
    
        //旋转中心为图像中心
        double rx0=iWidth;  
        double ry0=iHeight; 
        double srcx,srcy,u,v;
        int xOr,yOr;
        int newWidth=ceil(dbZoom*iWidth);
        int newHeight=ceil(dbZoom*iHeight);
        int middleInFinalx=615;//内圈图像待放置的,处于目标图中的图像中心。(也是图像放大中心)
        int middleInFinaly=730;
    
        for (int y=0;y<1024;y++)
        {
            for (int x=0;x<1280;x++)
            {
    
                srcx=(double)(newWidth/2-middleInFinalx+x)/dbZoom;
                srcy=(double)(newHeight/2-middleInFinaly+y)/dbZoom ;
                xOr = floor(srcx);
                yOr = floor(srcy);
                u=srcx-xOr;
                v=srcy-yOr;
    
                int phasex=floor(16*u+0.5);//16相位
                int phasey=floor(16*v+0.5);
                double A1,B1,C1,D1,A2,B2,C2,D2;
                A1=phase[16+phasex];
                B1=phase[phasex];
                C1=phase[16-phasex];
                D1=phase[32-phasex];
    
                A2=phase[16+phasey];
                B2=phase[phasey];
                C2=phase[16-phasey];
                D2=phase[32-phasey];
    
                if( !(srcx>=xl && srcx<=xr && srcy>=yu && srcy<=yd))//越界部分需拼接为外圈大视场图像,远景
                    {
                        /*
                        srcx=(double)(1.5*newWidth-middleInFinalx+x)/(3*dbZoom);//补偏差
                        srcy=(double)(1.5*newHeight-middleInFinaly+y)/(3*dbZoom);//此处映射公式为外圈比内圈放大倍数=3。原来是2。
                        xOr = floor(srcx);
                        yOr = floor(srcy);
                        u=srcx-xOr; 
                        v=srcy-yOr;
    
                        phasex=floor(16*u+0.5);//16相位
                         phasey=floor(16*v+0.5);
    
                        A1=phase[16+phasex];
                        B1=phase[phasex];
                        C1=phase[16-phasex];
                        D1=phase[32-phasex];
    
                        A2=phase[16+phasey];
                        B2=phase[phasey];
                        C2=phase[16-phasey];
                        D2=phase[32-phasey];
    
                        double middle=
                        pbSrc1[(yOr-1)*iWidth+(xOr-1)]*A1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr-1)]*A1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr-1)]*A1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr-1)]*A1*D2+
                        
                        pbSrc1[(yOr-1)*iWidth+(xOr)]*B1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr)]*B1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr)]*B1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr)]*B1*D2+
    
                        pbSrc1[(yOr-1)*iWidth+(xOr+1)]*C1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr+1)]*C1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr+1)]*C1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr+1)]*C1*D2+
    
                        pbSrc1[(yOr-1)*iWidth+(xOr+2)]*D1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr+2)]*D1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr+2)]*D1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr+2)]*D1*D2;
    
                    if(middle<=255&&middle>=0)
                        pbFinal[y*1280+x]=middle;
                    else if(middle>255)
                        pbFinal[y*1280+x]=255;
                    else 
                        pbFinal[y*1280+x]=0;
                        */
                        
                        srcx=(double)(1.5*newWidth-middleInFinalx+x-35.7*dbZoom)/(3*dbZoom);//补偏差
                        srcy=(double)(1.5*newHeight-middleInFinaly+y+311.4*dbZoom)/(3*dbZoom);//此处映射公式为外圈比内圈放大倍数=3。原来是2。
                        xOr = floor(srcx);
                        yOr = floor(srcy);
                        if(xOr>iWidth)
                            xOr=iWidth;
                        if(yOr>iHeight)
                            yOr=iHeight;
                        if(xOr<0)
                            xOr=0;
                        if(yOr<0)
                            yOr=0;
                        pbFinal[y*1280+x]=pbSrc1[(yOr)*iWidth+(xOr)];
                        
                    //pbFinal[y*1280+x]=255;
                
                }
    
                /*
                else if( !(srcx>=xl+transition && srcx<=xr-transition && srcy>=yu+transition && srcy<=yd-transition))
                        {
                            double weight=1;//代表内圈所占的权重
    
                            if(srcx>=xl && srcx<=xl+transition)
                                weight=(srcx-xl)*1.0/transition;
                            else if(srcx>=xr-transition && srcx<=xr)
                                weight=(xr-srcx)*1.0/transition;
    
                            if(srcy>=yu && srcy<=yu+transition)
                                weight=(srcy-yu)*1.0/transition;
                            else if(srcy>=yd-transition && srcy<=yd)
                                weight=(yd-srcy)*1.0/transition;
    
                            if((srcx>=xl && srcx<=xl+transition)&&(srcy>=yu && srcy<=yu+transition))
                                weight=min((srcx-xl),(srcy-yu))*1.0/transition;
                            else if((srcx>=xl && srcx<=xl+transition)&&(srcy>=yd-transition && srcy<=yd))
                                weight=min((srcx-xl),(yd-srcy))*1.0/transition;
                            else if((srcx>=xr-transition && srcx<=xr)&&(srcy>=yu && srcy<=yu+transition))
                                weight=min((xr-srcx),(srcy-yu))*1.0/transition;
                            else if((srcx>=xr-transition && srcx<=xr)&&(srcy>=yd-transition && srcy<=yd))
                                weight=min((xr-srcx),(yd-srcy))*1.0/transition;
                            //pbFinal[y*1280+x]=255;
                        srcx=(double)(newWidth-middleInFinalx+x)/(2*dbZoom)+6;//补偏差
                        srcy=(double)(newHeight-middleInFinaly+y)/(2*dbZoom)-3;
                        xOr = floor(srcx);
                        yOr = floor(srcy);
                        u=srcx-xOr; 
                        v=srcy-yOr;
                        phasex=floor(16*u+0.5);//16相位
                        phasey=floor(16*v+0.5);
                        A1=phase[16+phasex];
                        B1=phase[phasex];
                        C1=phase[16-phasex];
                        D1=phase[32-phasex];
                        A2=phase[16+phasey];
                        B2=phase[phasey];
                        C2=phase[16-phasey];
                        D2=phase[32-phasey];
                        double middle1=
                        pbSrc1[(yOr-1)*iWidth+(xOr-1)]*A1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr-1)]*A1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr-1)]*A1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr-1)]*A1*D2+                    
                        pbSrc1[(yOr-1)*iWidth+(xOr)]*B1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr)]*B1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr)]*B1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr)]*B1*D2+
                        pbSrc1[(yOr-1)*iWidth+(xOr+1)]*C1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr+1)]*C1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr+1)]*C1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr+1)]*C1*D2+
                        pbSrc1[(yOr-1)*iWidth+(xOr+2)]*D1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr+2)]*D1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr+2)]*D1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr+2)]*D1*D2;
                        //pbMiddle1[y*1280+x]=middle1;
                    if(middle1<=255&&middle1>=0)
                        pbMiddle1[y*1280+x]=middle1;
                    else if(middle1>255)
                        pbMiddle1[y*1280+x]=255;
                    else 
                        pbMiddle1[y*1280+x]=0;
                //外图的渐变区域的值,先存到pbMiddle1中。
                //------------------------------------------------------------
                        srcx=(double)(newWidth/2-middleInFinalx+x)/dbZoom;
                        srcy=(double)(newHeight/2-middleInFinaly+y)/dbZoom ;
                        xOr = floor(srcx);
                        yOr = floor(srcy);
                        u=srcx-xOr;
                        v=srcy-yOr;
                        phasex=floor(16*u+0.5);//16相位
                        phasey=floor(16*v+0.5);
                        A1=phase[16+phasex];
                        B1=phase[phasex];
                        C1=phase[16-phasex];
                        D1=phase[32-phasex];
                        A2=phase[16+phasey];
                        B2=phase[phasey];
                        C2=phase[16-phasey];
                        D2=phase[32-phasey];            
                        double middle2=
                        pbSrc2[(yOr-1)*iWidth+(xOr-1)]*A1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr-1)]*A1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr-1)]*A1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr-1)]*A1*D2+                    
                        pbSrc2[(yOr-1)*iWidth+(xOr)]*B1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr)]*B1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr)]*B1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr)]*B1*D2+
                        pbSrc2[(yOr-1)*iWidth+(xOr+1)]*C1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr+1)]*C1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr+1)]*C1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr+1)]*C1*D2+
                        pbSrc2[(yOr-1)*iWidth+(xOr+2)]*D1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr+2)]*D1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr+2)]*D1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr+2)]*D1*D2;
                        //pbMiddle2[y*1280+x]=middle2;
                    if(middle2<=255&&middle2>=0)
                        pbMiddle2[y*1280+x]=middle2;
                    else if(middle2>255)
                        pbMiddle2[y*1280+x]=255;
                    else 
                        pbMiddle2[y*1280+x]=0;
                    //内图的渐变区域的值,再存到pbMiddle2中。
                        //count++;
                        //count_a+=middle1;
                        //count_b+=middle2;
                        //w=count_a/count-count_b/count;
                        //w=count_a/count_b;                
    //边界融合
                    double middle3=(1-weight)* pbMiddle1[y*1280+x]+weight*pbMiddle2[y*1280+x];
                    pbFinal[y*1280+x]=middle3;
                    //if(middle3<=255&&middle3>=0)
        //                pbFinal[y*1280+x]=middle3;
        //            else if(middle3>255)
        //                pbFinal[y*1280+x]=255;
        //            else 
        //                pbFinal[y*1280+x]=0;
                                            
                        }    
                        */
    //内圈,核心区域pbSrc2-B
                else
                {   
                    /*
                    srcx=(double)(newWidth/2-640+x)/dbZoom;
                    srcy=(double)(newHeight/2-512+y)/dbZoom ;
                    
                    double middle3=
                        pbSrc2[(yOr-1)*iWidth+(xOr-1)]*A1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr-1)]*A1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr-1)]*A1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr-1)]*A1*D2+
                        
                        pbSrc2[(yOr-1)*iWidth+(xOr)]*B1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr)]*B1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr)]*B1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr)]*B1*D2+
    
                        pbSrc2[(yOr-1)*iWidth+(xOr+1)]*C1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr+1)]*C1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr+1)]*C1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr+1)]*C1*D2+
    
                        pbSrc2[(yOr-1)*iWidth+(xOr+2)]*D1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr+2)]*D1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr+2)]*D1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr+2)]*D1*D2;
                    //w=count_a/count-count_b/count;
                    //w=count_a/count_b;//0.762953
                    //middle3=middle3*w;                
                    if(middle3<=255&&middle3>=0)
                        pbFinal[y*1280+x]=middle3;
                    else if(middle3>255)
                        pbFinal[y*1280+x]=255;
                    else 
                        pbFinal[y*1280+x]=0;
                        */
                        pbFinal[y*1280+x]=pbSrc2[(yOr)*iWidth+(xOr)];
    
                     }        
            }
        }
    
    /*
    //亮度平衡部分
    double sum1=0,sum2=0;
    double w2=1;
    double xl2=0,xr2=0,yu2=0,yd2=0;
    //xl2=ceil(xl*dbZoom-newWidth/2+640);
    //xr2=ceil(xr*dbZoom-newWidth/2+640);
    //yu2=ceil(yu*dbZoom-newHeight/2+512);
    //yd2=ceil(yd*dbZoom-newHeight/2+512);
    xl2=ceil((xl+transition)*dbZoom-newWidth/2+640);
    xr2=ceil((xr-transition)*dbZoom-newWidth/2+640);//右侧细线
    yu2=ceil((yu+transition)*dbZoom-newHeight/2+512);
    yd2=ceil((yd-transition)*dbZoom-newHeight/2+512);
    
    for (int y=0;y<1024;y++)
        {
            for (int x=0;x<1280;x++)
            {    if(pbMiddle1[y*1280+x]!=205)
                sum1+=pbMiddle1[y*1280+x];
                if(pbMiddle2[y*1280+x]!=205)
                sum2+=pbMiddle2[y*1280+x];
            }
        }
        w2=sum1/sum2;//0.82    ,原来的直接取一个系数。
    
    
    //统计直方图
    double middle1_state[256]={0};
    double middle2_state[256]={0};
    int gray1=0;
    int gray2=0;
    int num1_L=0;
    int num1_H=0;
    int num2_L=0;
    int num2_H=0;
    int gray1L=0;
    int gray1H=0;
    int gray2L=0;
    int gray2H=0;
    
        for (int y=0;y<1024;y++)
        {
            for (int x=0;x<1280;x++)
            {    
                if(pbMiddle1[y*1280+x]!=205)
                {
                    gray1=pbMiddle1[y*1280+x];
                    middle1_state[gray1]++;//按灰度级统计外圈的
                }
                if(pbMiddle2[y*1280+x]!=205)
                {
                    gray2=pbMiddle2[y*1280+x];
                    middle2_state[gray2]++;//按灰度级统计内圈的
                }
            }
        }
    //统计好后分别找前1/3和后1/3
        //先统计总个数
        for(int gray=0;gray<256;gray++)
        {
            sum1+=middle1_state[gray];//个数之和,共有多少个有效元素。
            sum2+=middle1_state[gray];
        }
        //外圈统计中找1/3
        for(int gray=0;gray<256;gray++)
        {
            num1_L+=middle1_state[gray];
            if(num1_L<=sum1/3.0)
            {gray1L=gray;}//前1/3数量的灰度级是到gray1L。
            else
                ;
        }
        for(int gray=255;gray>=0;gray--)
        {
            num1_H+=middle1_state[gray];
            if(num1_H<=sum1/3.0)
            {gray1H=gray;}//后1/3数量的灰度级是到gray1H。
            else
                ;
        }
        //内圈统计找1/3
        for(int gray=0;gray<256;gray++)
        {
            num2_L+=middle2_state[gray];
            if(num2_L<=sum2/3.0)
            {gray2L=gray;}//前1/3数量的灰度级是到gray2L。
            else
                ;
        }
        for(int gray=255;gray>=0;gray--)
        {
            num2_H+=middle2_state[gray];
            if(num2_H<=sum2/3.0)
            {gray2H=gray;}//后1/3数量的灰度级是到gray2H。
            else
                ;
        }
    //统计好后,计算A1,A2,B1,B2。双点进行亮度平衡。
        double sum1L=0,sum1H=0,sum2L=0,sum2H=0;//用于统计个数
        double pix_sum1L=0,pix_sum1H=0,pix_sum2L=0,pix_sum2H=0;//用于累计像素值求和
        double A1=0,A2=0,B1=0,B2=0;
        double w3=1,b3=1;//要用到的,增益和偏置参数
        //外圈的1/3计算A1,A2
        for(int gray=0;gray<=gray1L;gray++)
        {
            sum1L+=middle1_state[gray];
            pix_sum1L+=middle1_state[gray]*gray;
        }
        for(int gray=255;gray>=gray1H;gray--)
        {
            sum1H+=middle1_state[gray];
            pix_sum1H+=middle1_state[gray]*gray;
        }
        //内圈的1/3计算B1,B2
        for(int gray=0;gray<=gray2L;gray++)
        {
            sum2L+=middle2_state[gray];
            pix_sum2L+=middle2_state[gray]*gray;
        }
        for(int gray=255;gray>=gray2H;gray--)
        {
            sum2H+=middle2_state[gray];
            pix_sum2H+=middle2_state[gray]*gray;
        }
        A1=pix_sum1L/sum1L;
        A2=pix_sum1H/sum1H;
    
        B1=pix_sum2L/sum2L;
        B2=pix_sum2H/sum2H;
    
        w3=(A2-A1)/(B2-B1);
        b3=A1-w3*B1;
        double middle=0;
        
    
    //===================================================================================
    
    //亮度平衡
        for (int y=0;y<1024;y++)
        {
            for (int x=0;x<1280;x++)
            {
                    if(x>=xl2 && x<=xr2 && y>=yu2 && y<=yd2)
                    {
                        double middle=0;
                        middle=w3*pbFinal[y*1280+x]+b3;
                        //middle=w2*pbFinal[y*1280+x];
                    if(middle<=255&&middle>=0)
                       pbFinal[y*1280+x]=middle ;
                    else if(middle>255)
                        pbFinal[y*1280+x]=255;
                    else 
                        pbFinal[y*1280+x]=0;
                    }
            }
        }
        //对渐变范围也做平衡处理:
            for (int y=0;y<1024;y++)
            {
                for (int x=0;x<1280;x++)
                {
                    srcx=(double)(newWidth/2-middleInFinalx+x)/dbZoom;
                    srcy=(double)(newHeight/2-middleInFinaly+y)/dbZoom ;
                    if( !(srcx>=xl && srcx<=xr && srcy>=yu && srcy<=yd))
                        ;
                    else if( !(srcx>=xl+transition && srcx<=xr-transition && srcy>=yu+transition && srcy<=yd-transition))
                        {
                            double weight=1;//代表内圈所占的权重
                            if(srcx>=xl && srcx<=xl+transition)
                                weight=(srcx-xl)*1.0/transition;
                            else if(srcx>=xr-transition && srcx<=xr)
                                weight=(xr-srcx)*1.0/transition;
                            if(srcy>=yu && srcy<=yu+transition)
                                weight=(srcy-yu)*1.0/transition;
                            else if(srcy>=yd-transition && srcy<=yd)
                                weight=(yd-srcy)*1.0/transition;
                            if((srcx>=xl && srcx<=xl+transition)&&(srcy>=yu && srcy<=yu+transition))
                                weight=min((srcx-xl),(srcy-yu))*1.0/transition;
                            else if((srcx>=xl && srcx<=xl+transition)&&(srcy>=yd-transition && srcy<=yd))
                                weight=min((srcx-xl),(yd-srcy))*1.0/transition;
                            else if((srcx>=xr-transition && srcx<=xr)&&(srcy>=yu && srcy<=yu+transition))
                                weight=min((xr-srcx),(srcy-yu))*1.0/transition;
                            else if((srcx>=xr-transition && srcx<=xr)&&(srcy>=yd-transition && srcy<=yd))
                                weight=min((xr-srcx),(yd-srcy))*1.0/transition;
                    
                    double middle=0;
                    middle=(1-weight)*pbMiddle1[y*1280+x]+weight*(w3*pbMiddle2[y*1280+x]+b3);
                        //middle=(1-weight)*pbMiddle1[y*1280+x]+weight*(w2*pbMiddle2[y*1280+x]);
                    if(middle<=255&&middle>=0)
                       pbFinal[y*1280+x]=middle ;
                    else if(middle>255)
                        pbFinal[y*1280+x]=255;
                    else 
                        pbFinal[y*1280+x]=0;
                         }
                }
            } 
            */
    return ERROR_SUCCESS;
    }
    View Code

    为什么选择(615,730)。

    在当前dbZoom下!很重要!例如当前dbZoom=0.6

    首先,移动内圈至其偏移中心:

    其次,对于外圈:中心(640,512)。

    srcx=(double)(1.5*newWidth-640+x)/(3*dbZoom);//补偏差
    srcy=(double)(1.5*newHeight-512+y)/(3*dbZoom);

    使内外圈边界对齐,试验,得出:

    int middleInFinalx=620;//内圈图像待放置的,处于目标图中的图像中心。(也是图像放大中心)
    int middleInFinaly=705;

    srcx=(double)(1.5*newWidth-middleInFinalx+x-20)/(3*dbZoom);//补偏差
    srcy=(double)(1.5*newHeight-middleInFinaly+y+193)/(3*dbZoom);

    仅在当前dbZoom下有效。。

    扩展到任意倍数放大,改为:

    srcx=(double)(1.0/2*3*newWidth-middleInFinalx+x-20/0.6*dbZoom)/(3*dbZoom);//补偏差
    srcy=(double)(1.0/2*3*newHeight-middleInFinaly+y+193/0.6*dbZoom)/(3*dbZoom);


    最后的代码:

    // Imagejoint.cpp : 定义控制台应用程序的入口点。
    //
    #include "stdafx.h"
    #include "Imagejoint.h"
    #include <afxwin.h> 
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    #include <atlimage.h>//CImage类
    #include <locale.h>
    #include "math.h"
    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 pbSrc1,PBYTE pbSrc2,int iWidth,int iHeight,double dbZoom,PBYTE pbFinal,PBYTE pbMiddle1,PBYTE pbMiddle2);
    
    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)
        {
    
            HRESULT hResult1,hResult2;
            //初始化一些变量
            int        iWidth,iHeight,iBytePerPixel,iPitch;
            int        x,y;
            PBYTE    pbSrc1=NULL,pbSrc2=NULL,pbFinal=NULL;//源图、目标图
            PBYTE    pbMiddle1=NULL,pbMiddle2=NULL;
            PBYTE    pbImage=NULL;//load图像后存在这
            PDWORD    pdwImage=NULL;//用于保存图像
            int frame_num=1;
            double    dbZoom=1.25;
    
            //起始放大倍数,需要注意!过小外图都填不下。
            for(dbZoom=0.66;dbZoom<=1.50;dbZoom+=0.001)
            {
                
                CImage cImage_far;
                CImage cImage_near;
    
                CString farsrc= "1.bmp";
                CString nearsrc = "1650.bmp";
    
                LPCTSTR filename1 = (LPCTSTR)farsrc;
                LPCTSTR filename2 = (LPCTSTR)nearsrc;
      
                if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
                {
                    // TODO: change error code to suit your needs
                    _tprintf(_T("Fatal Error: MFC initialization failed
    "));
                    nRetCode = 1;
                    
                }
                //Load 图像到cImage对象中
                hResult1=cImage_far.Load(filename1);
                hResult2=cImage_near.Load(filename2);
                if(hResult1!=ERROR_SUCCESS||hResult2!=ERROR_SUCCESS)
                {
                    _tprintf(_T("源图像文件名错误!
    "));
                    nRetCode= -3;
                  
                }
                
                iWidth=cImage_far.GetWidth();
                iHeight=cImage_far.GetHeight();
                //分配源图内存
                pbSrc1 = (PBYTE)malloc(iWidth*iHeight);
                pbSrc2 = (PBYTE)malloc(iWidth*iHeight);
                //分配目标图内存
                pbFinal = (PBYTE)malloc(1280*1024);
                pbMiddle1=(PBYTE)malloc(1280*1024);
                pbMiddle2=(PBYTE)malloc(1280*1024);
    
                if(pbSrc1==NULL||pbSrc2==NULL || pbFinal==NULL )
                {
                    _tprintf(_T("内存申请错误!
    "));
                    nRetCode= -4;
                   
                }
                //cImage数据存到pbImage,后再转换为源灰度图pbSrc
                iPitch=cImage_far.GetPitch();
                iBytePerPixel=(cImage_far.GetBPP()+7)/8;
                if(iBytePerPixel==3)
                {
                    for(y=0;y<iHeight;y++)
                    {   //load的图像数据放到pbImage
                        pbImage=(PBYTE)(PBYTE(cImage_far.GetBits())+iPitch*y);//得到的是图像初始像素地址
                        for(x=0;x<iWidth;x++)
                        {
                            //pbImage转换为灰度图pbSrc
                            pbSrc1[y*iWidth+x]=(pbImage[3*x]*0.15+pbImage[3*x+1]*0.55+pbImage[3*x+2]*0.3);
                        }
                    }
                }
                cImage_far.Destroy();
    
                iPitch=cImage_near.GetPitch();
                iBytePerPixel=(cImage_near.GetBPP()+7)/8;
                if(iBytePerPixel==3)
                {
                    for(y=0;y<iHeight;y++)
                    {   //load的图像数据放到pbImage
                        pbImage=(PBYTE)(PBYTE(cImage_near.GetBits())+iPitch*y);//得到的是图像初始像素地址
                        for(x=0;x<iWidth;x++)
                        {
                            //pbImage转换为灰度图pbSrc
                            pbSrc2[y*iWidth+x]=(pbImage[3*x]*0.15+pbImage[3*x+1]*0.55+pbImage[3*x+2]*0.3);
                        }
                    }
                }
                cImage_near.Destroy();
    
                //执行操作
                hResult1=Imagejoint(pbSrc1,pbSrc2,iWidth,iHeight,dbZoom,pbFinal,pbMiddle1,pbMiddle2);
                if(hResult1!=ERROR_SUCCESS)
                {
                    _tprintf(_T("图像处理错误!
    "));
                    nRetCode= -5;
                   
                }
                //处理后保存图像
                iWidth=1280;
                iHeight=1024;
                cImage_far.Create(iWidth,-iHeight,32);
                iPitch=cImage_far.GetPitch();
                for(y=0;y<iHeight;y++)
                {
                    pdwImage=(PDWORD)(PBYTE(cImage_far.GetBits())+iPitch*y);
                    for(x=0;x<iWidth;x++)
                    {
                        pdwImage[x]=pbFinal[y*iWidth+x]*0x10101;  
                    }
                }
                //可预存待保存图像文件名
                CString name1="D:/文件及下载相关/桌面/模拟变焦拼接/Matlab_code/result/";
                CString name2;
                //这里要随着帧数改动
                name2.Format(_T("%d"),frame_num);
                CString csTagName;
                csTagName=name1+name2;
                
                csTagName.Trim();
                csTagName.MakeUpper();
                if(csTagName.Right(4)!=_T(".bmp") ) csTagName.Append(_T(".bmp"));
                hResult1=cImage_far.Save(csTagName);
                if(hResult1!=ERROR_SUCCESS)
                {
                    _tprintf(_T("图像结果保存错误!
    "));
                    nRetCode= -5;
                   
                }
                _tprintf(_T("图像处理成功!
    "));
                nRetCode= ERROR_SUCCESS;
    
                if(pbSrc1) free(pbSrc1);
                if(pbSrc2) free(pbSrc2);
                if(pbFinal) free(pbFinal);
                
                //dbZoom=dbZoom+0.0070;
                //dbZoom=dbZoom+0.25;
                frame_num++;
            }//对应+=0.25倍数的for循环。
    
        }
        else
        {
            _tprintf(_T("Fatal Error: GetModuleHandle failed
    "));
            nRetCode = 1;
        }
        getchar();    
        return nRetCode;
    }
    
    HRESULT Imagejoint(PBYTE pbSrc1,PBYTE pbSrc2,int iWidth,int iHeight,double dbZoom,PBYTE pbFinal,PBYTE pbMiddle1,PBYTE pbMiddle2)
    {
        double phase[33]={0};//16相位,包含端点存在33个距离
        for (int i=0;i<33;i++)
        {
            double i2=1.0*i;
            phase[i]=fs(i2/16);
        }
        double count_a=0;
        double count_b=0;
        double count=0;
        double w=1;
    
        //Matlab中测试获取定值(34:541 -Y,41:728 -X),需要微调。
        //int xl=41,xr=720,yu=34,yd=541;//原768*576大小图像中,存在内容的部分。
        //int xl=3,xr=752,yu=3,yd=574;
        int xl=30,xr=720,yu=30,yd=550;
        int transition=25;//渐变像素过渡设置
    
    
        //旋转中心为图像中心
        double rx0=iWidth;  
        double ry0=iHeight; 
        double srcx,srcy,u,v;
        int xOr,yOr;
        int newWidth=ceil(dbZoom*iWidth);
        int newHeight=ceil(dbZoom*iHeight);
        int middleInFinalx=617;//内圈图像待放置的,处于目标图中的图像中心。(也是图像放大中心)
        int middleInFinaly=730;
    
    
    
        int changex=middleInFinalx-640;
        int changey=middleInFinaly-512;
        double scale_y=1.01;
        double scale_x=1.02;//0.9内圈拉开
    
        for (int y=0;y<1024;y++)
        {
            for (int x=0;x<1280;x++)
            {
    
                srcx=(double)(newWidth/2.0-middleInFinalx+x)/dbZoom;
                srcy=(double)(newHeight/2.0-middleInFinaly+y)/(dbZoom) ;
                xOr = floor(srcx);
                yOr = floor(srcy);
                u=srcx-xOr;
                v=srcy-yOr;
    
                int phasex=floor(16*u+0.5);//16相位
                int phasey=floor(16*v+0.5);
                double A1,B1,C1,D1,A2,B2,C2,D2;
                A1=phase[16+phasex];
                B1=phase[phasex];
                C1=phase[16-phasex];
                D1=phase[32-phasex];
    
                A2=phase[16+phasey];
                B2=phase[phasey];
                C2=phase[16-phasey];
                D2=phase[32-phasey];
    
                if( !(srcx>=xl && srcx<=xr && srcy>=yu && srcy<=yd))//越界部分需拼接为外圈大视场图像,远景
                    {
                        //srcx=(double)(1.5*newWidth-640+x)/(3*dbZoom);//原始外图摆放位置,以目标图像中心为中心。
                        //srcy=(double)(1.5*newHeight-512+y)/(3*dbZoom);
                        srcx=(double)(scale_x*1.5*newWidth-middleInFinalx+x+changex/0.7*dbZoom)/(scale_x*3*dbZoom);//补偏差
                        srcy=(double)(scale_y*1.5*newHeight-middleInFinaly+y+changey/0.7*dbZoom)/(scale_y*3*dbZoom);//此处映射公式为外圈比内圈放大倍数=3。原来是2。
            
                        xOr = floor(srcx);
                        yOr = floor(srcy);
                        u=srcx-xOr; 
                        v=srcy-yOr;
    
                        if(xOr>iWidth)
                            xOr=iWidth;
                        if(yOr>iHeight)
                            yOr=iHeight;
                        if(xOr<0)
                            xOr=0;
                        if(yOr<0)
                            yOr=0;
    
    
                        phasex=floor(16*u+0.5);//16相位
                        phasey=floor(16*v+0.5);
    
                        A1=phase[16+phasex];
                        B1=phase[phasex];
                        C1=phase[16-phasex];
                        D1=phase[32-phasex];
    
                        A2=phase[16+phasey];
                        B2=phase[phasey];
                        C2=phase[16-phasey];
                        D2=phase[32-phasey];
    
                        double middle=
                        pbSrc1[(yOr-1)*iWidth+(xOr-1)]*A1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr-1)]*A1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr-1)]*A1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr-1)]*A1*D2+
                        
                        pbSrc1[(yOr-1)*iWidth+(xOr)]*B1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr)]*B1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr)]*B1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr)]*B1*D2+
    
                        pbSrc1[(yOr-1)*iWidth+(xOr+1)]*C1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr+1)]*C1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr+1)]*C1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr+1)]*C1*D2+
    
                        pbSrc1[(yOr-1)*iWidth+(xOr+2)]*D1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr+2)]*D1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr+2)]*D1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr+2)]*D1*D2;
    
                    if(middle<=255&&middle>=0)
                        pbFinal[y*1280+x]=middle;
                    else if(middle>255)
                        pbFinal[y*1280+x]=255;
                    else 
                        pbFinal[y*1280+x]=0;
                                    
                        pbFinal[y*1280+x]=pbSrc1[(yOr)*iWidth+(xOr)];
                        
                    //pbFinal[y*1280+x]=255;
                
                }
    
                
                else if( !(srcx>=xl+transition && srcx<=xr-transition && srcy>=yu+transition && srcy<=yd-transition))
                        {
                            double weight=1;//代表内圈所占的权重
    
                            if(srcx>=xl && srcx<=xl+transition)
                                weight=(srcx-xl)*1.0/transition;
                            else if(srcx>=xr-transition && srcx<=xr)
                                weight=(xr-srcx)*1.0/transition;
    
                            if(srcy>=yu && srcy<=yu+transition)
                                weight=(srcy-yu)*1.0/transition;
                            else if(srcy>=yd-transition && srcy<=yd)
                                weight=(yd-srcy)*1.0/transition;
    
                            if((srcx>=xl && srcx<=xl+transition)&&(srcy>=yu && srcy<=yu+transition))
                                weight=min((srcx-xl),(srcy-yu))*1.0/transition;
                            else if((srcx>=xl && srcx<=xl+transition)&&(srcy>=yd-transition && srcy<=yd))
                                weight=min((srcx-xl),(yd-srcy))*1.0/transition;
                            else if((srcx>=xr-transition && srcx<=xr)&&(srcy>=yu && srcy<=yu+transition))
                                weight=min((xr-srcx),(srcy-yu))*1.0/transition;
                            else if((srcx>=xr-transition && srcx<=xr)&&(srcy>=yd-transition && srcy<=yd))
                                weight=min((xr-srcx),(yd-srcy))*1.0/transition;
                            //pbFinal[y*1280+x]=255;
                        srcx=(double)(scale_x*1.5*newWidth-middleInFinalx+x-35.7*dbZoom)/(scale_x*3*dbZoom);//补偏差
                        srcy=(double)(scale_y*1.5*newHeight-middleInFinaly+y+311.4*dbZoom)/(scale_y*3*dbZoom);
                        xOr = floor(srcx);
                        yOr = floor(srcy);
                        u=srcx-xOr; 
                        v=srcy-yOr;
    
    
                        if(xOr>iWidth)
                            xOr=iWidth;
                        if(yOr>iHeight)
                            yOr=iHeight;
                        if(xOr<0)
                            xOr=0;
                        if(yOr<0)
                            yOr=0;
    
                        phasex=floor(16*u+0.5);//16相位
                        phasey=floor(16*v+0.5);
                        A1=phase[16+phasex];
                        B1=phase[phasex];
                        C1=phase[16-phasex];
                        D1=phase[32-phasex];
                        A2=phase[16+phasey];
                        B2=phase[phasey];
                        C2=phase[16-phasey];
                        D2=phase[32-phasey];
                        double middle1=
                        pbSrc1[(yOr-1)*iWidth+(xOr-1)]*A1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr-1)]*A1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr-1)]*A1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr-1)]*A1*D2+                    
                        pbSrc1[(yOr-1)*iWidth+(xOr)]*B1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr)]*B1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr)]*B1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr)]*B1*D2+
                        pbSrc1[(yOr-1)*iWidth+(xOr+1)]*C1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr+1)]*C1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr+1)]*C1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr+1)]*C1*D2+
                        pbSrc1[(yOr-1)*iWidth+(xOr+2)]*D1*A2+
                        pbSrc1[(yOr)*iWidth+(xOr+2)]*D1*B2+
                        pbSrc1[(yOr+1)*iWidth+(xOr+2)]*D1*C2+
                        pbSrc1[(yOr+2)*iWidth+(xOr+2)]*D1*D2;
                        
                    if(middle1<=255&&middle1>=0)
                        pbMiddle1[y*1280+x]=middle1;
                    else if(middle1>255)
                        pbMiddle1[y*1280+x]=255;
                    else 
                        pbMiddle1[y*1280+x]=0;
                //外图的渐变区域的值,先存到pbMiddle1中。
                //------------------------------------------------------------
                        srcx=(double)(newWidth/2-middleInFinalx+x)/dbZoom;
                        srcy=(double)(newHeight/2-middleInFinaly+y)/(dbZoom) ;
                        xOr = floor(srcx);
                        yOr = floor(srcy);
                        u=srcx-xOr;
                        v=srcy-yOr;
                        phasex=floor(16*u+0.5);//16相位
                        phasey=floor(16*v+0.5);
                        A1=phase[16+phasex];
                        B1=phase[phasex];
                        C1=phase[16-phasex];
                        D1=phase[32-phasex];
                        A2=phase[16+phasey];
                        B2=phase[phasey];
                        C2=phase[16-phasey];
                        D2=phase[32-phasey];            
                        double middle2=
                        pbSrc2[(yOr-1)*iWidth+(xOr-1)]*A1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr-1)]*A1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr-1)]*A1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr-1)]*A1*D2+                    
                        pbSrc2[(yOr-1)*iWidth+(xOr)]*B1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr)]*B1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr)]*B1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr)]*B1*D2+
                        pbSrc2[(yOr-1)*iWidth+(xOr+1)]*C1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr+1)]*C1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr+1)]*C1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr+1)]*C1*D2+
                        pbSrc2[(yOr-1)*iWidth+(xOr+2)]*D1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr+2)]*D1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr+2)]*D1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr+2)]*D1*D2;
                        
                    if(middle2<=255&&middle2>=0)
                        pbMiddle2[y*1280+x]=middle2;
                    else if(middle2>255)
                        pbMiddle2[y*1280+x]=255;
                    else 
                        pbMiddle2[y*1280+x]=0;
                    //内图的渐变区域的值,再存到pbMiddle2中。
                        //count++;
                        //count_a+=middle1;
                        //count_b+=middle2;
                        //w=count_a/count-count_b/count;
                        //w=count_a/count_b;                
    //边界融合
                    double middle3=(1-weight)* pbMiddle1[y*1280+x]+weight*pbMiddle2[y*1280+x];
                    pbFinal[y*1280+x]=middle3;
    
                        }    
                        
    //内圈,核心区域pbSrc2-B
                else
                {   
                    double middle3=
                        pbSrc2[(yOr-1)*iWidth+(xOr-1)]*A1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr-1)]*A1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr-1)]*A1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr-1)]*A1*D2+
                        
                        pbSrc2[(yOr-1)*iWidth+(xOr)]*B1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr)]*B1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr)]*B1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr)]*B1*D2+
    
                        pbSrc2[(yOr-1)*iWidth+(xOr+1)]*C1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr+1)]*C1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr+1)]*C1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr+1)]*C1*D2+
    
                        pbSrc2[(yOr-1)*iWidth+(xOr+2)]*D1*A2+
                        pbSrc2[(yOr)*iWidth+(xOr+2)]*D1*B2+
                        pbSrc2[(yOr+1)*iWidth+(xOr+2)]*D1*C2+
                        pbSrc2[(yOr+2)*iWidth+(xOr+2)]*D1*D2;
                    //w=count_a/count-count_b/count;
                    //w=count_a/count_b;//0.762953
                    //middle3=middle3*w;                
                    if(middle3<=255&&middle3>=0)
                        pbFinal[y*1280+x]=middle3;
                    else if(middle3>255)
                        pbFinal[y*1280+x]=255;
                    else 
                        pbFinal[y*1280+x]=0;                
                     }        
            }
        }
    
    
    //亮度平衡部分
    double sum1=0,sum2=0;
    double w2=1;
    double xl2=0,xr2=0,yu2=0,yd2=0;
    //四点用于确定内圈的亮度平衡范围
    /*
    //xl2=ceil(xl*dbZoom-newWidth/2+640);
    //xr2=ceil(xr*dbZoom-newWidth/2+640);
    //yu2=ceil(yu*dbZoom-newHeight/2+512);
    //yd2=ceil(yd*dbZoom-newHeight/2+512);
    */
    
    xl2=floor((xl+transition)*dbZoom-newWidth/2+middleInFinalx);
    xr2=ceil((xr-transition)*dbZoom-newWidth/2+middleInFinalx);//原来有细线是因为最后渐变部分2用的pbFinal
    yu2=floor((yu+transition)*dbZoom-newHeight/2+middleInFinaly);
    yd2=ceil((yd-transition)*dbZoom-newHeight/2+middleInFinaly);
    
    //for (int y=0;y<1024;y++)
    //    {
    //        for (int x=0;x<1280;x++)
    //        {    if(pbMiddle1[y*1280+x]!=205)
    //            sum1+=pbMiddle1[y*1280+x];
    //            if(pbMiddle2[y*1280+x]!=205)
    //            sum2+=pbMiddle2[y*1280+x];
    //        }
    //    }
    //    w2=sum1/sum2;//0.82    ,原来的直接取一个系数。
    
    
    //统计直方图
    double middle1_state[256]={0};
    double middle2_state[256]={0};
    int gray1=0;
    int gray2=0;
    int num1_L=0;
    int num1_H=0;
    int num2_L=0;
    int num2_H=0;
    int gray1L=0;
    int gray1H=0;
    int gray2L=0;
    int gray2H=0;
    
        for (int y=0;y<1024;y++)
        {
            for (int x=0;x<1280;x++)
            {    
                if(pbMiddle1[y*1280+x]!=205)
                {
                    gray1=pbMiddle1[y*1280+x];
                    middle1_state[gray1]++;//按灰度级统计外圈的
                }
                if(pbMiddle2[y*1280+x]!=205)
                {
                    gray2=pbMiddle2[y*1280+x];
                    middle2_state[gray2]++;//按灰度级统计内圈的
                }
            }
        }
    //统计好后分别找前1/3和后1/3
        //先统计总个数
        for(int gray=0;gray<256;gray++)
        {
            sum1+=middle1_state[gray];//个数之和,共有多少个有效元素。
            sum2+=middle1_state[gray];
        }
        //外圈统计中找1/3
        for(int gray=0;gray<256;gray++)
        {
            num1_L+=middle1_state[gray];
            if(num1_L<=sum1/3.0)
            {gray1L=gray;}//前1/3数量的灰度级是到gray1L。
            else
                ;
        }
        for(int gray=255;gray>=0;gray--)
        {
            num1_H+=middle1_state[gray];
            if(num1_H<=sum1/3.0)
            {gray1H=gray;}//后1/3数量的灰度级是到gray1H。
            else
                ;
        }
        //内圈统计找1/3
        for(int gray=0;gray<256;gray++)
        {
            num2_L+=middle2_state[gray];
            if(num2_L<=sum2/3.0)
            {gray2L=gray;}//前1/3数量的灰度级是到gray2L。
            else
                ;
        }
        for(int gray=255;gray>=0;gray--)
        {
            num2_H+=middle2_state[gray];
            if(num2_H<=sum2/3.0)
            {gray2H=gray;}//后1/3数量的灰度级是到gray2H。
            else
                ;
        }
    //统计好后,计算A1,A2,B1,B2。双点进行亮度平衡。
        double sum1L=0,sum1H=0,sum2L=0,sum2H=0;//用于统计个数
        double pix_sum1L=0,pix_sum1H=0,pix_sum2L=0,pix_sum2H=0;//用于累计像素值求和
        double A1=0,A2=0,B1=0,B2=0;
        double w3=1,b3=1;//要用到的,增益和偏置参数
        //外圈的1/3计算A1,A2
        for(int gray=0;gray<=gray1L;gray++)
        {
            sum1L+=middle1_state[gray];
            pix_sum1L+=middle1_state[gray]*gray;
        }
        for(int gray=255;gray>=gray1H;gray--)
        {
            sum1H+=middle1_state[gray];
            pix_sum1H+=middle1_state[gray]*gray;
        }
        //内圈的1/3计算B1,B2
        for(int gray=0;gray<=gray2L;gray++)
        {
            sum2L+=middle2_state[gray];
            pix_sum2L+=middle2_state[gray]*gray;
        }
        for(int gray=255;gray>=gray2H;gray--)
        {
            sum2H+=middle2_state[gray];
            pix_sum2H+=middle2_state[gray]*gray;
        }
        A1=pix_sum1L/sum1L;
        A2=pix_sum1H/sum1H;
    
        B1=pix_sum2L/sum2L;
        B2=pix_sum2H/sum2H;
    
        w3=(A2-A1)/(B2-B1);
        b3=A1-w3*B1;
        double middle=0;
        
        //w3=1;b3=0;
    
    //===================================================================================
    
    //亮度平衡
        for (int y=0;y<1024;y++)
        {
            for (int x=0;x<1280;x++)
            {
                    if(x>=xl2 && x<=xr2 && y>=yu2 && y<=yd2)
                    {
                        double middle=0;
                        middle=w3*pbFinal[y*1280+x]+b3;
                        //middle=w2*pbFinal[y*1280+x];
                    if(middle<=255&&middle>=0)
                       pbFinal[y*1280+x]=middle ;
                    else if(middle>255)
                        pbFinal[y*1280+x]=255;
                    else 
                        pbFinal[y*1280+x]=0;
                    }
            }
        }
        //对渐变范围也做平衡处理:
            for (int y=0;y<1024;y++)
            {
                for (int x=0;x<1280;x++)
                {
                    srcx=(double)(newWidth/2.0-middleInFinalx+x)/dbZoom;
                    srcy=(double)(newHeight/2.0-middleInFinaly+y)/(dbZoom);
    
                    if( !(srcx>xl && srcx<xr && srcy>yu && srcy<yd))
                        ;//外圈保持不变
                    else if( !(srcx>=xl+transition && srcx<=xr-transition && srcy>=yu+transition && srcy<=yd-transition))
                        {
                            double weight=1;//代表内圈所占的权重
                            if(srcx>=xl && srcx<=xl+transition)
                                weight=(srcx-xl)*1.0/transition;
                            else if(srcx>=xr-transition && srcx<=xr)
                                weight=(xr-srcx)*1.0/transition;
                            if(srcy>=yu && srcy<=yu+transition)
                                weight=(srcy-yu)*1.0/transition;
                            else if(srcy>=yd-transition && srcy<=yd)
                                weight=(yd-srcy)*1.0/transition;
                            if((srcx>=xl && srcx<=xl+transition)&&(srcy>=yu && srcy<=yu+transition))
                                weight=min((srcx-xl),(srcy-yu))*1.0/transition;
                            else if((srcx>=xl && srcx<=xl+transition)&&(srcy>=yd-transition && srcy<=yd))
                                weight=min((srcx-xl),(yd-srcy))*1.0/transition;
                            else if((srcx>=xr-transition && srcx<=xr)&&(srcy>=yu && srcy<=yu+transition))
                                weight=min((xr-srcx),(srcy-yu))*1.0/transition;
                            else if((srcx>=xr-transition && srcx<=xr)&&(srcy>=yd-transition && srcy<=yd))
                                weight=min((xr-srcx),(yd-srcy))*1.0/transition;
                    
                    double middle=0;
                    //middle=255;
                    middle=(1-weight)*pbMiddle1[y*1280+x]+weight*(w3*pbMiddle2[y*1280+x]+b3);
                        //middle=(1-weight)*pbMiddle1[y*1280+x]+weight*(w2*pbMiddle2[y*1280+x]);
                    if(middle<=255&&middle>=0)
                       pbFinal[y*1280+x]=middle ;
                    else if(middle>255)
                        pbFinal[y*1280+x]=255;
                    else 
                        pbFinal[y*1280+x]=0;
                         }
                }
            } 
            
    
    return ERROR_SUCCESS;
    }
    View Code
  • 相关阅读:
    【贪心】时空定位I
    【贪心】删数问题
    【贪心】取火柴游戏
    【贪心】均分纸牌
    Fix a Tree
    Vacations
    One Bomb
    Abandoned country
    BZOJ 1006 [HNOI2008]神奇的国度
    BZOJ 2118 墨墨的等式
  • 原文地址:https://www.cnblogs.com/wxl845235800/p/11210449.html
Copyright © 2020-2023  润新知