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