图像滤镜处理算法:柔化、光照、放大镜、哈哈镜

图像滤镜处理算法:柔化、光照、放大镜、哈哈镜1 柔化算法柔化算法的效果是让图片的每一个点与周围点的颜色更平滑 算法原理很简单 就是针对每一个像素 将其颜色值置为周围 8 个点加上自身的 RGB 的平均值

大家好,欢迎来到IT知识分享网。

1 柔化算法
柔化算法的效果是让图片的每一个点与周围点的颜色更平滑,算法原理很简单,就是针对每一个像素,将其颜色值置为周围8个点加上自身的RGB的平均值。不过这样处理后的效果不是很明显,可以采用高斯模糊算法,能获取更好的效果。

原图如下:
图像滤镜处理算法:柔化、光照、放大镜、哈哈镜

采用平均值法的柔化算法处理结果如下:
图像滤镜处理算法:柔化、光照、放大镜、哈哈镜

2 光照
有时需要在照片中增加一个光源这样的效果,如何实现呢?

首先我们设定一个光源中心坐标和光照强度,然后以此光源和图片边缘的最短距离为半径,依次为每个点的RGB增加一个同样的值,当然,图片上的点距离光源中心越远,则增加的颜色值越小,通过这样的方法,就能够实现光照的效果了。

原图如下:
图像滤镜处理算法:柔化、光照、放大镜、哈哈镜
光照处理效果如下:
图像滤镜处理算法:柔化、光照、放大镜、哈哈镜

3 放大镜
前面介绍过通过坐标变换矩阵来缩放、旋转图片的方法,这里通过直接操作图像数据来实现图像的局部放大功能。

假如我们定义放大镜的坐标为(CenterX,CenterY),半径为Radius,而放大倍数为M = 2,那么其实就是将原图中的坐标为(CenterX,CenterY)、半径为Radius/M的区域的图像放大到放大镜覆盖的区域即可,算法其实很简单,对图片上的每一个点(X,Y),求其与(CenterX,CenterY)的距离Distance,若Distance < Radius,则取原图中坐标为(X/M,Y/M)的像素的颜色值作为新的颜色值。

处理效果如下:
图像滤镜处理算法:柔化、光照、放大镜、哈哈镜

代码如下:

jintArray Java_com_spore_meitu_jni_ImageUtilEngine_toFangdajing (JNIEnv* env,jobject thiz, jintArray buf, jint width, jint height,jint centerX, jint centerY, jint radius, jfloat multiple) { jint * cbuf; cbuf = (*env)->GetIntArrayElements(env, buf, 0); int newSize = width * height; jint rbuf[newSize]; // 新图像像素值 float xishu = multiple; int real_radius = (int)(radius / xishu); int i = 0, j = 0; for (i = 0; i < width; i++) { for (j = 0; j < height; j++) { int curr_color = cbuf[j * width + i]; int pixR = red(curr_color); int pixG = green(curr_color); int pixB = blue(curr_color); int pixA = alpha(curr_color); int newR = pixR; int newG = pixG; int newB = pixB; int newA = pixA; int distance = (int) ((centerX - i) * (centerX - i) + (centerY - j) * (centerY - j)); if (distance < radius * radius) { // 图像放大效果 int src_x = (int)((float)(i - centerX) / xishu + centerX); int src_y = (int)((float)(j - centerY) / xishu + centerY); int src_color = cbuf[src_y * width + src_x]; newR = red(src_color); newG = green(src_color); newB = blue(src_color); newA = alpha(src_color); } newR = min(255, max(0, newR)); newG = min(255, max(0, newG)); newB = min(255, max(0, newB)); newA = min(255, max(0, newA)); int modif_color = ARGB(newA, newR, newG, newB); rbuf[j * width + i] = modif_color; } } jintArray result = (*env)->NewIntArray(env, newSize); (*env)->SetIntArrayRegion(env, result, 0, newSize, rbuf); (*env)->ReleaseIntArrayElements(env, buf, cbuf, 0); return result; }

4 哈哈镜
哈哈镜就是各种千奇百怪的扭曲效果,其实上面的放大镜不是真正的放大镜效果,大家都知道使用凹凸镜时看到的图像其实是有扭曲效果的,因为放大镜并不是一个平滑的镜面,而是越靠经中心的点放大倍数越大,靠近边缘的点放大倍数越小,这样就形成了扭曲的效果,这个效果和哈哈镜比较类似。

于是,我们可以改进上面的放大镜算法来实现一个简单的哈哈镜的扭曲效果,注意放大算法中这两行代码:

int src_x = (int)((float)(i - centerX) / xishu + centerX); int src_y = (int)((float)(j - centerY) / xishu + centerY); 

这就是计算新的颜色值与原图中像素对应坐标的,从这里可以看出,这种方式是简单的根据放大系数等比例的缩放坐标值,即Y = X / M,由于是一元的关系,因此只能实现平滑的缩放的效果,我们应该使用一种二元或者其他的计算方法,使得放大系数与距离成反比。

这是我想到的一种比较简单的方法,是通过抛物线的二项表达式推导出来的,当然,其实效果也不是那里理想,不过好歹能看出扭曲的效果了。不得不感慨当年高数应该好好学习的啊!

将上面的代码替换成下面:

// 放大镜的凹凸效果 int src_x = (int) ((float) (i - centerX) / xishu); int src_y = (int) ((float) (j - centerY) / xishu); src_x = (int)(src_x * (sqrt(distance) / real_radius)); src_y = (int)(src_y * (sqrt(distance) / real_radius)); src_x = src_x + centerX; src_y = src_y + centerY; 

现在处理后的效果如下:

图像滤镜处理算法:柔化、光照、放大镜、哈哈镜

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/141809.html

(0)
上一篇 2025-05-14 19:00
下一篇 2025-05-14 19:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信