代码改变世界

TJU_SCS_软件测试_homework1——《error impressed me most》

2016-03-06 18:13  blueContra  阅读(217)  评论(0编辑  收藏  举报

  1.作业要求  

  作为TJU_SCS中一个普通的本科生,虽然我写的projects不多,但在学习和作业中也都遇到过许多不大小的bugs、errors,一方面是在完成作业或者是在学习新知识的过程中必然会由于编程知识的缺乏和技术经验的不足而遇到让人头痛的情况。这次作业要求把最近遇到的印象深刻的编程中的问题写到博客上,这里就简单的说明一下。

  

  2.作业内容

  上学期在选修图像处理这门课的时候,有一次作业让我印象深刻,由于一小段代码的失误,我折腾了数个小时,直到凌晨3点才找出问题。

  

    2.1具体情况:

    当时图像作业的题目是——双立方插值算法放缩图像的matlab实现

    作业要求如下:

    要求写一段Matlab的代码,该代码能够对图像进行放缩,通过使用自己推导的bicubic interpolation算法。

    输入要求:a) 一张图像 b)长宽放缩系数

    这个问题实际上就是,对一张输入的图片,根据需要放缩的倍数,确定输出图片的大小,然后根据输入图片的RGB三个颜色空间的每个像素进行矩阵变换,通过计算得到对    应的变换过后的图片。

  

    2.2错误现象

    当时我在觉得代码写完没什么问题的时候,出现了错误的结果。

    我用一张220x220的图片作为输入,在将之长宽各放大2倍的时候,我发现结果图片尺寸是变了,但是除了220x220的区域,其余区域都是黑的,以及还有一些不太有规    则的像素点。于是我尝试改变了输入的参数,甚至改变了输入图片,发现结果都是一样的。

    

    (输入图片)

 

    2.3发现过程

    我当时第一个感觉是我的算法写错了,于是花了好多时间,反复验证我的图像计算矩阵变换的算法逻辑有没有出现漏洞,甚至用不同的方法去实现双立方插值的算法,然后    而无论我怎么验证修改,结果还是类似的错,大片的黑。

    由于图像变换前后像素是由对应关系的,所以我又对出错的图片反复地进行了对比,发觉在放缩后的图像的(2x,2y)的坐标的像素,对应的似乎不是(x,y),所以才    会导致220x220的位置有一样大小的图像,而其他区域都是黑的。所以我认为是逻辑上出了错,于是我在像素对应相应的计算的循环发现了错误——一个令我想破头也想    不到的错误,似乎是多写了一个分号(或者是别的,记不太清了),于是导致我的循环逻辑上出了错。

    源代码(部分)如下:

    

    就在for的那两行,一个微小的失误,花费了我很多精力。

 

    2.4总结原因

    我认为出现这种失误有两个原因:

      1)自己在写代码的时候的失误,粗心,这似乎不太避免,毕竟总会有手错的时候

      2)新接触的Matlab语法和大部分先前学习过的编程语言有点不同,就比如这个for循环,C++,JAVA中的for循环都会有括号,更有边界性不容易出错,也更容易发        现,然而Matlab中的for循环只需要空格,比较容易失误

 

    2.5教训经验

      1)逻辑错误很关键,不容易发现,会让人很头疼

      2)在遇到bug的时候更需要冷静分析,从结果形成的过程中逐步分析,找出原因

      3)不同的测试用例可以帮你快速找到出错的地点

 

  这就是令我印象比较深刻的一个编程中遇到的bug以及解决的过程。

%B的逆矩阵

Br = B^-1;

%for循环对新图每个像素插值

for i = 1:nn

    ii = (i-1)/h+1;

    iip = ii - fix(ii);

    for j = 1:mm

        %新图对应旧图的点的坐标

        jj = (j-1)/w+1;

        jjp = jj - fix(jj);

        %得到在旧图中落在的像素方块中的左上角的点的坐标

        x = floor(ii)+1;

        if x > n

            x = n;

        end

        if x < 2

            x = 2;

        end

        y = floor(jj)+1;

        if y > m

            y = m;

        end

        if y < 2

            y = 2;

        end

        %设置Y,获得16个点的像素值

        Y = [I(x-1,y-1),I(x-1,y),I(x-1,y+1),I(x-1,y+2),I(x,y-1),I(x,y),I(x,y+1),I(x,y+2),I(x+1,y-1),I(x+1,y),I(x+1,y+1),I(x+1,y+2),I(x+2,y-1),I(x+2,y),I(x+2,y+1),I(x+2,y+2)]';

        %设置b

        B = [iip^3*jjp^3,iip^3*jjp^2,iip^3*jjp^1,iip^3*jjp^0,iip^2*jjp^3,iip^2*jjp^2,iip^2*jjp^1,iip^2*jjp^0,iip^1*jjp^3,iip^1*jjp^2,iip^1*jjp^1,iip^1*jjp^0,iip^0*jjp^3,iip^0*jjp^2,iip^0*jjp^1,iip^0*jjp^0];

        %代入公式计算目标像素值

        o(i,j) = b*Br*C*Y;

    end

end