纯C++超分辨率重建SRCNN --改编--卷积2(前奏二)

前面的哪个卷积只适合用方形图像,一般的图像是长方形的,所以

这里重新找了一个博文《关于图像的二维卷积各种版本的实现(C++,Cuda和mex)》中的做模板:

首先是最常用的C++版本的卷积实现,代码如下:

void Conv2(int** filter, int** arr, int** res, int filterW, int filterH, int arrW, int arrH)  
{  
    int temp;  

    for (int i=0; i<filterH+arrH-1; i++)  
    {  
        for (int j=0; j<filterW+arrW-1; j++)  
        {  
            temp = 0;  
            for (int m=0; m<filterH; m++)  
            {  
                for (int n=0; n<filterW; n++)  
                {  
                    if ((i-m)>=0 && (i-m)<arrH && (j-n)>=0 && (j-n)<arrW)  
                    {  
                        temp += filter[m][n]*arr[i-m][j-n];  
                    }  
                }  
            }  
            res[i][j] = temp;  
        }  
    }  
} 

实现:

//c++实现卷积
#define USE_EGE 0 //选择ege (1)或 easyx(0)的开关
#if USE_EGE

	#include <ege.h> //使用ege库 和 easyx 差不多,这里没有实现
	using namespace ege;
#else
	#include <easyx.h>//使用easyx库
	#include<conio.h> 

#endif


#include<iostream>
#include<vector>
using namespace std;

#define SCREEN_WIDTH 1100 //窗口大小
#define SCREEN_HEIGHT 600

#define byte unsigned char

struct 卷积矩阵
{
	
	int		width;    //宽
	int     height;   //高

	//数据
	int *	data;

	//构造函数
	卷积矩阵(int iwidth,int iheight);
};

IMAGE jpg;//一张原图

//定义一个卷积过程中的矩阵
卷积矩阵::卷积矩阵(int iwidth,int iheight): width(iwidth),
                                            height(iheight)
											
{
	int size=sizeof(int)*width*iheight;
    data=(int*)malloc(size);

	memset(data, 0,size);
}


void error(char *s)
{ 
printf("%s\n",s);
getch();
exit(1);
} 


void loadjpg(char * jpgname)
{
	loadimage(&jpg,jpgname);//载入图像

}

//C++版本的卷积实现
void Conv2(float* filter, int* arr, int* res, int filterW, int filterH, int arrW, int arrH)  
{  
    float temp;  
	int resW=filterW+arrW-1;//输出宽
	int resH=filterH+arrH-1;//输出高

	for (int i=0; i<resH; i++)  //输入
    {  
        for (int j=0; j<resW; j++)  
        {  
            temp = 0;  
            for (int m=0; m<filterH; m++)  //核
            {  
                for (int n=0; n<filterW; n++)  
                {  
                    if ((i-m)>=0 && (i-m)<arrH && (j-n)>=0 && (j-n)<arrW)  
                    {  
						
                        temp += filter[m*filterW+n]*arr[(i-m)*arrW+(j-n)];  //积 和
                    }  
                }  
            }  
            res[i*resW+j] = (int)temp;  
        }  
    }  
}


int main()
{
	initgraph(SCREEN_WIDTH, SCREEN_HEIGHT,SHOWCONSOLE);//, INIT_RENDERMANUAL


	char jpgname[]="butterfly-0.jpg";
	//载入图片
	loadjpg(jpgname);


	SetWorkingImage(&jpg);//设置已经加载图片为要扫描的图片



	int height = jpg.getheight();
	int width = jpg.getwidth();


    // 1。定义被卷积的矩阵(其实是一个数组)
	// 这里用一张单色图代替
	卷积矩阵 isA(width,height);
	int  *A=isA.data;//(int*)malloc(sizeof(int)*map*map);



	//图像转化单色并保存结果
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			


			A[i*width+j]= GetRValue(RGBtoGRAY(getpixel(j , i)));//返回指定颜色 范围0-255


		}
	}
	SetWorkingImage();//还原为屏幕

	int c;
	//显示原图
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			
			c=A[i*width+j];//返回指定颜色 范围0-255
			putpixel(j, i, RGB(c,c,c));

		}
	}


	getch();
	


    // 2。定义卷积核矩阵(其实也是一个数组,数组元素的个数3*3)
    int const kernel = 3;
    float B[kernel*kernel] =
    {
#if 1
		//'sobel'     索贝尔水平边缘增强滤波器
		//-1, 0, 1,
		//-2, 0, 2,
		//-1, 0, 1

		1.2886529 , 0.04068733 , -1.3082279,
		1.43157125, 0.01173212 , -1.45389295,
		1.34158182, -0.07245208, -1.27504027

#else
		// 'unsharp'   反锐化对比度增强滤波器
		-0.1667,   -0.6667,-0.1667,
		-0.6667,    4.3333,-0.6667,
		-0.1667,   -0.6667,-0.1667
#endif
    };
   
	//计算卷积输出矩阵宽、高
	int c_width= kernel+width-1; //filterW+arrW-1;
	int c_height= kernel+height-1; // filterH+arrH-1;


		//3。卷积后输出矩阵
		卷积矩阵 isC(c_width,c_height);
		int * C=isC.data;

    //Conv2(int** filter, int** arr, int** res, int filterW, int filterH, int arrW, int arrH)  
    Conv2(B, A, C, kernel, kernel, width, height) ;

 
	//归一化
	//1。找最小最大值
	int imin=0,imax=255;
    for (int i = 0; i < c_height; i++)
    {
        for (int j = 0; j < c_width; j++)
        {
            c= C[i*c_width + j];
			//找最小值
			if(c<imin) imin=c;

			//找最大值
			if(c>imax)imax=c;
        }
    }
	cout << "最小值:"<<imin<<"最大值:"<<imax<<endl;
	//2。用最小最大值来归一化
    for (int i = 0,k; i < c_height; i++)
    {
        for (int j = 0; j < c_width; j++)
        {
			k=i*c_width + j;
            float p= C[k];
			p=(p-imin)/(imax-imin)*255;
			C[k]=p;

        }
    }


    //显示卷积图
    //cout << "卷积后输出矩阵:" << endl;
	
	
    for (int i = 0; i < c_height; i++)
    {
        for (int j = 0; j < c_width; j++)
        {
            c= C[i*c_width + j];

			putpixel(j+c_width+5, i, RGB(c,c,c));
        }
    }



		getch();

	closegraph();
    system("pause");
    return 0;
}

效果图:


卷积部分暂时就这样吧。

猜你喜欢

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