期末数字图像处理的作业

来源:互联网 发布:windows logo 编辑:程序博客网 时间:2024/05/21 06:33


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

前段时间买了一个自行车,花了我所有的积蓄!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);}