算法调优记录

1.双线性插值

2.平方插值

if ((sub_a_b>Th_value) && dx <= 0.5)
    k1_dx = 2*(dx ^ 2);
elseif ((sub_a_b>Th_value) && dx > 0.5)
    k1_dx = -2*((dx-1)^2)+1;
elseif (sub_a_b <= Th_value) 
    k1_dx = dx;
end

3.分段函数插值法

for k= 2:1:5;
    for a= (0.5-(0.5/k)):0.1:0.5;
        
        if ((sub_a_b>Th_value) && dx <= a)
            k1_dx = (k-(k/(2*a))+(0.5/a))*dx;
        elseif ((sub_a_b>Th_value) && dx > a && dx < 1-a)
            k1_dx = k*(dx-0.5)+0.5;
        elseif ((sub_a_b>Th_value) && dx >= 1-a)
            k1_dx = (k-(0.5*k/a)+(0.5/a))*(dx-1)+1;
        elseif (sub_a_b <= Th_value) 
            k1_dx = dx;
        end

    end
end

针对上述对应关系,n=6,8,10时,k,a组合方针效果最好
说明对于一个特定的k值而言,a越小越好

  • k=1 a=0



  • k=2 a=0.2500



  • k=3 a=0.3333



  • k=4 a=0.3750



  • k=5 a=0.4000



  • k=6 a=0.4167



  • k=7 a=0.4286



  • k=8 a=0.4375



4.PS梯形矫正坐标变化

矫正值 缩放比例 左上角坐标 右上角坐标
2 99 4,2 内容
4 97 15,8 内容
6 96 19,11 内容
8 95 30,16 内容
10 93 41,23 内容
12 92 45,25 内容
14 91 55,31 内容
16 90 60,34 内容
18 88 71,40 内容

5.摩尔纹的根本原因

图像出现摩尔纹的根本原因是单像素直线在发生旋转时,势必会出现像素错位,下图中的黑白条纹图中,以从左边为起点的一条黑条纹为例。它会在中间某个位置渐变为白色,我把它称之为渐变区。从上至下所有的渐变区域连在一起就会形成摩尔纹。单条摩尔纹的宽度由渐变区的宽度决定,摩尔纹的密度由线条倾斜的角度决定。




所以对于单像素线条(极窄线条)而言,摩尔纹是无法避免的,而且线条的倾斜角度也是无法控制的,所以我们能做的就是缩短渐变区的宽度。但是缩短渐变区的宽度会带来图像锯齿化现象的加剧。因为线条没有那么平滑了。所以我们需要分情况考虑。这里我需要提到一点渐变区的宽度还决定于插值区四个点像素值的变化率。如果某个区域像素值的变化率过大,类似于我们这里的黑白条纹区域(像素要么是0要么是255),那么此时容易造成较大的渐变区。这时我们采用权重变化陡峭的插值法来缩短渐变区的宽度。如果某个区域的像素变化率不大,那么我们就采用更平滑的标准双线性插值。来得到较为平滑的图像。

个人认为没有必要过分较真单像素线的摩尔纹现象,更应该关注实际图像的显示效果

投影测试

在投影上做测试,感觉投影仪的显示效果和笔记本电脑不太一样。对于不做gamma处理的图片笔记本电脑上有很明显的摩尔纹,但是在投影仪上打出来的效果看着就没有摩尔纹。所以我得出结论,由于每一块display的性能都有差异。显示效果也会有差。这主要是不同屏幕的gamma值不同导致的。

定点数调试1 (分辨率215*212 shift=50)

fraction_len 坐标2 坐标3 坐标4
golden 214,50 0,161 164,211
5 210,51 4,158 165,209
6 212,52 2,160 163,211
7 214,50 0,160 165,211
8 214,50 0,161 164,211
9 214,50 0,161 164,211

定点数调试2 (分辨率1920*1080 shift=50)

fraction_len 坐标4
golden 1870,1080
8 1913,1074
9 1918.9,1077.2
10 1919.9,1079
11 1919.9,1079
12 1919.9,1079.8
13 1919.9,1079.8

调试日志

当fraction_len=20 , word_len=32时,其他图片都正常,circle_keystone4不正常

num2fixpt函数超过表示范围将变为负数或者0.但是fi函数不一样,fi函数转化定点数,若待转化值小于最小精度,那么转化值截断为最小精度。若待转化值大于最大表示范围,那么转化值将截断为能表示的最大数.

建议不要使用num2fixpt,建议使用fi函数。使用fi函数以后inv_pos可以计算的很精准

  • fi函数转换checker.jpg生成7张图耗时 10min 43s
  • num2fixpt函数转换checker.jpg生成7张图耗时 1min43秒

不过当fraction_len小于5时,使用num2fixpt函数来转换checker.jpg,生成的图像会有严重的变形


num2fixpt与fi 误差和比较

fraction_len num2fixpt fi
8 1913,1074
9 1918.9,1077.2
10 1919.9,1079
11 1919.9,1079
12 1919.9,1079.8
13 1919.9,1079.8

w值范围

经过统计正确的w值全部落在 1<w<=1.1 范围内,不在此范围内的w值计算出的结果不在1920*1280范围内

下图表示
在1<=w<2时有10322848个点

双精度浮点数跑出来的结果(0.9<w<1.15)base=0.9 incr=0.05


8/16

在跑keystones2的时候会出现小于1的w
首先介绍双精度
然后介绍定点化

8/27

随机验证k=0:100(base=0.9 incr=0.05)


随机验证k=0:500(base=0.9 incr=0.05)


把范围暂且定为0.875 < w <1.250;

8/28

move_points是以下的点时会有异常情况出现



此时i=1023,j=1920.计算结果如下:w=0.89997767


VCS仿真测试事项:

  • 两个低位宽数做乘法是否需要做位扩展

比如8位数a乘8位数b然后右移8位,结果赋值给一个8位数c。结果是否会被截断为0
结果会被截断,可以使用如下方法;

reg [7:0] a,b,c;
wire [15:0] tmp;
assign tmp = (a*b)>>8;
always @(posedge i_clk)
begin 
  c <= tmp;
end
  • 有符号数乘法测试

8位有符号数a 乘 8位无符号数b 。如果不对b做有符号转化,结果如何
结论:不能对有符号的负数做>>或者是<<操作。因为作该操作。编译器都会补0.举个例子。

reg signed  [7:0]  a = -64(0xc0);
a = a>>1;

做了移位操作后,a=96(0x60).
不过可以自行做位操作

reg signed  [7:0]  a = -64(0xc0);
a = {1'b1,a[7:1]};

此时操作后a=-32

  • 一种合适的有符号数移位方式

reg signed [7 :0] a;
reg signed [7 :0] b;
reg signed [15:0] c;
reg signed [15:0] c_tmp;
reg signed [7 :0] d;

initial begin 
    a = -8'd64;
    b = -8'd8;
    c = a*b;
    c_tmp = {{3{c[15]}},c[15:3]};
    d = c_tmp;
end

output :
c = -512;
c_tmp=-64;
d = -64;  

8/30 待解决的问题

  • W查找表超过上下限的处理
  • dut 计算z_tmp需要使用更宽的位宽

9/3

第1920行的数据MATLAB和SV计算结果不同

line matlab SV
9601 -225928 -204278 -234120 -212471

重大BUG

修正前

如果给w_rpl的数据类型定义为无符号数,那么仿真结果会和实际不符

        logic signed [WLEN-1     :0] uw_tmp;
        logic signed [WLEN-1     :0] vw_tmp;
        logic signed [WLEN+FLEN-1:0] u_tmp,u_tmp_ref ;
        logic signed [WLEN+FLEN-1:0] v_tmp,v_tmp_ref ;
        int x,y;
        logic signed [WLEN+COORD_LEN-1:0] w_tmp1;
        logic signed [WLEN+COORD_LEN-1:0] w_tmp2;
        logic        [WLEN-1          :0] w     ;
        logic        [WLEN-1          :0] w_rpl ; //w_reciprocal

            uw_tmp             = a11*x+a12*y+a13;
            vw_tmp             = a21*x+a22*y+a23;
            w_tmp1             = a31*x;
            w_tmp2             = a32*y;
            w                  = {{(HIGH_FLEN-FLEN){w_tmp1[WLEN+COORD_LEN-1]}},w_tmp1[WLEN+COORD_LEN-1:HIGH_FLEN-FLEN]}+{{(HIGH_FLEN-FLEN){w_tmp2[WLEN+COORD_LEN-1]}},w_tmp2[WLEN+COORD_LEN-1:HIGH_FLEN-FLEN]}+a33;
            w_rpl              = w_lut(w[FLEN:0]);
            u_tmp              = uw_tmp*w_rpl;
            v_tmp              = vw_tmp*w_rpl;
            u_tmp_ref          = -225983*4095;
            v_tmp_ref          = -204328*4095;

预期是u_tmp_ref,实际计算是u_tmp。二者不符


修正后

将w_rpl修改为signed类型。仿真结果符合预期

        logic signed [WLEN-1     :0] uw_tmp;
        logic signed [WLEN-1     :0] vw_tmp;
        logic signed [WLEN+FLEN-1:0] u_tmp,u_tmp_ref ;
        logic signed [WLEN+FLEN-1:0] v_tmp,v_tmp_ref ;
        int x,y;
        logic signed [WLEN+COORD_LEN-1:0] w_tmp1;
        logic signed [WLEN+COORD_LEN-1:0] w_tmp2;
        logic        [WLEN-1          :0] w     ;
        logic signed [WLEN-1          :0] w_rpl ; //w_reciprocal

            uw_tmp             = a11*x+a12*y+a13;
            vw_tmp             = a21*x+a22*y+a23;
            w_tmp1             = a31*x;
            w_tmp2             = a32*y;
            w                  = {{(HIGH_FLEN-FLEN){w_tmp1[WLEN+COORD_LEN-1]}},w_tmp1[WLEN+COORD_LEN-1:HIGH_FLEN-FLEN]}+{{(HIGH_FLEN-FLEN){w_tmp2[WLEN+COORD_LEN-1]}},w_tmp2[WLEN+COORD_LEN-1:HIGH_FLEN-FLEN]}+a33;
            w_rpl              = w_lut(w[FLEN:0]);
            u_tmp              = uw_tmp*w_rpl;
            v_tmp              = vw_tmp*w_rpl;
            u_tmp_ref          = -225983*4095;
            v_tmp_ref          = -204328*4095;

9/4

调试中发现SV计算结果有时候会和MATLAB计算结果相差1,这是负数做移位时出现的,如果被移位部分非0,那么就会出现这种现象。补码负数和正数的截断产生了这个差异。如果没有被移位部分为0则不会有这个差异
案例如下:

logic signed [7:0] a,b,c,d;
logic [7:0] x,y,z;
initial begin 
    a=-60;
    b= 60;
    c={{3{1'b1}},a[7:3]};
    d={{3{1'b0}},b[7:3]};
    $display("a=%0d(%8b) b=%0d(%8b) c=%0d(%8b) d=%0d(%8b)",a,a,b,b,c,c,d,d); 
end

输出如下:



计算Eason发给我的图片

Eason给我的图片分辨率均是1080*1920。当high_flen=18时,keystone1底部对的不齐。故我将high_flen设置为19

9/5


仿真时会把x态视为真,所以在仿真中一定要把控制信号的复位做好

9/6

坐标变化规律

  • 对于横坐标而言,在shrink的畸变下,横坐标每10个incr会出现一次+2
  • 对于纵坐标而言,在rotate畸变下,1920x1080图片每36个incr会出现一次+2,1080x1920图片每20个incr会出现一个+2

各种情况的统计,每一行的求和为2073600


10/8

仿真证明在下式中,括号中的内容出现负值也不会对最终结果产生影响。与结果与预期一致
o_sram_addr <= BASE_ADDR + (i_coord_v[WLEN-1:FLEN] - i_coord_y)*1920 + i_coord_u[WLEN-1:FLEN];

10/15

对matlab
i =100 j = 100
inv_x_fix = 225803 inv_y_fix=225902
x1 = 55, y1 = 55
x2 = 56 , y2 = 56
dx = 523 , dy = 622
target_img(i,j,2) = 222

对vcs
i = 100 , j = 100


matlab和SV的控制点移动是不一样的

10/16


当i=0 , j=53时 ,计算pixel_value有点问题

当 4个点的像素都是255时,插值的结果竟然是253,这个精度很有问题


改了之后,像素值变为了254。可以接受

结果有问题

  • matlab


  • vcs
    i = 100, j=47


结果有问题

96053 ---- i=50 j=52


  • matlab
    inv_x_fix = 8605 inv_y_fix = 16
    x1 = 2 y1 = 0
    x2 = 3 y1 = 1
    dx = 413 dy = 16 sub_dx = 3683 sub_dy = 4080
    value_a = 255 value_b=255 value_c = 0 value_d = 255
  • vcs


(49,71)与(49,70)梯度太大


造成上述结果的原因是边界条件处理的不好。

修改前

                if ( inv_x1 > 1919) 
                    flag_x1 = 1;
                end

                if ( inv_x2 > 1919 )
                    flag_x2 = 1;
                end

                if ( inv_y1 > 1079 ) 
                    flag_y1 = 1;
                end

                if ( inv_y2 > 1079 ) 
                    flag_y2 = 1;
                end

修改后

               if ( inv_x1 > 1919 | inv_x1 <= -1) 
                    flag_x1 = 1;
                end

                if ( inv_x2 > 1919 | inv_x2 <= -1)
                    flag_x2 = 1;
                end

                if ( inv_y1 > 1079 | inv_y1 <= -1) 
                    flag_y1 = 1;
                end

                if ( inv_y2 > 1079 | inv_y2 <= -1) 
                    flag_y2 = 1;
                end

10/17


96051: i=50 j=50

keystone1没问题了,但是后面得有问题

keystone2


mul_a, mul_b等变量只给FLEN位宽不够。应该给FLEN+1位宽。


1923 i=1 j=2

keystone3


1889: i=0 j=1888

  • vcs


10/22

flag_pixel_reg在赋值时做了一些修改

always @(posedge i_clk or negedge i_rst_n)
begin 
    if (!i_rst_n) begin 
        flag_pixel_reg <= 1'b0; 
    end else if (hsync_2d && v1 == v1_1d+1 && flag_sram && ~flag_sram_1d) begin  //flag_sram_1d must be 1
        flag_pixel_reg <= 1;
    end else if (hsync_2d && v1 == v1_1d-1 && ~flag_sram && flag_sram_1d) begin 
        flag_pixel_reg <= 1;
    end else begin 
        flag_pixel_reg <= 1'b0;
    end
end

u1_offset在赋值时遇到了一些问题

需要考虑到当出现type 4,5,6情况,而且flag_sram ^ flag_sram_1d == 1时,那么应有如下式:
u1_offset == u1 - u1_2d;

always @(posedge i_clk or negedge i_rst_n)
begin 
    if (!i_rst_n) begin 
        u1_offset <= 3'd0;
    end else if (hsync_1d && hsync_2d && hsync_3d && v1!=v1_1d && (flag_sram ^ flag_sram_1d)) begin 
        u1_offset <= u1 - u1_2d;
    end else if (hsync_1d && hsync_2d ) begin 
        u1_offset <= u1 - u1_1d;
    end else begin 
        u1_offset <= 0;
    end
end

10/23

v1_1d未及时清零

我对RAM的要求是地址的increment为24bit数据。但是每个地址输入后,数据输出端可以输出紧连着的4个地址的96位数据

u1_offset在应用于每行第一个点时会遇到一些问题

u1_offset可能会出现等于3的情况,这样以来超出了case语句的范围

在keystone4畸变下,一共会出现8000+次的u1_offset = 3的情况
但是并没有出现u1_offset=4的情况
修改方法,需要将读数据位宽调整为24*5=120 bits

10/24

SRAM寻址方式存在问题。目前考虑使用128行line buffer。
sram_addr = i_coord_v[6:0] * 1920 + i_coord_u;

会出现coord_v连续变化的情况


u1_offset值给的不对,u1_offset长期等于2

我添加了一个cnt_v来表示连续出现v变化或者是u一次加2这种情况。cnt_v最大是4,一共出现了32次
cnt_v == 3的情况一共出现了1582次

对于一种极端情况是需要数据位宽为7*24=168才够

对于u1_offset的问题,我的解决方案是对u1_offset采用递增方案。引入sub_u1_u11d 与 flag_uoffset_add对u1_offset的赋值进行控制:

always @(posedge i_clk or negedge i_rst_n)
begin 
    if (!i_rst_n) begin 
        u1_offset <= 3'd0;
    end else if (hsync_2d && flag_uoffset_add) begin 
        u1_offset <= u1_offset + sub_u1_u11d;
    end else if (hsync_2d)begin 
        u1_offset <= sub_u1_u11d;
    end
end

修正该错误后,错误数来到了1836个

10/25

解决了所有错误,目前跑单像素黑白线条的简单案例在keystone4畸变下顺利通过

10/28

  • 对于u1=8191,v在正常范围的情况。u2为0,但是,img_distortion输出的地址是无法读取到(u2,v1),(u2,v2)点的像素值的。

10/31

11/1

  • sram_raddr的赋值有讲究。100行Line buffer

  • 定义二维数组,VCS无法仿真

  • tmp_line2_reg2 = 79ff,但是赋值给pixel_b时却变成了78ff

11/4

flag_line_reg变化早了一拍
目前遇到的问题实际上是验证环境在写pixel_ram的时候落在了计算模块读取sram的后面。读取的像素超出了50行的范围

11/5

遇到中途插入的情况,比如上一个(u1,v1)=(1126,1080) 该坐标位于范围以外
然后下一个(u1,v1)=(1127,1079) 该坐标位于合理范围内。且该坐标需要做插值时周围的4个点刚好需要在连续两个地址中读取故有问题

遇到中途插入的情况,比如上一个(u1,v1)=(1780,8191) 该坐标位于范围以外
然后下一个(u1,v1)=(1781,8191) 该坐标位于合理范围内。但是1781%8=5;所以头4组寄存器输入后,不超过2个周期,马上会输入下一组地址。但是此时上一组数据还未读出来。所以这里把上一组数据充掉,下例中连起了两个addr_en

目前使用了4行Buffer,其实也可以使用3行Buffer

11/6

对于乘常数的乘法器可以改写为下列形式:
a * 240 = a<<8 - a<<4;

11/7

自己计算的变换矩阵与MATLAB计算的变换矩阵略有差异。主要体现在a13与a23的差异。按照公式a13=x0, a23=y0。但是MATLAB计算出来的结果不符合这个规律
matlab更换了fitgeotrans函数。计算结果与我自己实现的函数得到的结果相同

11/8

测试方案
先使用matlab测试改为fit函数以及加入w_hflen后的视觉效果,然后比对matlab与VCS的计算结果。
然后给VCS加入覆盖率的测试。
仿真发现,图形的右边缘有轻微锯齿。不论是MATLAB还是vcs都有这个问题

浮点数方案
(1871,68)=118
(1871,69)=102
定点数方案
(1871,68)= 174
(1871,69)= 34

11/11

需要加入覆盖率:
我统计了1/w查找表的输入。100种畸变类型的统计结果显示,没有一个值落到查找表的范围之外
设置了coverage统计1/w查找表的输入。
设置了coverage统计控制点坐标的分布。
并且自行设置了随机种子。做验证

需要考虑一下1T4P的实现方式:
统计一下a31的分布

11/12

1000包覆盖率报告:
插值模块行覆盖率为100%
x0y0_x1y1覆盖率100%
x2y2_x3y3覆盖率100%
1/w查找表依然在范围内,小表集中在表项的11-63项。大表集中在表项的0-54项

开始统计a31的分布,step=6。一共有9^8=43046721个项.142min跑完



a31绝对值最大也就是14
所以意味着最坏的情况是可以4个点查一次表的

11/13

如果要实现1T4P那么需要我们布置4份运算器。能公用的尽量公用
明日统计一下倾斜角最大的情况下,y值连跳两下的最小间隔是多少
经过统计发现coordv最短两跳的间距是38。但是这是特殊情况。因为第57行第一个点到第二个点就发生了一次跳变。平均下来是每75个点跳两下。平均37个点跳一次
经过统计发现coordu一次跳2格的平均间距是20.

11/14

更加细化对a31的统计,一共统计了815730721次


11/18

10000次的验证结束,控制点的覆盖率如下:


查找表覆盖率:(红色部分是未覆盖的区域)



下图的红色区域一直持续到表结尾


11/19

出于最糟糕的情况考虑。在决定addr3的时候需要考虑到算上u_src那个周期的数据后第五个周期的coord_u,coord_v输入。coord_v与v_src作比较。然后判断是否需要启用第三行buffer

11/20 ——11/25

完成了插值模块的编写,以及坐标变换模块的验证

11/26

1T4P i=11 j=118时,4个pixel的值如下:


reference i=11 j=118时,4个pixel的值如下:



解决了,应该写sub_va_6d的地方写成了sub_va

  • 1T4P i=15 j=418时,4个pixel的值如下:


reference i=15 j=418时,4个pixel的值如下:


  • 1T4P i=73 j=481时,4个pixel的值如下:


reference i=73 j=481时,4个pixel的值如下:


  • 1T4P i=112 j=1279时,4个pixel的值如下:



    reference i=112 j=1279时,4个pixel的值如下:


11/27

地址产生方式不对,addr1= 127120+u时,此时addr2=addr1+120。那么addr2并不会回到sram的第一行而是addr2 = 128120+u。该地址会越界

v值跳变的问题实在难以处理


为何addr_en_line3会频繁拉高,不应该有这么高的频率


结果不匹配的数量降低到了14136

11/28

第一个247正好启动了下次sram读取



不能使用最新的坐标减初始的坐标这种方式来确定line3的读取地址。因为会出现以下这种情况。必须通过读取地址段内部的坐标来确定line3的读取地址


当我把matrix_cell中的灰阶比较从相等修改为差值小于2时,最后的结果一下子就只剩下9个不同了。而且剩下那九个灰阶差值为2

11/29

需要预知前面6个点


出现了u_a在连续四个像素中连跳两下的情况 1849-1851 1852-1854



使用了种子为563779634

12/2

temp_reg和pre_reg都多加了一组寄存器
1000次的验证顺利通过
插值模块的行覆盖率近乎100%。只有对pix_a_3 ...pix_d_3赋值时会出现下列未覆盖完全的情况


12/5

5000次验证顺利通过
将pixel_ram也改为随机,然后验证5000次

12/6

5000次验证顺利通过。坐标分布覆盖率如下所示:


12/9

明天使用迭代法计算一下系数M的范围

12/11

15000次验证顺利完成,结果合理。覆盖率数据如下:


12/16

12/18

1.平方计算如何处理
2.case语句和cache如何取舍(case分支过多,需不需要用一级缓存来改善)
\color{#FF0000}{(50,53)}
\color{#A000A0}{(1869,53)}

12/19

采用了全新的delta方案做透视变换的矫正

畸变类型 delta refer
keystone1 \color{#FF0000}{(50,53)} \color{#A000A0}{(1870,53)} (0,1079) (1919 1079) \color{#FF3030}{(50,50)} (50,50)\color{#A000A0}{(1869,53)} (0,1079) (1919 1079)
keystone2 (0,0) (1919,0)\color{#FF0000}{(50,1027)} \color{#A000A0}{ (1070,1027)} (0,0) (1919,0) \color{#FF0000}{(50,1029)} \color{#A000A0}{ (1070,1029)}
keystone3 \color{#FF0000}{(55,50)} (1919 0) \color{#A000A0}{(55,1030)} (1919 1079) \color{#FF0000}{(50,50)} (1919 0) \color{#A000A0}{(50,1029)} (1919 1079)
keystone4 (0,0)\color{#FF0000}{(1865,50)} (0,1079)\color{#A000A0}{ (1865,1030)} (0,0) \color{#FF0000}{(1869,50)} (0,1079)\color{#A000A0}{(1869,1029)}
rotate (50,0) (1919,50) (0,1030) (1870,1079) (50,0) (1919,50) (0,1029) (1869,1079)
mixed (50,51) (1900,51) (0 ,1030) (1870,1030) (50,50) (1899,50) (0 ,1029) (1869,1029)
shrink (50,50) (1870,50) (50 ,1030) (1870,1030) (50,50) (1869,50) (50 ,1029) (1869,1029)

新方案绝对可行

12/24

tform_delta.m与tform_delta_v1.m的控制点变换不太一样,(50,50)对(51,51)
原因是通过公式计算出的变换矩阵与matlab的函数计算结果不一样



我知道误差的原因了,因为我是以变换矩阵计算公式默认了起始点的坐标是(0,0)(1919,0)....
但是在tform_delta_v1.m中的起始点是(1,1)(1920,1)...

sv_model的变换矩阵计算有大问题

12/25

求1920倒数,定点数精确度与误差的关系

数值 小数位数 误差
17 15 9 pixels
1902.8 21 0.32pixel
4371.3 23 0.14 pixel

需要对1919求倒数的精度进行调整
matlab与sv_model的坐标变换结果一致(keystone1)
取1919倒数精度为小数点后21位

坐标变换模块debug成功
目前正在调试插值模块

12/26

目前的IP随机验证10次结果没问题
实际上采用这种delta的方式计算是存在系统误差的,这是因为,显示屏上的一行像素是均匀分布的,但是这行像素反向映射到原图时,得到的点虽然位于同一条直线上。但是,点的分布是不均匀的。但是可以近似看成是均匀的,因此采用delta的方式来计算

12/27

分析不同畸变图的delta-x曲线

keystone1

  • x-delta


  • y-delta


keystone2

  • x-delta


  • y_delta


keystone3

  • x-delta


keystone4

  • x-delta


rotate

  • x-delta

    data1:

    data22:
  • y_delta

    data1:

    data22:

mixed

  • x-delta


  • y-delta


12/30

引入斜率的方法不是很可靠,计算出来的图片效果非常一般

12/31

经过试验,发现inter_flen=4与inter_flen=12图片质量相同,当inter_flen<4时,图片边缘会有明显的锯齿感

  • inter_flen=1


  • inter_flen=3


  • inter_flen=4


  • inter_flen=12


这delta方案下,实际上也会出现两个像素点同处一个方块的情况。此时\Delta x=4095。我的temp_cache和pixel_a,pixel_b.pixel_c,pixel_d赋值未考虑这些。目前做了修改

调整插值模块精度

inter_flen=12到
inter_flen= 8
计算出来的像素都没问题

1/2

inter_flen=12

综合情况:


inter_flen=8

验证了10000种情况,目前有200个报错,但每个报错仅仅只有一个像素的灰阶相差2
综合情况:


inter_flen=6

1/3

inter_len=6

验证了10000种情况(设置的错误触发条件是diff>5),目前有261个报错.其中每个报错均只有一个像素异常。diff=5占据了192个,diff=6占据了10个,diff=7占据了1个。

将代码实现到VIVADO上去

1/6

waveform_trans

{signal: [
  {name: 'clk', wave: 'p.|......|...'},
  {name: 'vsync', wave: '01|......|0..'},
  {name: 'hsync', wave: '0...1....|0..'},
  {name: 'de', wave: '0...1....|0..'},
  {name: 'delta_v1_x', wave: '3........|...', data: ['Δx_v1']},
  {name: 'delta_v2_x', wave: '3........|...', data: ['Δx_v2']},  
  {name: 'x_a_ini', wave: '5........|...', data: ['xa_0']},
  {name: 'x_b_ini', wave: '5........|...', data: ['xb_0']},  
  {},
  ['pre_stage',
    {name: 'x_head', wave: '6.6......|.6.', data: ['0' ,'xa_0','xa_0+Δx_v1']}, 
    {name: 'x_tail', wave: '6.6......|.6.', data: ['0' ,'xb_0','xb_0+Δx_v2']},
    {name: 'delta_h_x', wave: '7..7.....|..7', data: ['0' ,'Δx=(xb_0-xa_0)/1920','Δx1']},   
   ],
   {},
   ['stage 0',
    {name: 'u1', wave: '8....8888|..', data: ['0' ,'xa_0','xa_0+4Δx','xa_0+8Δx']}, 
    {name: 'u2', wave: '8....8888|..', data: ['0' ,'xa_0+Δx','xa_0+5Δx','xa_0+9Δx']},
    {name: 'u3', wave: '8....8888|..', data: ['0' ,'xa_0+2Δx','xa_0+6Δx','xa_0+10Δx']},  
    {name: 'u4', wave: '8....8888|..', data: ['0' ,'xa_0+3Δx','xa_0+7Δx','xa_0+11Δx']},
   ],
],
  config: { hscale: 2 }
  }

waveform_inter

{signal: [
  {name: 'clk', wave: 'p.............'},
  {name: 'vsync', wave: '01............'},
  {name: 'hsync', wave: '0.1...........'},
  {name: 'de', wave: '0.1...........'},
 [ 'stage0',
  {name: 'coord_u[4*21-1:0]', wave: '7.77777777....', data: ['0' ,'coord_u1','coord_u2','coord_u3','coord_u4','coord_u5','coord_u6','coord_u7']},
  {name: 'u1_a[12:0]', wave: '8..88888888...', data: ['0' ,'-6','-2','2','6','10','14','18']}, 
  {name: 'u2_a[12:0]', wave: '8..88888888...', data: ['0' ,'-5','-1','3','7','11','15','19']},
  {name: 'u3_a[12:0]', wave: '8..88888888...', data: ['0' ,'-4','0','4','8','12','16','20']},  
  {name: 'u4_a[12:0]', wave: '8..88888888...', data: ['0' ,'-3','1','5','9','13','17','21']},  
  {name: 'coord_v[4*21-1:0]', wave: '7.77777777....', data: ['0' ,'coord_v1','coord_v2','coord_v3','coord_v4','coord_v5','coord_v6','coord_v7']},
  {name: 'v1_a[12:0]', wave: '8..88888888...', data: ['0' ,'50','50','50','50','50','51','51']}, 
  {name: 'v2_a[12:0]', wave: '8..88888888...', data: ['0' ,'50','50','50','50','50','51','51']},
  {name: 'v3_a[12:0]', wave: '8..88888888...', data: ['0' ,'50','50','50','50','50','51','51']},  
  {name: 'v4_a[12:0]', wave: '8..88888888...', data: ['0' ,'50','50','50','50','50','51','51']},  
  ],
  {},
 ['stage1' ,{name: 'flag_start', wave: '0....1........'},],
  {},
 ['stage2', 
  {name: 'addr_en', wave:'0.....1.0.1..0'},
  {name: 'u_src[12:0]',wave:'9.........9...',data:['0','16']},
  {name: 'v_src[12:0]',wave:'9.....9...9...',data:['0','50','51']},
  {name: 'pre_v_offset[1:0]',wave:'9.........9...',data:['0','1']},
 ],
  {},
  ['stage3',
   {name:'sram_addr[13:0]',wave:'3......33..333',data:['0','addr1','addr2','addr1','addr2','addr3']},
   {name: 'sram_web', wave:'0......1.0.1..'},
   {name:'u_a_offset[4:0]',wave:'3.....33333333',data:['0','-6','-2','2','6','10','-2','2']},
   {name:'v_a_offset[1:0]',wave:'3.............',data:['0']}
 ],
],
  config: { hscale: 2 }
  }

1/8

img_distortion_v3 (插值模块流水线深度降低为10)

1/9


1/10

对4个顶点的第一个顶点做一个统计,偏差如下,2 pixel以内的偏差是97%


25位乘法器面积

25位除法器

25位加法器

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容