7
7
#endif
8
8
9
9
module OpenCV.Internal.ImgProc.StructuralAnalysis
10
- ( convexHull
10
+ ( approxPolyDP
11
+ , ApproxPolyDP (.. )
12
+ , convexHull
11
13
, ConvexHull (.. )
12
14
) where
13
15
@@ -39,6 +41,129 @@ C.using "namespace cv"
39
41
40
42
--------------------------------------------------------------------------------
41
43
44
+
45
+ {- | Approximates a polygonal curve(s) with the specified precision.
46
+
47
+ The functions approxPolyDP approximate a curve or a polygon with another
48
+ curve/polygon with less vertices so that the distance between them is less or
49
+ equal to the specified precision. It uses the
50
+ <http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm Douglas-Peucker algorithm>
51
+
52
+ <http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=contourarea#approxpolydp>
53
+ -}
54
+ approxPolyDP
55
+ :: forall point2 depth
56
+ . ( IsPoint2 point2 depth
57
+ , ApproxPolyDP depth
58
+ )
59
+ => V. Vector (point2 depth )
60
+ -> Double -- ^ epsilon
61
+ -> Bool -- ^ is closed
62
+ -> CvExcept (V. Vector (Point 2 depth ))
63
+ approxPolyDP curve epsilon isClosed = unsafeWrapException $
64
+ withArrayPtr (V. map toPoint curve) $ \ curvePtr ->
65
+ alloca $ \ (approxPtrPtr :: Ptr (Ptr (Ptr (C (Point 2 depth ))))) ->
66
+ alloca $ \ (approxSizePtr :: Ptr Int32 ) ->
67
+ handleCvException
68
+ ( do approxSize <- fromIntegral <$> peek approxSizePtr
69
+ approxPtr :: Ptr (Ptr (C (Point 2 depth ))) <- peek approxPtrPtr
70
+ approxList :: [Ptr (C (Point 2 depth ))] <- peekArray approxSize approxPtr
71
+ approxVec <- V. fromList <$> mapM (fromPtr . pure ) approxList
72
+ approxPolyDP_deletePtrArray approxPtrPtr
73
+ pure approxVec
74
+ ) $
75
+ approxPolyDP_internal
76
+ (fromIntegral $ V. length curve)
77
+ curvePtr
78
+ approxSizePtr
79
+ approxPtrPtr
80
+ (toCDouble epsilon)
81
+ (fromBool isClosed)
82
+
83
+ -- | Internal class used to overload the 'approxPolyDP' depth.
84
+ class ( FromPtr (Point 2 depth )
85
+ , CSizeOf (C'Point 2 depth )
86
+ , PlacementNew (C'Point 2 depth )
87
+ ) => ApproxPolyDP depth where
88
+ approxPolyDP_internal
89
+ :: Int32 -- ^ Number of input curve points.
90
+ -> Ptr (C (Point 2 depth )) -- ^ Input curve points array.
91
+ -> Ptr Int32 -- ^ Size of approximated curve.
92
+ -> Ptr (Ptr (Ptr (C (Point 2 depth ))))
93
+ -- ^ Array of pointers to approximated curve points.
94
+ -> CDouble -- ^ epsilon
95
+ -> CInt -- ^ is closed
96
+ -> IO (Ptr (C CvCppException ))
97
+
98
+ approxPolyDP_deletePtrArray
99
+ :: Ptr (Ptr (Ptr (C (Point 2 depth ))))
100
+ -- ^ Array of pointers to approximated curve points.
101
+ -> IO ()
102
+
103
+ instance ApproxPolyDP Int32 where
104
+ approxPolyDP_internal curveSize curvePtr approxSizePtr approxPtrPtr epsilon isClosed =
105
+ [cvExcept |
106
+ cv::_InputArray curve =
107
+ cv::_InputArray( $(Point2i * curvePtr)
108
+ , $(int32_t curveSize)
109
+ );
110
+ std::vector<cv::Point2i> approx;
111
+ cv::approxPolyDP
112
+ ( curve
113
+ , approx
114
+ , $(double epsilon)
115
+ , $(bool isClosed)
116
+ );
117
+
118
+ *$(int32_t * approxSizePtr) = approx.size();
119
+
120
+ cv::Point2i * * * approxPtrPtr = $(Point2i * * * approxPtrPtr);
121
+ cv::Point2i * * approxPtr = new cv::Point2i * [approx.size()];
122
+ *approxPtrPtr = approxPtr;
123
+
124
+ for (std::vector<cv::Point2i>::size_type i = 0; i < approx.size(); i++) {
125
+ cv::Point2i & ptAddress = approx[i];
126
+ cv::Point2i * newPt = new cv::Point2i(ptAddress.x, ptAddress.y);
127
+ approxPtr[i] = newPt;
128
+ }
129
+ |]
130
+
131
+ approxPolyDP_deletePtrArray approxPtrPtr =
132
+ [CU. block | void { delete [] *$(Point2i * * * approxPtrPtr); } |]
133
+
134
+ instance ApproxPolyDP CFloat where
135
+ approxPolyDP_internal curveSize curvePtr approxSizePtr approxPtrPtr epsilon isClosed =
136
+ [cvExcept |
137
+ cv::_InputArray curve =
138
+ cv::_InputArray( $(Point2f * curvePtr)
139
+ , $(int32_t curveSize)
140
+ );
141
+ std::vector<cv::Point2f> approx;
142
+ cv::approxPolyDP
143
+ ( curve
144
+ , approx
145
+ , $(double epsilon)
146
+ , $(bool isClosed)
147
+ );
148
+
149
+ *$(int32_t * approxSizePtr) = approx.size();
150
+
151
+ cv::Point2f * * * approxPtrPtr = $(Point2f * * * approxPtrPtr);
152
+ cv::Point2f * * approxPtr = new cv::Point2f * [approx.size()];
153
+ *approxPtrPtr = approxPtr;
154
+
155
+ for (std::vector<cv::Point2f>::size_type i = 0; i < approx.size(); i++) {
156
+ cv::Point2f & ptAddress = approx[i];
157
+ cv::Point2f * newPt = new cv::Point2f(ptAddress.x, ptAddress.y);
158
+ approxPtr[i] = newPt;
159
+ }
160
+ |]
161
+
162
+ approxPolyDP_deletePtrArray approxPtrPtr =
163
+ [CU. block | void { delete [] *$(Point2f * * * approxPtrPtr); } |]
164
+
165
+ --------------------------------------------------------------------------------
166
+
42
167
{- | Finds the convex hull of a point set.
43
168
44
169
Finds the convex hull of a 2D point set using the Sklansky's algorithm
@@ -61,103 +186,96 @@ convexHull
61
186
convexHull points clockwise = unsafeWrapException $
62
187
withArrayPtr (V. map toPoint points) $ \ (pointsPtr :: Ptr (C (Point 2 depth ))) ->
63
188
alloca $ \ (hullPointsPtrPtr :: Ptr (Ptr (Ptr (C (Point 2 depth ))))) ->
64
- alloca $ \ (numHullPointsPtr :: Ptr Int32 ) ->
189
+ alloca $ \ (hullSizePtr :: Ptr Int32 ) ->
65
190
handleCvException
66
- ( do numHullPoints <- fromIntegral <$> peek numHullPointsPtr
191
+ ( do hullSize <- fromIntegral <$> peek hullSizePtr
67
192
hullPointsPtr :: Ptr (Ptr (C (Point 2 depth ))) <- peek hullPointsPtrPtr
68
- hullPointsList :: [Ptr (C (Point 2 depth ))] <- peekArray numHullPoints hullPointsPtr
193
+ hullPointsList :: [Ptr (C (Point 2 depth ))] <- peekArray hullSize hullPointsPtr
69
194
hullPointsVec <- V. fromList <$> mapM (fromPtr . pure ) hullPointsList
70
195
convexHull_deletePtrArray hullPointsPtrPtr
71
196
pure hullPointsVec
72
197
) $
73
198
convexHull_internal
74
199
(fromIntegral $ V. length points)
75
- (fromBool clockwise)
76
200
pointsPtr
201
+ (fromBool clockwise)
77
202
hullPointsPtrPtr
78
- numHullPointsPtr
203
+ hullSizePtr
79
204
80
205
-- | Internal class used to overload the 'convexHull' depth.
81
206
class ( FromPtr (Point 2 depth )
82
207
, CSizeOf (C'Point 2 depth )
83
208
, PlacementNew (C'Point 2 depth )
84
209
) => ConvexHull depth where
85
210
convexHull_internal
86
- :: Int32
87
- -> CInt
88
- -> Ptr ( C ( Point 2 depth ))
211
+ :: Int32 -- ^ Number of input points.
212
+ -> Ptr ( C ( Point 2 depth )) -- ^ Input points array.
213
+ -> CInt -- ^ Orientation flag.
89
214
-> Ptr (Ptr (Ptr (C (Point 2 depth ))))
90
- -> Ptr Int32
215
+ -- ^ Array of pointers to hull points.
216
+ -> Ptr Int32 -- ^ Size of convex hull.
91
217
-> IO (Ptr (C CvCppException ))
92
218
93
219
convexHull_deletePtrArray
94
220
:: Ptr (Ptr (Ptr (C (Point 2 depth ))))
221
+ -- ^ Array of pointers to hull points.
95
222
-> IO ()
96
223
97
- instance ConvexHull CFloat where
98
- convexHull_internal numPoints clockwise pointsPtr hullPointsPtrPtr numHullPointsPtr =
224
+ instance ConvexHull Int32 where
225
+ convexHull_internal numPoints pointsPtr clockwise hullPointsPtrPtr hullSizePtr =
99
226
[cvExcept |
100
227
cv::_InputArray points =
101
- cv::_InputArray( $(Point2f * pointsPtr)
228
+ cv::_InputArray( $(Point2i * pointsPtr)
102
229
, $(int32_t numPoints)
103
230
);
104
- std::vector<cv::Point2f > hull;
231
+ std::vector<cv::Point2i > hull;
105
232
cv::convexHull
106
233
( points
107
234
, hull
108
235
, $(bool clockwise)
109
236
, true
110
237
);
111
238
112
- *$(int32_t * numHullPointsPtr ) = hull.size();
239
+ *$(int32_t * hullSizePtr ) = hull.size();
113
240
114
- cv::Point2f * * * hullPointsPtrPtr = $(Point2f * * * hullPointsPtrPtr);
115
- cv::Point2f * * hullPointsPtr = new cv::Point2f * [hull.size()];
241
+ cv::Point2i * * * hullPointsPtrPtr = $(Point2i * * * hullPointsPtrPtr);
242
+ cv::Point2i * * hullPointsPtr = new cv::Point2i * [hull.size()];
116
243
*hullPointsPtrPtr = hullPointsPtr;
117
244
118
245
for (std::vector<cv::Point2i>::size_type i = 0; i < hull.size(); i++)
119
246
{
120
- cv::Point2f & hullPt = hull[i];
121
- cv::Point2f * newHullPt = new cv::Point2f (hullPt.x, hullPt.y);
247
+ cv::Point2i & hullPt = hull[i];
248
+ cv::Point2i * newHullPt = new cv::Point2i (hullPt.x, hullPt.y);
122
249
hullPointsPtr[i] = newHullPt;
123
250
}
124
251
|]
125
252
126
253
convexHull_deletePtrArray hullPointsPtrPtr =
127
- [CU. block | void {
128
- delete [] *$(Point2f * * * hullPointsPtrPtr);
129
- }|]
254
+ [CU. block | void { delete [] *$(Point2i * * * hullPointsPtrPtr); }|]
130
255
131
- instance ConvexHull Int32 where
132
- convexHull_internal numPoints clockwise pointsPtr hullPointsPtrPtr numHullPointsPtr =
256
+ instance ConvexHull CFloat where
257
+ convexHull_internal numPoints pointsPtr clockwise hullPointsPtrPtr hullSizePtr =
133
258
[cvExcept |
134
259
cv::_InputArray points =
135
- cv::_InputArray( $(Point2i * pointsPtr)
260
+ cv::_InputArray( $(Point2f * pointsPtr)
136
261
, $(int32_t numPoints)
137
262
);
138
- std::vector<cv::Point2i> hull;
139
- cv::convexHull
140
- ( points
141
- , hull
142
- , $(bool clockwise)
143
- , true
144
- );
263
+ std::vector<cv::Point2f> hull;
264
+ cv::convexHull(points, hull, $(bool clockwise), true);
145
265
146
- *$(int32_t * numHullPointsPtr ) = hull.size();
266
+ *$(int32_t * hullSizePtr ) = hull.size();
147
267
148
- cv::Point2i * * * hullPointsPtrPtr = $(Point2i * * * hullPointsPtrPtr);
149
- cv::Point2i * * hullPointsPtr = new cv::Point2i * [hull.size()];
268
+ cv::Point2f * * * hullPointsPtrPtr = $(Point2f * * * hullPointsPtrPtr);
269
+ cv::Point2f * * hullPointsPtr = new cv::Point2f * [hull.size()];
150
270
*hullPointsPtrPtr = hullPointsPtr;
151
271
152
272
for (std::vector<cv::Point2i>::size_type i = 0; i < hull.size(); i++)
153
273
{
154
- cv::Point2i & hullPt = hull[i];
155
- cv::Point2i * newHullPt = new cv::Point2i (hullPt.x, hullPt.y);
274
+ cv::Point2f & hullPt = hull[i];
275
+ cv::Point2f * newHullPt = new cv::Point2f (hullPt.x, hullPt.y);
156
276
hullPointsPtr[i] = newHullPt;
157
277
}
158
278
|]
159
279
160
280
convexHull_deletePtrArray hullPointsPtrPtr =
161
- [CU. block | void {
162
- delete [] *$(Point2i * * * hullPointsPtrPtr);
163
- }|]
281
+ [CU. block | void { delete [] *$(Point2f * * * hullPointsPtrPtr); }|]
0 commit comments