图像保边滤波算法集锦--Smart Blur算法与实现(PS2018 Smart Blur)

新版PS中有个Smart Blur的滤镜,是一个可以保留边缘的滤波器,效果如下所示:

 

这个滤波器的算法实现如下:

1,Smart Blur有两个参数:Radius和Threshold

Radius是邻域半径,Threshold是当前像素与周围像素的阈值差,范围为[0,255]

2,假设当前像素点为P(x,y),滤波结果为D,以P为中心,Radius为邻域半径,计算邻域范围内符合条件A的像素点像素值和的均值,即为M;

条件A:像素X的值在区间[P-Threshold,P+Threshold]内

3,滤波结果值D=M;

用公式表示如下:

本人代码实现如下:

#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include"f_SmartFilter.h"
#include"TRGB2YCbCr.h"
#define MIN2(a, b) ((a) < (b) ? (a) : (b))
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
#define CLIP3(x, a, b) MIN2(MAX2(a,x), b)


int SmartBlurOneChannel(unsigned char* srcData, int width ,int height, int radius, int threshold)
{	
	int len = sizeof(unsigned long) * width * height;
	int i, j;
	int gray = 0;
	unsigned char* tempData = (unsigned char*) malloc(sizeof(unsigned char) * height * width);
	memcpy(tempData, srcData, sizeof(unsigned char) * height * width);
	for(j = 0; j < height; j++ )
	{
		for(i = 0; i < width; i++)
		{
			len = i + j * width;
			gray = tempData[len];
			int low = CLIP3(gray - threshold, 0, 255);
			int high = CLIP3(gray + threshold, 0, 255);
			int sum = 0;
			int count = 0;
			for(int n = -radius; n <= radius; n++)
			{
				for(int m = -radius; m <= radius; m++)
				{
					int x = CLIP3(i + m, 0, width - 1);
					int y = CLIP3(j + n, 0, height - 1);
					int pos = x + y * width;					
					gray = tempData[pos];
					if(gray > low && gray < high)
					{
						sum += gray;
					    count++;
					}
				}
			}
			gray = count == 0 ? gray : sum / count;						
			srcData[len] = CLIP3(gray, 0, 255);
		}
	}
	free(tempData);
	return 0;
};

void f_SmartFilter(unsigned char* srcData, int nWidth, int nHeight, int nStride, int radius, int threshold)
{
	if (srcData == NULL)
	{
		return;
	}
	if(radius == 0 || threshold == 0)
		return;
	unsigned char* yData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);
	unsigned char* cbData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);
	unsigned char* crData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);
	unsigned char* pSrc = srcData;
	int Y, CB, CR;
	unsigned char* pY = yData;
	unsigned char* pCb = cbData;
	unsigned char* pCr = crData;
	for(int j = 0; j < nHeight; j++)
	{
		for(int i = 0; i < nWidth; i++)
		{

			RGBToYCbCr(pSrc[2],pSrc[1],pSrc[0],&Y,&CB,&CR);
			*pY = Y;
			*pCb = CB;
			*pCr = CR;
			pY++;
			pCb++;
			pCr++;
			pSrc += 4;
		}
	}
	SmartBlurOneChannel(yData, nWidth, nHeight, radius, threshold);
	pSrc = srcData;
	pY = yData;
	pCb = cbData;
	pCr = crData;
	int R, G, B;
	for(int j = 0; j < nHeight; j++)
	{
		for(int i = 0; i < nWidth; i++)
		{
			YCbCrToRGB(*pY, *pCb, *pCr, &R, &G, &B);
            pSrc[0] = B;
			pSrc[1] = G;
			pSrc[2] = R;
			pY++;
			pCb++;
			pCr++;
			pSrc += 4;
		}
	}
	free(yData);
	free(cbData);
	free(crData);
}




本文算法效果与PS效果对比如下:

最后在放一些效果图:

本文的DEMO连接:点击打开链接

本人QQ1358009172

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Trent1985

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值