纯C++超分辨率重建SRCNN --改编--(七)双三次插值放大

最后一个问题了,一个博文《C#双三次插值缩放图像》好象不错,改一下放在这里

好象不能一次三个通道,R、G、B 要放大三次:

//-----------------------------------------------------------------------
//C#双三次插值缩放图像

/// <summary>  
/// 双三次插值缩放灰度图像。  
/// </summary>  
/// <param name="image">源图像。</param>  
/// <param name="newWidth">新宽度。</param>  
/// <param name="newHeight">新高度。</param>  
/// <returns>缩放后的图像。</returns>  
static void ResizeGrayscaleImage(IMAGE * P,double ZoomRate )  
{ 
//目标图像,缩放比,
	int Pwidth=P->getwidth();
	int Pheight=P->getheight();

	//分别对原图像获取指针
	DWORD* M=GetImageBuffer(P);
	

	//为BiCubic_Zoom函数准备数据
	//int m_nBitCount=8*3;
	int m_nBitCount=8;
   
    //图像每行像素字节数  
    int lineByte=(Pwidth*m_nBitCount/8+3)/4*4;  
       
   
    //申请缓冲区,存放后面函数用到的数据格式 输入  
       
    unsigned char* r=new unsigned char[lineByte * Pheight];  //R
    unsigned char* g=new unsigned char[lineByte * Pheight];  //G
    unsigned char* b=new unsigned char[lineByte * Pheight];  //B
DWORD tt;
int pp;

	for(int i=0;i<Pheight;i++)
		for(int j=0;j<Pwidth;j++)
			{
			tt=M[j+i*Pwidth];
			pp=j+i*lineByte;
			r[pp]=GetRValue(tt);
			g[pp]=GetGValue(tt);
			b[pp]=GetBValue(tt);
			}
	int newWidth= Pwidth * ZoomRate;
	int newHeight = Pheight * ZoomRate;

	//返回图像每行像素字节数  
    int lineByteOut=(newWidth*m_nBitCount/8+3)/4*4;  

	unsigned char* OutR=new unsigned char[lineByteOut * newHeight];  
	unsigned char* OutG=new unsigned char[lineByteOut * newHeight];  
	unsigned char* OutB=new unsigned char[lineByteOut * newHeight];  

	//这里三个通道分别缩放三次
	//ResizeProcess(BitmapData srcData, ref BitmapData dstData)  
	ResizeProcess(r,Pwidth,Pheight, lineByte,OutR,newWidth, newHeight,lineByteOut);  
	ResizeProcess(g,Pwidth,Pheight, lineByte,OutG,newWidth, newHeight,lineByteOut);  
	ResizeProcess(b,Pwidth,Pheight, lineByte,OutB,newWidth, newHeight,lineByteOut);  

	P->Resize(newWidth, newHeight);

	M=GetImageBuffer(P);
		
	Pwidth=P->getwidth();
	Pheight=P->getheight();
	//lineByte=(Pwidth*m_nBitCount/8+3)/4*4;  

	for(int i=0;i<Pheight;i++)
		for(int j=0;j<Pwidth;j++)
			{
			pp=j+i*lineByteOut;
			M[j+i*Pwidth]=RGB(OutR[pp],OutG[pp+1],OutB[pp+2]);
			}

}


/// <summary>  
/// 双三次插值处理缩放。  
/// </summary>  
/// <param name="srcData">源图像数据。</param>  
/// <param name="dstData">目标图像数据。</param>  
static void ResizeProcess(unsigned char*  srcData,int srcWidth,int srcHeight, int srcStride,
						  unsigned char*  dstData,int dstWidth,int dstHeight, int dstStride)  
{  
    // 获取源图像数据  
    //int srcWidth  = srcData.Width;  
    //int srcHeight = srcData.Height;  
    //int srcStride = srcData.Stride;  
    //IntPtr srcPtr = srcData.Scan0; 
	unsigned char*  srcPtr = srcData;
  
    // 获取目标图像数据  
    //int dstWidth  = dstData.Width;  
    //int dstHeight = dstData.Height;  
    //int dstStride = dstData.Stride;  
    int dstOffset = dstStride - dstWidth;  
    //IntPtr dstPtr = dstData.Scan0;  
	unsigned char*  dstPtr = dstData;

	// 计算比例系数  
    double xFactor = (double)srcWidth / dstWidth;  
    double yFactor = (double)srcHeight / dstHeight;  
  
    // 将源图像数据复制到托管内存中  
    int srcBytes = srcStride * srcHeight;  
    byte* srcGrayData = new byte[srcBytes];  
    //Marshal.Copy(srcPtr, srcGrayData, 0, srcBytes);  
	memcpy(srcGrayData, srcPtr, srcBytes);

    // 保存目标图像数据  
    int dstBytes = dstStride * dstHeight;  
    byte* dstGrayData = new byte[dstBytes];  
    int dst = 0;    // 下标  
  
    // 源图像坐标点及系数  
    double ox, oy, dx, dy, k1, k2;  
    int ox1, oy1, ox2, oy2;  
    // 目标图像像素值  
    double grayValue;  
    // 边界  
    int ymax = srcHeight - 1;  
    int xmax = srcWidth - 1;  
 
    //#region 插值  
    for (int y = 0; y < dstHeight; y++)  
    {  
        // Y坐标  
        oy = (double)y * yFactor - 0.5;  
        oy1 = (int)oy;  
        dy = oy - (double)oy1;  
  
        for (int x = 0; x < dstWidth; x++, dst++)  
        {  
            // X坐标  
            ox = (double)x * xFactor - 0.5f;  
            ox1 = (int)ox;  
            dx = ox - (double)ox1;  
  
            // 像素值归零  
            grayValue = 0;  
  
            for (int n = -1; n < 3; n++)  
            {  
                // Y系数  
                k1 = BiCubicInterpolator(dy - (double)n);  
  
                oy2 = oy1 + n;  
                if (oy2 < 0)  
                    oy2 = 0;  
                if (oy2 > ymax)  
                    oy2 = ymax;  
  
                for (int m = -1; m < 3; m++)  
                {  
                    // X系数  
                    k2 = k1 * BiCubicInterpolator((double)m - dx);  
  
                    ox2 = ox1 + m;  
                    if (ox2 < 0)  
                        ox2 = 0;  
                    if (ox2 > xmax)  
                        ox2 = xmax;  
  
                    grayValue += k2 * srcGrayData[oy2 * srcStride + ox2];  
                }  
            }  
            dstGrayData[dst] = (byte)max(0, min(255, grayValue));  
        }  
        dst += dstOffset;  
    }  
    //Marshal.Copy(dstGrayData, 0, dstPtr, dstBytes);  
		memcpy(dstPtr, dstGrayData, dstBytes);

    //#endregion  
}  
  
/// <summary>  
/// 双三次插值器。  
/// coefficient is set to -0.5.  
/// </summary>  
/// <param name="x">X Value.</param>  
/// <returns>Bicubic cooefficient.</returns>  
static double BiCubicInterpolator(double x)  
{  
    if (x < 0)  
    {  
        x = -x;  
    }  
  
    double biCoef = 0;  
  
    if (x <= 1)  
    {  
        biCoef = (1.5 * x - 2.5) * x * x + 1;  
    }  
    else if (x < 2)  
    {  
        biCoef = ((-0.5 * x + 2.5) * x - 4) * x + 2;  
    }  
  
    return biCoef;  
}  
  

效果

输入图:


放大图:


重建图:


这个图已经放大了两次,就是9倍,效果好象不明显,再过一次(不放大):


只能这样,看来是不能无限放大的。

本程序已经全部完成了。哈哈

猜你喜欢

转载自blog.csdn.net/juebai123/article/details/80586195