public static double distanceHsv( Gaussian2D_F64 model , double hue , double saturation ) { double dx = UtilAngle.dist(hue,model.x); double dy = saturation-model.y; // chi-square = d^T*S*d double tmp0 = dx*model.sxx + dy*model.sxy; double tmp1 = dx*model.sxy + dy*model.syy; return tmp0*dx + tmp1*dy; } }
/** * Applies trilinear interpolation across the descriptor */ protected void trilinearInterpolation( float weight , float sampleX , float sampleY , double angle , TupleDesc_F64 descriptor ) { for (int i = 0; i < widthGrid; i++) { double weightGridY = 1.0 - Math.abs(sampleY-i); if( weightGridY <= 0) continue; for (int j = 0; j < widthGrid; j++) { double weightGridX = 1.0 - Math.abs(sampleX-j); if( weightGridX <= 0 ) continue; for (int k = 0; k < numHistogramBins; k++) { double angleBin = k*histogramBinWidth; double weightHistogram = 1.0 - UtilAngle.dist(angle,angleBin)/histogramBinWidth; if( weightHistogram <= 0 ) continue; int descriptorIndex = (i*widthGrid + j)*numHistogramBins + k; descriptor.value[descriptorIndex] += weight*weightGridX*weightGridY*weightHistogram; } } } }
/** * Given the interpolated index, compute the angle from the 3 indexes. The angle for each index * is computed from the weighted gradients. * @param offset Interpolated index offset relative to index0. range -1 to 1 * @return Interpolated angle. */ double interpolateAngle(int index0, int index1, int index2, double offset) { double angle1 = Math.atan2(histogramY[index1],histogramX[index1]); double deltaAngle; if( offset < 0 ) { double angle0 = Math.atan2(histogramY[index0],histogramX[index0]); deltaAngle = UtilAngle.dist(angle0,angle1); } else { double angle2 = Math.atan2(histogramY[index2], histogramX[index2]); deltaAngle = UtilAngle.dist(angle2,angle1); } return UtilAngle.bound(angle1 + deltaAngle*offset); }
while( UtilAngle.dist(startAngle,endAngle) <= windowSize ) { sumX += derivX[endIndex]; sumY += derivY[endIndex];
/** * Selects the node on the contour which is closest to 270 degrees and is thus likely to be * a node on the corner */ NodeInfo selectSeedCorner() { NodeInfo best = null; double bestError = Double.MAX_VALUE; for (int i = 0; i < contour.size; i++) { NodeInfo info = contour.get(i); double error = UtilAngle.dist(3*Math.PI/2.0,info.angleBetween); if( error < bestError ) { bestError = error; best = info; } } return best; }
LinePolar2D_F64 b = listPolar.get(j); if( Math.abs(a.distance-b.distance) < 20 && UtilAngle.dist(a.angle,b.angle) < 0.2 ) { listPolar.remove(j); similar.add(listSegments.remove(j));
@Override protected double computeOrientation() { computeAngles(); double windowRadius = windowSize/2.0; int w = rect.x1-rect.x0; double bestScore = -1; double bestAngle = 0; double stepAngle = Math.PI*2.0/numAngles; int N = w*(rect.y1-rect.y0); for( double angle = -Math.PI; angle < Math.PI; angle += stepAngle ) { double dx = 0; double dy = 0; for( int i = 0; i < N; i++ ) { double diff = UtilAngle.dist(angle,angles[i]); if( diff <= windowRadius) { int x = rect.x0 + i % w; int y = rect.y0 + i / w; dx += derivX.get(x,y); dy += derivY.get(x,y); } } double n = dx*dx + dy*dy; if( n > bestScore) { bestAngle = Math.atan2(dy,dx); bestScore = n; } } return bestAngle; }
@Override protected double computeOrientation() { computeAngles(); double windowRadius = windowSize/2.0; int w = rect.x1-rect.x0; double bestScore = -1; double bestAngle = 0; double stepAngle = Math.PI*2.0/numAngles; int N = w*(rect.y1-rect.y0); for( double angle = -Math.PI; angle < Math.PI; angle += stepAngle ) { double dx = 0; double dy = 0; for( int i = 0; i < N; i++ ) { double diff = UtilAngle.dist(angle,angles[i]); if( diff <= windowRadius) { int x = rect.x0 + i % w; int y = rect.y0 + i / w; dx += derivX.get(x,y); dy += derivY.get(x,y); } } double n = dx*dx + dy*dy; if( n > bestScore) { bestAngle = Math.atan2(dy,dx); bestScore = n; } } return bestAngle; }
NodeInfo c = next.edges.get(j).target; double diff = UtilAngle.dist(angle,anglePrev); if( diff <= MAX_LINE_ANGLE_CHANGE ) { double d = c.ellipse.center.distance(next.ellipse.center);
@Override protected double computeOrientation() { computeAngles(); double windowRadius = windowSize/2.0; int w = rect.x1-rect.x0; double bestScore = -1; double bestAngle = 0; double stepAngle = Math.PI*2.0/numAngles; int N = w*(rect.y1-rect.y0); for( double angle = -Math.PI; angle < Math.PI; angle += stepAngle ) { double dx = 0; double dy = 0; for( int i = 0; i < N; i++ ) { double diff = UtilAngle.dist(angle,angles[i]); if( diff <= windowRadius) { int x = rect.x0 + i % w; int y = rect.y0 + i / w; dx += derivX.get(x,y); dy += derivY.get(x,y); } } double n = dx*dx + dy*dy; if( n > bestScore) { bestAngle = Math.atan2(dy,dx); bestScore = n; } } return bestAngle; }
double dy = 0; for( int i = 0; i < N; i++ ) { double diff = UtilAngle.dist(angle,angles[i]); if( diff <= windowRadius) { int localX = i%w;
double dy = 0; for( int i = 0; i < N; i++ ) { double diff = UtilAngle.dist(angle,angles[i]); if( diff <= windowRadius) { int localX = i%w;
double dy = 0; for( int i = 0; i < N; i++ ) { double diff = UtilAngle.dist(angle,angles[i]); if( diff <= windowRadius) { int localX = i%w;
/** * Select the first node (currentSeed) in the next row it finds the next element in the next row by * looking at the first and second elements in the previous row. It selects the edge in * currentSeed which cones closest to matching the angle of 'prevSeed' and 'prevNext' * @param prevSeed First node in the previous row * @param prevNext Second node in the previous row * @param currentSeed First node in the current row * @return The found node or null if one was not found */ static protected NodeInfo selectSeedNext( NodeInfo prevSeed , NodeInfo prevNext , NodeInfo currentSeed) { double angleTarget = direction(prevSeed, prevNext); double bestScore = Double.MAX_VALUE; NodeInfo best = null; // cut down on verbosity by saving the reference here Point2D_F64 c = currentSeed.ellipse.center; for (int i = 0; i < currentSeed.edges.size(); i++) { Edge edge = currentSeed.edges.get(i); double angleDiff = UtilAngle.dist(edge.angle, angleTarget); if( angleDiff > MAX_LINE_ANGLE_CHANGE*1.5 ) continue; double score = (angleDiff+0.001)*c.distance(edge.target.ellipse.center); if( score < bestScore ) { bestScore = score; best = edge.target; } } return best; }
double acuteAngle( SquareNode a , int sideA , SquareNode b , int sideB ) { Point2D_F64 a0 = a.corners.get(sideA); Point2D_F64 a1 = a.corners.get(add(sideA, 1)); Point2D_F64 b0 = b.corners.get(sideB); Point2D_F64 b1 = b.corners.get(add(sideB, 1)); vector0.set(a1.x - a0.x, a1.y - a0.y); vector1.set(b1.x - b0.x, b1.y - b0.y); double acute = vector0.acute(vector1); return Math.min(UtilAngle.dist(Math.PI, acute), acute); }
/** * If there is a nearly perfect line a node farther down the line can come before. This just selects the closest */ void pruneNearlyIdenticalAngles() { for (int i = 0; i < listInfo.size(); i++) { NodeInfo infoN = listInfo.get(i); for (int j = 0; j < infoN.edges.size(); ) { int k = (j+1)%infoN.edges.size; double angularDiff = UtilAngle.dist(infoN.edges.get(j).angle,infoN.edges.get(k).angle); if( angularDiff < UtilAngle.radian(5)) { NodeInfo infoJ = infoN.edges.get(j).target; NodeInfo infoK = infoN.edges.get(k).target; double distJ = infoN.ellipse.center.distance(infoJ.ellipse.center); double distK = infoN.ellipse.center.distance(infoK.ellipse.center); if( distJ < distK ) { infoN.edges.remove(k); } else { infoN.edges.remove(j); } } else { j++; } } } }