findConvexityDefects_Android.txt

Kirill Kornyakov, 2012-03-19 04:54 pm

Download (3.5 kB)

 
1
private class ConvexityDefect {
2
3
		private Point mStart;
4
		private Point mEnd;
5
		private Point mDepthPoint;
6
		private float mDepth;
7
8
		public Point getStart(){
9
			return mStart;
10
		}
11
12
		public Point getEnd(){
13
			return mEnd;
14
		}
15
16
		public Point getDepthPoint(){
17
			return mDepthPoint;
18
		}
19
20
		public float getDepth(){
21
			return mDepth;
22
		}
23
24
		public void setStart(Point start){
25
			this.mStart = start;
26
		}
27
28
		public void setEnd(Point end){
29
			this.mEnd = end;
30
		}
31
32
		public void setDepthPoint(Point DepthPoint){
33
			this.mDepthPoint = DepthPoint;
34
		}
35
36
		public void setDepth(float depth){
37
			this.mDepth = depth;
38
		}
39
40
	}
41
	
42
	public List<ConvexityDefect> findConvexityDefects(Mat contour, List<Point> hullPts){
43
44
		List<Point> contourPts = new ArrayList<Point>();
45
		List<ConvexityDefect> defects = new ArrayList<ConvexityDefect>();
46
47
		Converters.Mat_to_vector_Point(contour, contourPts);
48
49
		if(contourPts.size() < 4 || hullPts.size() < 3)
50
		{
51
			// Error: Contour size must be >= 4 and convex hull size must be >= 3 
52
			return null; 
53
		}
54
55
		// Co-Orientation of Contour and it's Hull
56
		int sign = 0;
57
		int index1, index2, index3;
58
		Point pos, hull_cur, contour_cur;
59
60
		pos = hullPts.get(0);
61
		index1 = contourPts.indexOf(pos);
62
63
		pos = hullPts.get(1);
64
		index2 = contourPts.indexOf(pos);
65
66
		pos = hullPts.get(2);
67
		index3 = contourPts.indexOf(pos);
68
69
		sign += (index2 > index1) ? 1 : 0;
70
		sign += (index3 > index2) ? 1 : 0;
71
		sign += (index1 > index3) ? 1 : 0;
72
73
		if(sign == 1) // 0: same orientation 1: reverse orientation
74
			Collections.reverse(hullPts);
75
76
		// Cycle through the contour and hull
77
		for( int i = 0; i < hullPts.size(); i++ )
78
		{
79
			double dx0, dy0;
80
			double depth = 0, scale;
81
			boolean is_defect = false;
82
			Point hull_next;
83
			ConvexityDefect defect = new ConvexityDefect();
84
			
85
			hull_cur = hullPts.get(i); 
86
			
87
			if(i + 1 == hullPts.size()) // Caculate the defect between the last hull point and the first
88
				hull_next = hullPts.get(0); // First point of the hull
89
			else
90
				hull_next = hullPts.get(i+1);
91
92
			dx0 = hull_next.x - hull_cur.x;
93
			dy0 = hull_next.y - hull_cur.y;
94
			assert( dx0 != 0 || dy0 != 0 );
95
			scale = 1/Math.sqrt(dx0*dx0 + dy0*dy0);
96
97
			defect.setStart(hull_cur);
98
			defect.setEnd(hull_next);
99
					
100
			// Cycle through the contour till next hull point
101
			for( int k = contourPts.indexOf(hullPts.get(i)); k < contourPts.size() ; k++ )
102
			{
103
				
104
				contour_cur = contourPts.get(k); // Next contour point between the 2 hull points
105
				
106
				if(contour_cur.equals(hull_next)) // If we have reached the second hull point, stop cycling through the contour
107
					break;
108
				else
109
				{	
110
					if(k + 1 == contourPts.size()) // If the contour reached the end, start from the first point
111
					{
112
						k = 0; // Reset the index to the first point of the contour
113
						contour_cur = contourPts.get(k); // Next contour point between the 2 hull points
114
						
115
						if(contour_cur.equals(hull_next))
116
							break;
117
					}
118
					
119
					// Compute distance from current point to the hull edge
120
					double dx = contour_cur.x - hull_cur.x;
121
					double dy = contour_cur.y - hull_cur.y;
122
123
					// Compute depth
124
					double dist = Math.abs(-dy0*dx + dx0*dy) * scale;
125
126
					if( dist > depth )
127
					{
128
						depth = dist;
129
						defect.setDepthPoint(contour_cur);
130
						defect.setDepth((float)depth);
131
						is_defect = true;
132
					}
133
				}
134
			}
135
136
			if(is_defect)
137
			{
138
				defects.add(defect);
139
				is_defect = false;
140
			}
141
		}
142
143
		return defects;
144
	}