前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >照片处理-几何滤镜实现哈哈镜

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

作者头像
公号sumsmile
发布2020-11-12 11:27:22
1.2K0
发布2020-11-12 11:27:22
举报

一、什么是几何滤镜

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

二、处理流程

  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)越靠近凸镜中心,变化越剧烈

实现源码:

代码语言:javascript
复制
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')

代码实现:

代码语言:javascript
复制
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;
}

哈哈镜效果

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、什么是几何滤镜
  • 二、处理流程
  • 三、凸镜效果
  • 四、凹镜
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档