美文网首页
照片处理-几何滤镜实现哈哈镜

照片处理-几何滤镜实现哈哈镜

作者: 天叔 | 来源:发表于2020-11-03 23:52 被阅读0次

    一、什么是几何滤镜

    几何滤镜比较简单,不涉及色彩模型,按照某种算法,对原图进行采样,得到一张新的图片。看起来就像是把原图进行了几何变形。
    这篇文章通过两个简单的案例,更直观的感受几何滤镜的实现--哈哈镜。

    二、处理流程

    1. 原图输入
    2. 定义变形算法,更准确点说是采样算法
    3. 遍历原图中所有像素,按照2步进行坐标变换原坐标(x1, y1) -->(x2, y2)
    4. 按照变换后的坐标采样得到像素new_rgb,并填充到原坐标(x1,y1)上

    三、凸镜效果


    对(x1, y1)处的点,重新采样,往图像中心采样,最后就是围绕中心放大的效果

    对点(CX, CY)进行处理,(x, y)是凸镜中心, R是凸镜效果半径,半径外不生效


    可以这么理解:当dis == R时,像素的值不变,当dis < R (CX, CY)变小,即对里采样,而且(CX, CY)越靠近凸镜中心,变化越剧烈

    实现源码:

    int f_ ConvexMirrorFilter(unsigned char* srcData, int width, int height, int stride, int x, int y, int k)
    {
        x = CLIP3(x, 0, width - 1);
        y = CLIP3(y, 0, height - 1);
        k = MAX2(k, 0);
        int radius = 0;
        float theta = 0;
        int tX = 0;
        int tY = 0;
        int mapX = 0;
        int mapY = 0;
        int mapR = 0;
        unsigned char* pSrc = srcData;
        unsigned char* tempData = (unsigned char*)malloc(sizeof(unsigned char) * height * stride);
        memcpy(tempData, srcData, sizeof(unsigned char) * height * stride);
        int offset = stride - width * 4;
        for(int j = 0; j < height; j++)
        {
            for(int i = 0; i < width; i++)
            {
                tX = i - x;
                tY = j - y;
                radius = k;;
                float distance = (i - x) * (i - x) + (j - y) * (j - y);
                float dis = sqrt(distance);
                if(distance <= k * k && distance > 0)
                {
                    mapX = floor(dis * (i - x) / k + x);
                    mapY = floor(dis * (j - y) / k + y);
                    pSrc[0] = tempData[mapX * 4 + mapY * stride];
                    pSrc[1] = tempData[mapX * 4 + mapY * stride + 1];
                    pSrc[2] = tempData[mapX * 4 + mapY * stride + 2];
                }
                pSrc += 4;
            }
            pSrc += offset;
        }
        free(tempData);
        return 0;
    }
    

    四、凹镜

    凹镜的原理相似,向外采样,坐标越靠近凹镜中心,向外的偏移量越大。计算稍微复杂点:
    要处理的点:(CX, CY)
    凹镜半径:K
    处理后的点:(X', Y')


    代码实现:

    int f_ConcaveMirrorFilter(unsigned char* srcData, int width, int height, int stride, int x, int y, int k)
    {
        x = CLIP3(x, 0, width - 1);
        y = CLIP3(y, 0, height - 1);
        k = MAX2(k, 0);
        int radius = 0;
        float theta = 0;
        int tX = 0;
        int tY = 0;
        int mapX = 0;
        int mapY = 0;
        int mapR = 0;
        unsigned char* pSrc = srcData;
        unsigned char* tempData = (unsigned char*)malloc(sizeof(unsigned char) * height * stride);
        memcpy(tempData, srcData, sizeof(unsigned char) * height * stride);
        int offset = stride - width * 4;
        for (int j = 0; j < height; j++)
        {
            for (int i = 0; i < width; i++)
            {
                tX = i - x;
                tY = j - y;
                theta = atan2((float)tY, (float)tX);
                radius = (int)sqrt((float)(tX * tX + tY * tY));
                mapR = (int)(sqrt((float)radius * k));
                mapX = CLIP3(x + (int)(mapR * cos(theta)), 0, width - 1);
                mapY = CLIP3(y + (int)(mapR * sin(theta)), 0, height - 1);
                pSrc[0] = tempData[mapX * 4 + mapY * stride];
                pSrc[1] = tempData[mapX * 4 + mapY * stride + 1];
                pSrc[2] = tempData[mapX * 4 + mapY * stride + 2];
                pSrc += 4;
            }
            pSrc += offset;
        }
        free(tempData);
        return 0;
    }
    
    哈哈镜效果

    相关文章

      网友评论

          本文标题:照片处理-几何滤镜实现哈哈镜

          本文链接:https://www.haomeiwen.com/subject/xekwvktx.html