图像处理之Mean Shift滤波(边缘保留的低通滤波)

简介: 一:Mean Shift算法介绍 Mean Shift是一种聚类算法,在数据挖掘,图像提取,视频对象跟踪中都有应用。本文 重要演示Mean Shift算法来实现图像的低通边缘保留滤波效果。其处理以后的图像有点 类似油画一样。

一:Mean Shift算法介绍

Mean Shift是一种聚类算法,在数据挖掘,图像提取,视频对象跟踪中都有应用。本文

重要演示Mean Shift算法来实现图像的低通边缘保留滤波效果。其处理以后的图像有点

类似油画一样。Mean Shift算法的输入参数一般有三个:

1.      矩阵半径r,声明大小

2.      像素距离,常见为欧几里德距离或者曼哈顿距离

3.      像素差值value

 

算法大致的流程如下:

a.      输入像素点P(x, y)

b.      计算该点的像素值pixelv

c.      根据输入的半径r与差值value求出矩阵半径内满足差值像素平均值作为输出像素点值

d.      计算shift与repetition,如果满足条件

e.      继续c ~ d,直到条件不满足退出,得到最终的输出像素值

f.       对输入图像的每个像素重复a ~ e,得到图像输出像素数据

二:色彩空间转换

 本文Mean Shift滤波在YIQ颜色空间上完成,关于RGB与YIQ颜色空间转换可以参考

这里:http://en.wikipedia.org/wiki/YIQ我google找来的转换公式截屏:


三:程序效果


滤镜源代码:

package com.gloomyfish.filter.study;

import java.awt.image.BufferedImage;

public class MeanShiftFilter extends AbstractBufferedImageOp {
	
	private int radius;
	private float colorDistance;
	
	public MeanShiftFilter() {
		radius = 3; // default shift radius
		colorDistance = 25; // default color distance
	}
	public int getRadius() {
		return radius;
	}

	public void setRadius(int radius) {
		this.radius = radius;
	}

	public float getColorDistance() {
		return colorDistance;
	}

	public void setColorDistance(float colorDistance) {
		this.colorDistance = colorDistance;
	}

	@Override
	public BufferedImage filter(BufferedImage src, BufferedImage dest) {
		int width = src.getWidth();
        int height = src.getHeight();

        if ( dest == null )
        	dest = createCompatibleDestImage( src, null );

        int[] inPixels = new int[width*height];
        int[] outPixels = new int[width*height];
        getRGB( src, 0, 0, width, height, inPixels);
        
        // convert RGB color space to YIQ color space
        float[][] pixelsf = new float[width*height][3];
        for(int i=0; i<inPixels.length; i++) {
			int argb = inPixels[i];
			int r = (argb >> 16) & 0xff;
			int g = (argb >>  8) & 0xff;
			int b = (argb) & 0xff;
			pixelsf[i][0] = 0.299f  *r + 0.587f *g + 0.114f  *b; // Y
			pixelsf[i][1] = 0.5957f *r - 0.2744f*g - 0.3212f *b; // I
			pixelsf[i][2] = 0.2114f *r - 0.5226f*g + 0.3111f *b; // Q
        }
        
        int index = 0;
        float shift = 0;
        float repetition = 0;
        float radius2 = radius * radius;
        float dis2 = colorDistance * colorDistance;
        for(int row=0; row<height; row++) {
        	int ta = 255, tr = 0, tg = 0, tb = 0;
        	for(int col=0; col<width; col++) {
				int xc = col;
				int yc = row;
				int xcOld, ycOld;
				float YcOld, IcOld, QcOld;
				index = row*width + col;
				float[] yiq = pixelsf[index];
				float Yc = yiq[0];
				float Ic = yiq[1];
				float Qc = yiq[2];

				repetition = 0;
				do {
					xcOld = xc;
					ycOld = yc;
					YcOld = Yc;
					IcOld = Ic;
					QcOld = Qc;

					float mx = 0;
					float my = 0;
					float mY = 0;
					float mI = 0;
					float mQ = 0;
					int num=0;

					for (int ry=-radius; ry <= radius; ry++) {
						int y2 = yc + ry; 
						if (y2 >= 0 && y2 < height) {
							for (int rx=-radius; rx <= radius; rx++) {
								int x2 = xc + rx; 
								if (x2 >= 0 && x2 < width) {
									if (ry*ry + rx*rx <= radius2) {
										yiq = pixelsf[y2*width + x2];

										float Y2 = yiq[0];
										float I2 = yiq[1];
										float Q2 = yiq[2];

										float dY = Yc - Y2;
										float dI = Ic - I2;
										float dQ = Qc - Q2;

										if (dY*dY+dI*dI+dQ*dQ <= dis2) {
											mx += x2;
											my += y2;
											mY += Y2;
											mI += I2;
											mQ += Q2;
											num++;
										}
									}
								}
							}
						}
					}
					float num_ = 1f/num;
					Yc = mY*num_;
					Ic = mI*num_;
					Qc = mQ*num_;
					xc = (int) (mx*num_+0.5);
					yc = (int) (my*num_+0.5);
					int dx = xc-xcOld;
					int dy = yc-ycOld;
					float dY = Yc-YcOld;
					float dI = Ic-IcOld;
					float dQ = Qc-QcOld;

					shift = dx*dx+dy*dy+dY*dY+dI*dI+dQ*dQ; 
					repetition++;
				}
				while (shift > 3 && repetition < 100);
				tr = (int)(Yc + 0.9563f*Ic + 0.6210f*Qc);
				tg = (int)(Yc - 0.2721f*Ic - 0.6473f*Qc);
				tb = (int)(Yc - 1.1070f*Ic + 1.7046f*Qc);     
				outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
        	}
        }
        setRGB( dest, 0, 0, width, height, outPixels );
        return dest;
	}
	
	public String toString() {
		System.out.println("Mean Shift Filter...");
		return "MeanShiftFilter";
	}

}
转载请注明

目录
相关文章
|
监控 算法 安全
基于伽马变换自适应修正的全景首尾融合算法
基于伽马变换自适应修正的全景首尾融合算法
|
6月前
|
算法
【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱
【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱
135 1
|
5月前
|
算法 API 计算机视觉
图像处理之角点检测与亚像素角点定位
图像处理之角点检测与亚像素角点定位
64 1
|
5月前
|
算法 数据挖掘 计算机视觉
图像处理之Mean Shift滤波(边缘保留的低通滤波)
图像处理之Mean Shift滤波(边缘保留的低通滤波)
32 0
|
5月前
|
资源调度 算法 计算机视觉
图像处理之积分图应用二(快速边缘保留滤波算法)
图像处理之积分图应用二(快速边缘保留滤波算法)
35 0
|
6月前
|
编解码 索引
LabVIEW使用正交编码器进行角位置测量
LabVIEW使用正交编码器进行角位置测量
91 1
|
6月前
|
算法 机器人 计算机视觉
LabVIEW使用灰度和边缘检测进行视频滤波
LabVIEW使用灰度和边缘检测进行视频滤波
39 1
|
6月前
|
算法 定位技术
ArcGIS中ArcMap栅格图像平滑滤波:焦点统计、滤波器、重采样
ArcGIS中ArcMap栅格图像平滑滤波:焦点统计、滤波器、重采样
268 1
|
机器学习/深度学习 传感器 算法
【光学】基于matlab模拟参考光栅和变形光栅折叠相位
【光学】基于matlab模拟参考光栅和变形光栅折叠相位
|
机器学习/深度学习 人工智能 算法
OpenCV-差分法实现绿叶识别(图像差分+颜色通道)
OpenCV-差分法实现绿叶识别(图像差分+颜色通道)
177 0