几何滤镜比较简单,不涉及色彩模型,按照某种算法,对原图进行采样,得到一张新的图片。看起来就像是把原图进行了几何变形。 这篇文章通过两个简单的案例,更直观的感受几何滤镜的实现--哈哈镜。
对(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; }
哈哈镜效果
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句