类似horizon效果的实现

        最近小项目中需要解决一些抗锯齿的问题,刚接触这个的时候查了很多资料,这里特别感觉一个朋友,谢谢他在我解决这个问题的时候给予的建议与帮助。

        在horizon App中,屏幕中的矩形框随着手机的角度而不停的变换,但是矩形框在某些角度下会产生明显的锯齿,会影响显示效果。采取两种方案解决锯齿问题。

方案1:opengl的简单实现,刚接触opengl,对一些api不是很熟,在PC端单间做了一下测试:

       1)code如下:    

float width = 1.0;
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glLineWidth(width);

glBegin(GL_LINE_LOOP);
glVertex3f(0, 0.0198, 0.0) ;
glColor3f(1.0,1.0,1.0);
glVertex3f(0.0301, 0.9877, 0.0) ;
glColor3f(1.0,1.0,1.0);
glVertex3f(1.0, 0.9802, 0.0) ;
glColor3f(1.0,1.0,1.0);
glVertex3f(0.9699, 0.01031, 0.0) ;
glColor3f(1.0,1.0,1.0);
glEnd();

glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
glFlush();//先画矩形框的四个边界(这个是在测试过程中)


glColor3f(1.0,1.0,1.0);
glBegin(GL_QUADS);
glVertex3f(0, 0.0198, 0.0) ;
glVertex3f(0.0301, 0.9877, 0.0) ;
glVertex3f(1.0, 0.9802, 0.0) ;
glVertex3f(0.9699, 0.01031, 0.0) ;
glEnd();//画矩形框
       在实际的测试中,如果没有画出无锯齿的矩形框而直接画出填充的矩形,这样锯齿是解决不了的。

       但是这个没有在android端实现,gl_line_smooth在android端没有效果,可能自己没有用对。有在网上查到用FBO,这个需要在3.0以上的版本上才可以用,而且很复杂,没有进行深入的查阅。

      2)效果图:

     

方案2:抗锯齿的边界算法

    抗锯齿这里主要用了融合的原理,当处于当前直线点的像素值的时候,融合底层像素值与直线像素的值。

    在图像中,先根据旋转角度求取出矩形框在图像中的四个顶点,求出四条直线的函数方程。抗锯齿的过程如下:

    1.根据直线方程以及点到直线的距离判断点在矩形框内的分布情况;

    

    2.若当前设置的矩形边界宽度为W,当点到直线的距离小于W/2的时候就认为当前点是直线上的点,距离大于W/2的时候根据点的分布情况设置矩形内外的值。 

       当直线距离小于W/2的时候,进行融合过程处理。

       融合值主要是由距离的exp获取,当距离越大的时候权值越低,exp函数又可以达到平滑的效果。

方案2:抗锯齿的边界算法优化

     无需判断点在矩形分布的内外情况。

     1. 反向插值。当前的旋转矩形框放大到原始尺寸的大小,并进行旋转到原始方向,若当前点经过反向插值以后不再原始框的区域内,说明此点不在旋转的矩形框内,若在的话说明此点在旋转的矩形框内(如下所示)。

     2. 距离计算。最原始的时候:点到直线的距离是计算点到四条旋转曲线的距离。而当前算法中:点到直线的距离,四条直线是不会变换的,就是原始矩形框的四条边界。

     3. 融合过程。上一方案的融合过程类似。

    这一方案的关键code如下:

    rstData = zeros(m,n,k);//结果像素
    linew = 1;//线宽
    lineData = ones(1,1,3) * 255;//线的像素
    for j = 1:m
        for i = 1:n   //遍历图像像素
            trans_before = [i;j;1];
            trans_end1 = S * trans_before + T;
            trans_end1 = R * (trans_end1 - T1) + T1;  //S、T、R仿射矩阵
            y = trans_end1(2);x = trans_end1(1);

            dis = min( min(y,m - y),min(x,n-x));
            ap = abs(abs(dis)) /f/linew ;
            a = exp(-1.0 *  ap^2);
            a = sqrt(a);
            y = round(y);x = round(x);
             if y < 0 | y > m | x < 0 | x > n
                rstData(j,i,:) = lineData * a + Image(j,i,:) * 0.4 * (1 - a);
             else
                rstData(j,i,:) = lineData * a + Image(j,i,:) * (1 - a);
             end//融合处理过程
        end
    end
    figure,imshow(uint8(rstData));
        效果图如下:

           

方案2、3效果上可能与opengl的效果有些差别,但是已经很好的去除了锯齿。

猜你喜欢

转载自blog.csdn.net/anan1205/article/details/45127883