期末数字图像处理的作业


研究生一个学期就快读完了,好像效率不是特别的高...想了想最近干的一些事情,发现很多事情都没有很好的完成。原因就是自己的意志不是很坚定。想起来就惭愧啊。不知道是不是自己有点厌烦了现在这样的生活,没有一点热情与激情,充满着平淡的气息,让人很容易颓废。

前段时间买了一个自行车,花了我所有的积蓄!Grant ATX 750,红色的,很帅的一辆。不过很多时候都是一个人骑车,有点无聊的样子,不过还是每周会骑出去走走...远远的...长长的时间....发现好的自行车比以前的那种自行车真的好很多,骑起来很舒服的样子....哈哈...

还是说正事吧,我们期末要到了,很多门功课不用考试,让我很开心,毕竟我上课好像也不怎么听老师讲的,如果要考试还真的有点怕的说。数字图像这门功能就不用考试,哈哈,觉得这老师真好,好像只要不用考试的老师都是很好的...哈哈...不过期末还是要交点东西上去的,所以老师给我安排了4个题目,让我们编程实现,觉得计算机的学习,会的就是编写计算机程序,用这个来作为期末考试合情合理阿..哈哈,不过好像现在的中国不是这样的...

还是讲一下题目把,4个题目本身老师要求不是特别的难,而且老师的意思好像可以使用库函数做的,这老师放水有点严重阿...不过我吗,既然作了,还是想学点东西,不然不是白做了...题目分别为

           1.图像均值化

           2.图像的Gauss低通和Gauss高通

           3.对图像进行Gamma变化

           4.DCT变换,加上量化在反量化,和IDCT


这四个题目,如果是对一些进行图像处理的程序员来讲或者很简单,但是我基本不接触图像处理这个方面的(虽然我头上挂着这个牌子),基本原理不同,很难写程序。不过幸好我同学是搞这个方面的,而且他的讲解能让我很快的知道我应该怎么去处理这个图像,而且通过网络的搜索,我发现wiki上的讲解真的相当的精准阿...不带让人纠结的数学公式,也不会长篇大论,有的就是通俗易懂的步骤和例子。让人很快能知道我应该怎么都作就能完成这个效果的处理。这是我一直很喜欢使用wiki的原因,推荐推荐阿....

对于这个作业我本打算以最大的速度做完的,也不想真的去对原理进行真正的了解!所以只要知道怎么去做就可以了。突然想到了那几天前我好像也学习QT,所以想连着这个一起作一次练习。qt一个gui做的不错的库!而且简单的很...

既然使用了QT那就要求我使用C++来写这个程序,C++这个语言,很久很久没使用了,主要是觉得自己对C++好像很陌生了,或者可以说是对面向对象这个思想的陌生。关于这点,我也很想提出我的一点点想法。虽然很早就开始使用面向对象去编程,可是好像自己一直没有入门面向对象这种思想。使用C++的过程好像是将C++当成C来使用,很少很少说一定要使用到类,继承,多态这种特性。看了很多书说,要学好C++就要放弃一些东西,把面向对象的这些东西学好。可是面向对象到底是一种什么样的思想呢,有的时候很想用面向对象的思想去写程序,可是有时候却发现自己好像是为了面向对象而面向对象...好似纠结....应该是我经历的还不够吧。。。

关于这个作业,我最想讲的两个方面是:

1.qt中的QImage这个对象,为了能让内存高效的访问,qt通过空间去换取时间的方法来提升效率。让每一行都能被4B整除,这就是让qt本身会对每一行进行填充的过程,所以将一个一维的图像数据的转换为QImage是一个要小心的过程。当然其实如果你懂的,那就是一个构造函数的问题,我在这方面犯过错,所以提出来了。

2.关于DCT的变换

这个变换的公式很长很复杂,如果按公式来做的话,这个计算量是很大的,所以在网络搜索到一篇论文,好像是通过将其变为矩阵的乘法的运算,能减少相当大的运算量。据说JPEG也是用这种方式进行dct的变化的。使用矩阵的运算简单很多,而且很多东西是很巧妙的联系着的。

关于dct应该是我花时间最多的一个方面,因为开始不懂是怎么样的过程,随便看了以下就开始写程序,最后不但程序有问题,连我改程序的心情都没有了。直接把那个程序del了,重新写。在写之前找了不少的论文和资料,在有很大把握了基础下,开始了编码的过程,那天花了5个小时才完成,最后还有一点点的暇眦,不过那个时候时间太晚了,坚持不住就去睡觉了。。。。第二天花了点时间调试以后,很顺利的完成了,而且变化的速度很快,比我使用公式法快很多。。。而且效果很好的样子..让我很开心,这种成功的感觉很久没有了。


我只想把最好的那部分代码贴出来给大家看,DCT变换:

当然如果大家需要这个运行的代码可以发email给我(smy19890720@gmail.com),哈哈很多的bug我可不管的哦....

void pimage::rgb_convert_yuv()
{   
    for(size_t j = 0; j < heigth8; j++)
    {
	for(size_t i = 0; i < width8; i++)
	{
	    if(j < heigth && i < width)
	    {
		int r = image[j*width*bpp+i*bpp + 2];
		int g = image[j*width*bpp+i*bpp + 1];
		int b = image[j*width*bpp+i*bpp];
		y[j][i] =   0.3 * r + g * 0.59 + b * 0.11;
		u[j][i] = -0.147 *r - 0.289 * g + 0.436 * b;
		v[j][i] = 0.615 * r - 0.515 * g - 0.100 * b;
		y[j][i] = y[j][i] - 128;

		//printf("r = %u,g = %u,b = %u\n",r,g,b);
		//printf("y = %d,u = %d,v = %d\n",y[j][i],u[j][i],v[j][i]);
	    }
	    else
	    {
		y[j][i] = 0;
		u[j][i] = 0;
		v[j][i] = 0;
	    }
	}
    }
}

void pimage::yuv_convert_rgb()
{
    for(size_t i = 0; i < heigth8; i++)
    { for(size_t j = 0; j < width8; j++) {
	    if(i < heigth && j < width) 
	    {
		int tmpy = y[i][j] + 128;
		int tmpu = u[i][j];
		int tmpv = v[i][j];

		int r  = tmpy + (1.13983 * (tmpv));
		int g = tmpy - (0.58 * (tmpv)) - (0.39 *(tmpu));
		int b = tmpy + (2.03211 * (tmpu));
		if(r > 255)
		    r = 255;
		if(g > 255)
    		    g = 255;
    		if(b > 255)
    		    b = 255;

    		if(r < 0)
    		    r = 0;
    		if(g < 0)
    		    g = 0;
    		if(b < 0)
		    b = 0;	

		//printf("r = %d,g = %d,b = %d\n",r,g,b);
		//printf("y = %d,u = %d,v = %d\n",tmpy,tmpu,tmpv);

		
		image[i*width*bpp+j*bpp] = b;
		image[i*width*bpp+j*bpp + 1] = g;
		image[i*width*bpp+j*bpp + 2] = r;
	    }
	}
    }
}

void pimage::DCT()
{
    int tmpy[8][8];
    int tmpu[8][8];
    int tmpv[8][8];
    
    rgb_convert_yuv();
    get_dct(dct,dct_t);

    for(int j = 0; j < heigth8/8; j++)
    {
	for(int i = 0; i < width8/8; i++)
	{
	    for(int h = 0; h < 8; h++)
	    {
		for(int w = 0; w < 8; w++)
		{
		    tmpy[h][w] = y[j*8+h][i*8+w];
		    tmpu[h][w] = u[j*8+h][i*8+w];
		    tmpv[h][w] = v[j*8+h][i*8+w];
		    //printf("j = %d,i = %d,h = %d,w = %d\n",j,i,h,w);
		}
	    }

	    matrix_mul(dct,tmpy,dct_t);
	    matrix_mul(dct,tmpu,dct_t);
	    matrix_mul(dct,tmpv,dct_t);

	    lianhuay(tmpy);
	    lianhuau(tmpu);
	    lianhuau(tmpv);
	    for(int h = 0; h < 8; h++)
	    {
		for(int w = 0; w < 8; w++)
		{
		    y[j*8+h][i*8+w] = tmpy[h][w];
		    u[j*8+h][i*8+w] = tmpu[h][w];
		    v[j*8+h][i*8+w] = tmpv[h][w];
		}
		
	    }
	}
    }
}

void pimage::IDCT()
{
    int tmpy[8][8];
    int tmpu[8][8];
    int tmpv[8][8];

    
    for(int j = 0; j < heigth8/8; j++)
    {
	for(int i = 0; i < width8/8; i++)
	{
	    for(int h = 0; h < 8; h++)
	    {
		for(int w = 0; w < 8; w++)
		{
		    tmpy[h][w] = y[j*8+h][i*8+w];
		    tmpu[h][w] = u[j*8+h][i*8+w];
		    tmpv[h][w] = v[j*8+h][i*8+w];
		}
	    }

	    ilianhuay(tmpy);
	    ilianhuau(tmpu);
	    ilianhuau(tmpv);

	    matrix_mul(dct_t,tmpy,dct);
	    matrix_mul(dct_t,tmpu,dct);
	    matrix_mul(dct_t,tmpv,dct);

	    for(int h = 0; h < 8; h++)
	    {
		for(int w = 0; w < 8; w++)
		{
		    y[j*8+h][i*8+w] = tmpy[h][w];
		    u[j*8+h][i*8+w] = tmpu[h][w];
		    v[j*8+h][i*8+w] = tmpv[h][w];
		}
	    }

	}
    }
    yuv_convert_rgb();
}
void pimage::get_dct(float (*dct)[8],float (*dct_T)[8])
{
    for(int i = 0; i < 8; i++)
    {
	dct[0][i] = 1.0 / sqrt(8);
	dct_T[i][0] = dct[0][i];
    }

    for(int i = 1; i < 8; i++)
	for(int j = 0; j < 8; j++)
	{
	    dct[i][j] = sqrt(2.0/8)*cos((2*j+1)*i*PI/(2.0*8));
	    dct_T[j][i] = dct[i][j];
	}
}

void pimage::matrix_mul(float (*first)[8],int (*sec)[8],float (*third)[8])
{
    float tmp[8][8];
    float tmp1[8][8];
    
    for(int i = 0;i < 8;i++)
    {
	for(int j = 0;j < 8;j++)
	{
	    tmp[i][j] = 0;
	    for(int k = 0;k < 8;k++)
	    {
		tmp[i][j] += (first[i][k] * sec[k][j]);
	    }
	}
    }

    for(int i = 0;i < 8; i++)
    {
	for(int j = 0;j < 8; j++)
	{
	   tmp1[i][j] = 0; 
	   for(int k = 0; k < 8;k++)
	   {
	       tmp1[i][j] += (tmp[i][k] * third[k][j]);
	   }
	}
    }

    for(int i = 0;i < 8;i++)
    {
	for(int j = 0;j < 8;j++)
	{
	    sec[i][j] = round(tmp1[i][j]);
	}
    }
}

int pimage::round(float thiz)
{
    if(fabs(thiz - (int)thiz) >= (1.0/2))
    {
	if(thiz > 0)
	{
	    return (int)thiz + 1;
	}
	else
	{
	    return (int)thiz - 1;
	}
    }
    else
    {
	return (int)thiz;
    }
}


void pimage::lianhuay(int (*thiz)[8])
{
    static int matrix[8][8] = {
	{16,11,10,16,24,40,51,61},
	{12,12,14,19,26,58,60,55},
	{14,13,16,24,40,57,69,56},
	{14,17,22,29,51,87,80,62},
	{18,22,37,56,68,109,103,77},
	{24,35,55,64,81,104,113,92},
	{49,64,78,87,103,121,120,101},
	{72,92,95,98,112,100,103,99},
    };

    for(int i = 0; i < 8; i++)
    {
	for(int j = 0; j < 8; j++)
	{
	    thiz[i][j] = round(thiz[i][j]*1.0/matrix[i][j]);
	}
    }
}

void pimage::ilianhuay(int (*thiz)[8])
{
    static int matrix[8][8] = {
	{16,11,10,16,24,40,51,61},
	{12,12,14,19,26,58,60,55},
	{14,13,16,24,40,57,69,56},
	{14,17,22,29,51,87,80,62},
	{18,22,37,56,68,109,103,77},
	{24,35,55,64,81,104,113,92},
	{49,64,78,87,103,121,120,101},
	{72,92,95,98,112,100,103,99},
    };
    
    for(int i = 0; i < 8; i++)
    {
	for(int j = 0; j < 8; j++)
	{
	    thiz[i][j] = thiz[i][j] * matrix[i][j];
	}
    }
}

void pimage::lianhuau(int (*thiz)[8])
{
    static int matrix[8][8] = {
	{17,18,24,47,99,99,99,99},
	{18,21,26,66,99,99,99,99},
	{24,26,56,99,99,99,99,99},
	{47,66,99,99,99,99,99,99},
	{99,99,99,99,99,99,99,99},
	{99,99,99,99,99,99,99,99},
	{99,99,99,99,99,99,99,99},
	{99,99,99,99,99,99,99,99},
    };

    for(int i = 0; i < 8; i++)
    {
	for(int j = 0; j < 8; j++)
	{
	    thiz[i][j] = round(thiz[i][j]*1.0/matrix[i][j]);
	}
    }
}

void pimage::ilianhuau(int (*thiz)[8])
{
    static int matrix[8][8] = {
	{17,18,24,47,99,99,99,99},
	{18,21,26,66,99,99,99,99},
	{24,26,56,99,99,99,99,99},
	{47,66,99,99,99,99,99,99},
	{99,99,99,99,99,99,99,99},
	{99,99,99,99,99,99,99,99},
	{99,99,99,99,99,99,99,99},
	{99,99,99,99,99,99,99,99},
    };

    for(int i = 0; i < 8; i++)
    {
	for(int j = 0; j < 8; j++)
	{
	    thiz[i][j] = thiz[i][j] * matrix[i][j];
	}
    }
}

void pimage::get_psnr()
{
    uchar *tmp_image = (uchar*)calloc(width*heigth*bpp,sizeof(uchar));
    memcpy(tmp_image,image,width*heigth*bpp);
    DCT();
    IDCT();
    
    double psnr_r = 0;
    double psnr_g = 0;
    double psnr_b = 0;

    double mse_r = 0;
    double mse_g = 0;
    double mse_b = 0;

    for(int i = 0; i < this->heigth; i++)
	for(int j = 0; j < this->width; j++)
	{
	    mse_b = mse_b + (image[i*this->width*bpp+j*bpp] - tmp_image[i*width*bpp+j*bpp]) * (image[i*this->width*bpp+j*bpp] - tmp_image[i*width*bpp+j*bpp]);
	    mse_g = mse_g + (image[i*this->width*bpp+j*bpp + 1] - tmp_image[i*width*bpp+j*bpp + 1]) * (image[i*this->width*bpp+j*bpp + 1] - tmp_image[i*width*bpp+j*bpp + 1]);
	    mse_r = mse_r + (image[i*this->width*bpp+j*bpp + 2] - tmp_image[i*width*bpp+j*bpp + 2]) * (image[i*this->width*bpp+j*bpp + 2] - tmp_image[i*width*bpp+j*bpp + 2]);
	}
    mse_r = mse_r / (heigth * width);
    mse_g = mse_g / (heigth * width);
    mse_b = mse_b / (heigth * width);
    
    psnr_r = 20 * log10(255/sqrt(mse_r));
    psnr_g = 20 * log10(255/sqrt(mse_g));
    psnr_b = 20 * log10(255/sqrt(mse_b));

    printf("r = %lf,g = %lf,b = %lf\n",psnr_r,psnr_g,psnr_b);
    free(tmp_image);
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值