Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.alibaba.simpleimage.analyze.harris;
  
  import java.util.Iterator;
  import java.util.List;
  
Harris角点

Author(s):
hui.xueh
 
 public class HarrisFast {
 
 	public List<Cornercorners = new ArrayList<Corner>();
 
 	private int[][] image;
 	private int widthheight;
 	private float[][] Lx2Ly2Lxy;
 
 	public HarrisFast(int[][] imageint widthint height,
 			IntegralImage mIntegralImage) {
 		this. = image;
 		this. = width;
 		this. = height;
 	}

高斯平滑

Parameters:
x
y
sigma
Returns:
 
 	private double gaussian(double xdouble ydouble sigma) {
 		double sigma2 = sigma * sigma;
 		double t = (x * x + y * y) / (2 * sigma2);
 		double u = 1.0 / (2 * . * sigma2);
 		double e = u * Math.exp(-t);
 		return e;
 	}

Sobel边缘提取算子

Parameters:
x
y
Returns:
 
 	private float[] sobel(int xint y) {
 		int v00 = 0, v01 = 0, v02 = 0, v10 = 0, v12 = 0, v20 = 0, v21 = 0, v22 = 0;
 
 		int x0 = x - 1, x1 = xx2 = x + 1;
 		int y0 = y - 1, y1 = yy2 = y + 1;
 		if (x0 < 0)
 			x0 = 0;
 		if (y0 < 0)
 			y0 = 0;
 		if (x2 >= )
 			x2 =  - 1;
 		if (y2 >= )
 			y2 =  - 1;
 
 		v00 = [x0][y0];
 		v10 = [x1][y0];
 		v20 = [x2][y0];
 		v01 = [x0][y1];
 		v21 = [x2][y1];
 		v02 = [x0][y2];
 		v12 = [x1][y2];
 		v22 = [x2][y2];
 
 		float sx = ((v20 + 2 * v21 + v22) - (v00 + 2 * v01 + v02)) / (1200f);
 		float sy = ((v02 + 2 * v12 + v22) - (v00 + 2 * v10 + v20)) / (1200f);
 		return new float[] { sxsy };
 	}

拉普拉斯高斯差分,Laplace of Gaussian,涉及到卷积操作,计算开销很大

Parameters:
sigma
 
 	private void computeDerivatives(double sigma) {
 		this. = new float[][];
 		this. = new float[][];
 		this. = new float[][];
 
 		float[][][] grad = new float[][][];
 		for (int y = 0; y < y++)
 			for (int x = 0; x < x++)
 				grad[x][y] = sobel(xy);
 
 		int radius = (int) (2 * sigma);
 		int window = 1 + 2 * radius;
 		float[][] gaussian = new float[window][window];
 		for (int j = -radiusj <= radiusj++)
 			for (int i = -radiusi <= radiusi++)
 				gaussian[i + radius][j + radius] = (floatgaussian(ijsigma);
		for (int y = 0; y < y++) {
			for (int x = 0; x < x++) {
				for (int dy = -radiusdy <= radiusdy++) {
					for (int dx = -radiusdx <= radiusdx++) {
						int xk = x + dx;
						int yk = y + dy;
						if (xk < 0 || xk >= )
							continue;
						if (yk < 0 || yk >= )
							continue;
						double gw = gaussian[dx + radius][dy + radius];
						this.[x][y] += gw * grad[xk][yk][0]
grad[xk][yk][0];
						this.[x][y] += gw * grad[xk][yk][1]
grad[xk][yk][1];
						this.[x][y] += gw * grad[xk][yk][0]
grad[xk][yk][1];
					}
				}
			}
		}
	}

角点判断的依据

Parameters:
x
y
k ,一般设为0.06
Returns:
	private float harrisMeasure(int xint yfloat k) {
		float m00 = this.[x][y];
		float m01 = this.[x][y];
		float m10 = this.[x][y];
		float m11 = this.[x][y];
		return m00 * m11 - m01 * m10 - k * (m00 + m11) * (m00 + m11);
	}

是否为8邻域中的极大值

Parameters:
hmap
x
y
Returns:
	private boolean isSpatialMaxima(float[][] hmapint xint y) {
		int n = 8;
		int[] dx = new int[] { -1, 0, 1, 1, 1, 0, -1, -1 };
		int[] dy = new int[] { -1, -1, -1, 0, 1, 1, 1, 0 };
		double w = hmap[x][y];
		for (int i = 0; i < ni++) {
			double wk = hmap[x + dx[i]][y + dy[i]];
			if (wk >= w)
				return false;
		}
		return true;
	}
	private static 	final double scala = 255/Math.log(256);
	private float[][] computeHarrisMap(double k) {
		float[][] harrismap = new float[][];
		for (int y = 0; y < y++) {
			for (int x = 0; x < x++) {
				double h = harrisMeasure(xy, (floatk);
				if (h <= 0)
					continue;
				// log scale
				h = Math.log(1 + h) * ;
				// store
				harrismap[x][y] = (floath;
			}
		}
		return harrismap;
	}

角点的生成和过滤

Parameters:
sigma
k
minDistance ,该邻域内只取算子最大的特征点
	public void filter(double sigmadouble kint minDistance) {
		// fastComputeDerivatives();
		float[][] harrismap = computeHarrisMap(k);
		for (int y = 1; y <  - 1; y++) {
			for (int x = 1; x <  - 1; x++) {
				float h = harrismap[x][y];
				if (h <= 1E-3)
					continue;
				if (!isSpatialMaxima(harrismapxy))
					continue;
				.add(new Corner(xyh));
			}
		}
		//System.out.println(corners.size() + " potential corners found.");
		// remove corners to close to each other (keep the highest measure)
		while (iter.hasNext()) {
			Corner p = iter.next();
			for (Corner n : ) {
				if (n == p)
					continue;
				int dist = (int) Math.sqrt((p.x - n.x) * (p.x - n.x)
						+ (p.y - n.y) * (p.y - n.y));
				if (dist > minDistance)
					continue;
				if (n.h < p.h)
					continue;
				iter.remove();
				break;
			}
		}
		// output
		/*
		 * int[][] output = new int[width][height]; for (int y = 0; y < height;
		 * y++) for (int x = 0; x < width; x++) output[x][y] = (int)
		 * (image[x][y] * 0.75); // original image // (darker)
		 * 
		 * // for each corner for (Corner p : corners) { // add the cross sign
		 * over the image for (int dt = -3; dt <= 3; dt++) { if (p.x + dt >= 0
		 * && p.x + dt < width) output[p.x + dt][p.y] = 255; if (p.y + dt >= 0
		 * && p.y + dt < height) output[p.x][p.y + dt] = 255; }
		 * System.out.println("corner found at: " + p.x + "," + p.y + " (" + p.h
		 * + ")"); } System.out.println(corners.size() + " corners found.");
		 * 
		 * return output;
		 */
	}
New to GrepCode? Check out our FAQ X