@@ -141,18 +141,174 @@ TEST_F(NonMaxSuppressionOpTest, TestInconsistentBoxAndScoreShapes) {
141141 AddInputFromArray<float >(TensorShape ({5 }), {.9f , .75f , .6f , .95f , .5f });
142142 AddInputFromArray<int >(TensorShape ({}), {30 });
143143 Status s = RunOpKernel ();
144+
145+ ASSERT_FALSE (s.ok ());
146+ EXPECT_TRUE (
147+ StringPiece (s.ToString ()).contains (" scores has incompatible shape" ))
148+ << s;
149+ }
150+
151+ TEST_F (NonMaxSuppressionOpTest, TestInvalidIOUThreshold) {
152+ MakeOp (1.2 );
153+ AddInputFromArray<float >(TensorShape ({1 , 4 }), {0 , 0 , 1 , 1 });
154+ AddInputFromArray<float >(TensorShape ({1 }), {.9f });
155+ AddInputFromArray<int >(TensorShape ({}), {3 });
156+ Status s = RunOpKernel ();
157+
158+ ASSERT_FALSE (s.ok ());
159+ EXPECT_TRUE (
160+ StringPiece (s.ToString ()).contains (" iou_threshold must be in [0, 1]" ))
161+ << s;
162+ }
163+
164+ TEST_F (NonMaxSuppressionOpTest, TestEmptyInput) {
165+ MakeOp (.5 );
166+ AddInputFromArray<float >(TensorShape ({0 , 4 }), {});
167+ AddInputFromArray<float >(TensorShape ({0 }), {});
168+ AddInputFromArray<int >(TensorShape ({}), {30 });
169+ TF_ASSERT_OK (RunOpKernel ());
170+
171+ Tensor expected (allocator (), DT_INT32, TensorShape ({0 }));
172+ test::FillValues<int >(&expected, {});
173+ test::ExpectTensorEqual<int >(expected, *GetOutput (0 ));
174+ }
175+
176+ //
177+ // NonMaxSuppressionV2Op Tests
178+ //
179+
180+ class NonMaxSuppressionV2OpTest : public OpsTestBase {
181+ protected:
182+ void MakeOp () {
183+ TF_EXPECT_OK (NodeDefBuilder (" non_max_suppression_op" , " NonMaxSuppressionV2" )
184+ .Input (FakeInput (DT_FLOAT))
185+ .Input (FakeInput (DT_FLOAT))
186+ .Input (FakeInput (DT_INT32))
187+ .Input (FakeInput (DT_FLOAT))
188+ .Finalize (node_def ()));
189+ TF_EXPECT_OK (InitOp ());
190+ }
191+ };
192+
193+ TEST_F (NonMaxSuppressionV2OpTest, TestSelectFromThreeClusters) {
194+ MakeOp ();
195+ AddInputFromArray<float >(TensorShape ({6 , 4 }),
196+ {0 , 0 , 1 , 1 , 0 , 0 .1f , 1 , 1 .1f , 0 , -0 .1f , 1 , 0 .9f ,
197+ 0 , 10 , 1 , 11 , 0 , 10 .1f , 1 , 11 .1f , 0 , 100 , 1 , 101 });
198+ AddInputFromArray<float >(TensorShape ({6 }), {.9f , .75f , .6f , .95f , .5f , .3f });
199+ AddInputFromArray<int >(TensorShape ({}), {3 });
200+ AddInputFromArray<float >(TensorShape ({}), {.5f });
201+ TF_ASSERT_OK (RunOpKernel ());
202+
203+ Tensor expected (allocator (), DT_INT32, TensorShape ({3 }));
204+ test::FillValues<int >(&expected, {3 , 0 , 5 });
205+ test::ExpectTensorEqual<int >(expected, *GetOutput (0 ));
206+ }
207+
208+ TEST_F (NonMaxSuppressionV2OpTest, TestSelectFromThreeClustersFlippedCoordinates) {
209+ MakeOp ();
210+ AddInputFromArray<float >(TensorShape ({6 , 4 }),
211+ {1 , 1 , 0 , 0 , 0 , 0 .1f , 1 , 1 .1f , 0 , .9f , 1 , -0 .1f ,
212+ 0 , 10 , 1 , 11 , 1 , 10 .1f , 0 , 11 .1f , 1 , 101 , 0 , 100 });
213+ AddInputFromArray<float >(TensorShape ({6 }), {.9f , .75f , .6f , .95f , .5f , .3f });
214+ AddInputFromArray<int >(TensorShape ({}), {3 });
215+ AddInputFromArray<float >(TensorShape ({}), {.5f });
216+ TF_ASSERT_OK (RunOpKernel ());
217+
218+ Tensor expected (allocator (), DT_INT32, TensorShape ({3 }));
219+ test::FillValues<int >(&expected, {3 , 0 , 5 });
220+ test::ExpectTensorEqual<int >(expected, *GetOutput (0 ));
221+ }
222+
223+ TEST_F (NonMaxSuppressionV2OpTest, TestSelectAtMostTwoBoxesFromThreeClusters) {
224+ MakeOp ();
225+ AddInputFromArray<float >(TensorShape ({6 , 4 }),
226+ {0 , 0 , 1 , 1 , 0 , 0 .1f , 1 , 1 .1f , 0 , -0 .1f , 1 , 0 .9f ,
227+ 0 , 10 , 1 , 11 , 0 , 10 .1f , 1 , 11 .1f , 0 , 100 , 1 , 101 });
228+ AddInputFromArray<float >(TensorShape ({6 }), {.9f , .75f , .6f , .95f , .5f , .3f });
229+ AddInputFromArray<int >(TensorShape ({}), {2 });
230+ AddInputFromArray<float >(TensorShape ({}), {.5f });
231+ TF_ASSERT_OK (RunOpKernel ());
232+
233+ Tensor expected (allocator (), DT_INT32, TensorShape ({2 }));
234+ test::FillValues<int >(&expected, {3 , 0 });
235+ test::ExpectTensorEqual<int >(expected, *GetOutput (0 ));
236+ }
237+
238+ TEST_F (NonMaxSuppressionV2OpTest, TestSelectAtMostThirtyBoxesFromThreeClusters) {
239+ MakeOp ();
240+ AddInputFromArray<float >(TensorShape ({6 , 4 }),
241+ {0 , 0 , 1 , 1 , 0 , 0 .1f , 1 , 1 .1f , 0 , -0 .1f , 1 , 0 .9f ,
242+ 0 , 10 , 1 , 11 , 0 , 10 .1f , 1 , 11 .1f , 0 , 100 , 1 , 101 });
243+ AddInputFromArray<float >(TensorShape ({6 }), {.9f , .75f , .6f , .95f , .5f , .3f });
244+ AddInputFromArray<int >(TensorShape ({}), {30 });
245+ AddInputFromArray<float >(TensorShape ({}), {.5f });
246+ TF_ASSERT_OK (RunOpKernel ());
247+
248+ Tensor expected (allocator (), DT_INT32, TensorShape ({3 }));
249+ test::FillValues<int >(&expected, {3 , 0 , 5 });
250+ test::ExpectTensorEqual<int >(expected, *GetOutput (0 ));
251+ }
252+
253+ TEST_F (NonMaxSuppressionV2OpTest, TestSelectSingleBox) {
254+ MakeOp ();
255+ AddInputFromArray<float >(TensorShape ({1 , 4 }), {0 , 0 , 1 , 1 });
256+ AddInputFromArray<float >(TensorShape ({1 }), {.9f });
257+ AddInputFromArray<int >(TensorShape ({}), {3 });
258+ AddInputFromArray<float >(TensorShape ({}), {.5f });
259+ TF_ASSERT_OK (RunOpKernel ());
260+
261+ Tensor expected (allocator (), DT_INT32, TensorShape ({1 }));
262+ test::FillValues<int >(&expected, {0 });
263+ test::ExpectTensorEqual<int >(expected, *GetOutput (0 ));
264+ }
265+
266+ TEST_F (NonMaxSuppressionV2OpTest, TestSelectFromTenIdenticalBoxes) {
267+ MakeOp ();
268+
269+ int num_boxes = 10 ;
270+ std::vector<float > corners (num_boxes * 4 );
271+ std::vector<float > scores (num_boxes);
272+ for (int i = 0 ; i < num_boxes; ++i) {
273+ corners[i * 4 + 0 ] = 0 ;
274+ corners[i * 4 + 1 ] = 0 ;
275+ corners[i * 4 + 2 ] = 1 ;
276+ corners[i * 4 + 3 ] = 1 ;
277+ scores[i] = .9 ;
278+ }
279+ AddInputFromArray<float >(TensorShape ({num_boxes, 4 }), corners);
280+ AddInputFromArray<float >(TensorShape ({num_boxes}), scores);
281+ AddInputFromArray<int >(TensorShape ({}), {3 });
282+ AddInputFromArray<float >(TensorShape ({}), {.5f });
283+ TF_ASSERT_OK (RunOpKernel ());
284+
285+ Tensor expected (allocator (), DT_INT32, TensorShape ({1 }));
286+ test::FillValues<int >(&expected, {0 });
287+ test::ExpectTensorEqual<int >(expected, *GetOutput (0 ));
288+ }
289+
290+ TEST_F (NonMaxSuppressionV2OpTest, TestInconsistentBoxAndScoreShapes) {
291+ MakeOp ();
292+ AddInputFromArray<float >(TensorShape ({6 , 4 }),
293+ {0 , 0 , 1 , 1 , 0 , 0 .1f , 1 , 1 .1f , 0 , -0 .1f , 1 , 0 .9f ,
294+ 0 , 10 , 1 , 11 , 0 , 10 .1f , 1 , 11 .1f , 0 , 100 , 1 , 101 });
295+ AddInputFromArray<float >(TensorShape ({5 }), {.9f , .75f , .6f , .95f , .5f });
296+ AddInputFromArray<int >(TensorShape ({}), {30 });
297+ AddInputFromArray<float >(TensorShape ({}), {.5f });
298+ Status s = RunOpKernel ();
144299
145300 ASSERT_FALSE (s.ok ());
146301 EXPECT_TRUE (
147302 StringPiece (s.ToString ()).contains (" scores has incompatible shape" ))
148303 << s;
149304}
150305
151- TEST_F (NonMaxSuppressionOpTest , TestInvalidIOUThreshold) {
152- MakeOp (1.2 );
306+ TEST_F (NonMaxSuppressionV2OpTest , TestInvalidIOUThreshold) {
307+ MakeOp ();
153308 AddInputFromArray<float >(TensorShape ({1 , 4 }), {0 , 0 , 1 , 1 });
154309 AddInputFromArray<float >(TensorShape ({1 }), {.9f });
155310 AddInputFromArray<int >(TensorShape ({}), {3 });
311+ AddInputFromArray<float >(TensorShape ({}), {1 .2f });
156312 Status s = RunOpKernel ();
157313
158314 ASSERT_FALSE (s.ok ());
@@ -161,11 +317,12 @@ TEST_F(NonMaxSuppressionOpTest, TestInvalidIOUThreshold) {
161317 << s;
162318}
163319
164- TEST_F (NonMaxSuppressionOpTest , TestEmptyInput) {
165- MakeOp (. 5 );
320+ TEST_F (NonMaxSuppressionV2OpTest , TestEmptyInput) {
321+ MakeOp ();
166322 AddInputFromArray<float >(TensorShape ({0 , 4 }), {});
167323 AddInputFromArray<float >(TensorShape ({0 }), {});
168324 AddInputFromArray<int >(TensorShape ({}), {30 });
325+ AddInputFromArray<float >(TensorShape ({}), {.5f });
169326 TF_ASSERT_OK (RunOpKernel ());
170327
171328 Tensor expected (allocator (), DT_INT32, TensorShape ({0 }));
0 commit comments