1# Tencent is pleased to support the open source community by making ncnn available.
2#
3# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
4#
5# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6# in compliance with the License. You may obtain a copy of the License at
7#
8# https://opensource.org/licenses/BSD-3-Clause
9#
10# Unless required by applicable law or agreed to in writing, software distributed
11# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12# CONDITIONS OF ANY KIND, either express or implied. See the License for the
13# specific language governing permissions and limitations under the License.
14
15import sys
16import numpy as np
17import pytest
18
19import ncnn
20
21
22def test_mat_dims1():
23    mat = ncnn.Mat(1)
24    assert mat.dims == 1 and mat.w == 1
25    mat = ncnn.Mat(2, elemsize=4)
26    assert mat.dims == 1 and mat.w == 2 and mat.elemsize == 4
27    mat = ncnn.Mat(3, elemsize=4, elempack=1)
28    assert mat.dims == 1 and mat.w == 3 and mat.elemsize == 4 and mat.elempack == 1
29    mat = ncnn.Mat(4, elemsize=4, elempack=1, allocator=None)
30    assert (
31        mat.dims == 1
32        and mat.w == 4
33        and mat.elemsize == 4
34        and mat.elempack == 1
35        and mat.allocator == None
36    )
37
38    mat = ncnn.Mat((1,))
39    assert mat.dims == 1 and mat.w == 1
40    mat = ncnn.Mat((2,), elemsize=4)
41    assert mat.dims == 1 and mat.w == 2 and mat.elemsize == 4
42    mat = ncnn.Mat((3,), elemsize=4, elempack=1)
43    assert mat.dims == 1 and mat.w == 3 and mat.elemsize == 4 and mat.elempack == 1
44    mat = ncnn.Mat((4,), elemsize=4, elempack=1, allocator=None)
45    assert (
46        mat.dims == 1
47        and mat.w == 4
48        and mat.elemsize == 4
49        and mat.elempack == 1
50        and mat.allocator == None
51    )
52
53
54def test_mat_dims2():
55    mat = ncnn.Mat(1, 2)
56    assert mat.dims == 2 and mat.w == 1 and mat.h == 2
57    mat = ncnn.Mat(3, 4, elemsize=4)
58    assert mat.dims == 2 and mat.w == 3 and mat.h == 4 and mat.elemsize == 4
59    mat = ncnn.Mat(5, 6, elemsize=4, elempack=1)
60    assert (
61        mat.dims == 2
62        and mat.w == 5
63        and mat.h == 6
64        and mat.elemsize == 4
65        and mat.elempack == 1
66    )
67    mat = ncnn.Mat(7, 8, elemsize=4, elempack=1, allocator=None)
68    assert (
69        mat.dims == 2
70        and mat.w == 7
71        and mat.h == 8
72        and mat.elemsize == 4
73        and mat.elempack == 1
74        and mat.allocator == None
75    )
76
77    mat = ncnn.Mat((1, 2))
78    assert mat.dims == 2 and mat.w == 1 and mat.h == 2
79    mat = ncnn.Mat((3, 4), elemsize=4)
80    assert mat.dims == 2 and mat.w == 3 and mat.h == 4 and mat.elemsize == 4
81    mat = ncnn.Mat((5, 6), elemsize=4, elempack=1)
82    assert (
83        mat.dims == 2
84        and mat.w == 5
85        and mat.h == 6
86        and mat.elemsize == 4
87        and mat.elempack == 1
88    )
89    mat = ncnn.Mat((7, 8), elemsize=4, elempack=1, allocator=None)
90    assert (
91        mat.dims == 2
92        and mat.w == 7
93        and mat.h == 8
94        and mat.elemsize == 4
95        and mat.elempack == 1
96        and mat.allocator == None
97    )
98
99
100def test_mat_dims3():
101    mat = ncnn.Mat(1, 2, 3)
102    assert mat.dims == 3 and mat.w == 1 and mat.h == 2 and mat.c == 3
103    mat = ncnn.Mat(4, 5, 6, elemsize=4)
104    assert (
105        mat.dims == 3 and mat.w == 4 and mat.h == 5 and mat.c == 6 and mat.elemsize == 4
106    )
107    mat = ncnn.Mat(7, 8, 9, elemsize=4, elempack=1)
108    assert (
109        mat.dims == 3
110        and mat.w == 7
111        and mat.h == 8
112        and mat.c == 9
113        and mat.elemsize == 4
114        and mat.elempack == 1
115    )
116    mat = ncnn.Mat(10, 11, 12, elemsize=4, elempack=1, allocator=None)
117    assert (
118        mat.dims == 3
119        and mat.w == 10
120        and mat.h == 11
121        and mat.c == 12
122        and mat.elemsize == 4
123        and mat.elempack == 1
124        and mat.allocator == None
125    )
126
127    mat = ncnn.Mat((1, 2, 3))
128    assert mat.dims == 3 and mat.w == 1 and mat.h == 2 and mat.c == 3
129    mat = ncnn.Mat((4, 5, 6), elemsize=4)
130    assert (
131        mat.dims == 3 and mat.w == 4 and mat.h == 5 and mat.c == 6 and mat.elemsize == 4
132    )
133    mat = ncnn.Mat((7, 8, 9), elemsize=4, elempack=1)
134    assert (
135        mat.dims == 3
136        and mat.w == 7
137        and mat.h == 8
138        and mat.c == 9
139        and mat.elemsize == 4
140        and mat.elempack == 1
141    )
142    mat = ncnn.Mat((10, 11, 12), elemsize=4, elempack=1, allocator=None)
143    assert (
144        mat.dims == 3
145        and mat.w == 10
146        and mat.h == 11
147        and mat.c == 12
148        and mat.elemsize == 4
149        and mat.elempack == 1
150        and mat.allocator == None
151    )
152
153
154def test_numpy():
155    mat = ncnn.Mat(1)
156    array = np.array(mat)
157    assert mat.dims == array.ndim and mat.w == array.shape[0]
158    mat = ncnn.Mat(2, 3)
159    array = np.array(mat)
160    assert (
161        mat.dims == array.ndim and mat.w == array.shape[1] and mat.h == array.shape[0]
162    )
163    mat = ncnn.Mat(4, 5, 6)
164    array = np.array(mat)
165    assert (
166        mat.dims == array.ndim
167        and mat.w == array.shape[2]
168        and mat.h == array.shape[1]
169        and mat.c == array.shape[0]
170    )
171
172    mat = ncnn.Mat(1, elemsize=1)
173    array = np.array(mat)
174    assert array.dtype == np.int8
175    mat = ncnn.Mat(1, elemsize=2)
176    array = np.array(mat)
177    assert array.dtype == np.float16
178    # pybind11 def_buffer throw bug
179    # with pytest.raises(RuntimeError) as execinfo:
180    #     mat = ncnn.Mat(1, elemsize=3)
181    #     array = np.array(mat)
182    #     assert "convert ncnn.Mat to numpy.ndarray only elemsize 1, 2, 4 support now, but given 3" in str(
183    #         execinfo.value
184    #     )
185    assert array.dtype == np.float16
186    mat = ncnn.Mat(1, elemsize=4)
187    array = np.array(mat)
188    assert array.dtype == np.float32
189
190    mat = np.random.randint(0, 128, size=(12,)).astype(np.uint8)
191    array = np.array(mat)
192    assert (mat == array).all()
193    mat = np.random.rand(12).astype(np.float32)
194    array = np.array(mat)
195    assert (mat == array).all()
196    mat = np.random.randint(0, 128, size=(12, 11)).astype(np.uint8)
197    array = np.array(mat)
198    assert (mat == array).all()
199    mat = np.random.rand(12, 11).astype(np.float32)
200    array = np.array(mat)
201    assert (mat == array).all()
202    mat = np.random.randint(0, 256, size=(12, 11, 3)).astype(np.uint8)
203    array = np.array(mat)
204    assert (mat == array).all()
205    mat = np.random.rand(12, 11, 3).astype(np.float32)
206    array = np.array(mat)
207    assert (mat == array).all()
208
209
210def test_fill():
211    mat = ncnn.Mat(1)
212    mat.fill(1.0)
213    array = np.array(mat)
214    assert np.abs(array[0] - 1.0) < sys.float_info.min
215
216
217def test_clone():
218    mat1 = ncnn.Mat(1)
219    mat2 = mat1.clone()
220    assert mat1.dims == mat2.dims and mat1.w == mat2.w
221
222    mat1 = ncnn.Mat(2, 3)
223    mat2 = mat1.clone()
224    assert mat1.dims == mat2.dims and mat1.w == mat2.w and mat1.h == mat2.h
225
226    mat1 = ncnn.Mat(4, 5, 6)
227    mat2 = mat1.clone()
228    assert (
229        mat1.dims == mat2.dims
230        and mat1.w == mat2.w
231        and mat1.h == mat2.h
232        and mat1.c == mat2.c
233    )
234
235    mat1 = ncnn.Mat((1,))
236    mat2 = mat1.clone()
237    assert mat1.dims == mat2.dims and mat1.w == mat2.w
238
239    mat1 = ncnn.Mat((2, 3))
240    mat2 = mat1.clone()
241    assert mat1.dims == mat2.dims and mat1.w == mat2.w and mat1.h == mat2.h
242
243    mat1 = ncnn.Mat((4, 5, 6))
244    mat2 = mat1.clone()
245    assert (
246        mat1.dims == mat2.dims
247        and mat1.w == mat2.w
248        and mat1.h == mat2.h
249        and mat1.c == mat2.c
250    )
251
252
253def test_clone_from():
254    mat2 = ncnn.Mat()
255
256    mat1 = ncnn.Mat(1)
257    mat2.clone_from(mat1)
258    assert mat1.dims == mat2.dims and mat1.w == mat2.w
259
260    mat1 = ncnn.Mat(2, 3)
261    mat2.clone_from(mat1)
262    assert mat1.dims == mat2.dims and mat1.w == mat2.w and mat1.h == mat2.h
263
264    mat1 = ncnn.Mat(4, 5, 6)
265    mat2.clone_from(mat1)
266    assert (
267        mat1.dims == mat2.dims
268        and mat1.w == mat2.w
269        and mat1.h == mat2.h
270        and mat1.c == mat2.c
271    )
272
273    mat1 = ncnn.Mat((1,))
274    mat2.clone_from(mat1)
275    assert mat1.dims == mat2.dims and mat1.w == mat2.w
276
277    mat1 = ncnn.Mat((2, 3))
278    mat2.clone_from(mat1)
279    assert mat1.dims == mat2.dims and mat1.w == mat2.w and mat1.h == mat2.h
280
281    mat1 = ncnn.Mat((4, 5, 6))
282    mat2.clone_from(mat1)
283    assert (
284        mat1.dims == mat2.dims
285        and mat1.w == mat2.w
286        and mat1.h == mat2.h
287        and mat1.c == mat2.c
288    )
289
290
291def test_reshape():
292    mat1 = ncnn.Mat()
293    mat2 = mat1.reshape(1)
294    assert mat2.dims == 0
295    mat2 = mat1.reshape(1, 1)
296    assert mat2.dims == 0
297    mat2 = mat1.reshape(1, 1, 1)
298    assert mat2.dims == 0
299
300    mat1 = ncnn.Mat(1)
301    mat2 = mat1.reshape(1, 1)
302    assert mat2.dims == 2 and mat2.w == 1 and mat2.h == 1
303    mat2 = mat1.reshape(1, 1, 1)
304    assert mat2.dims == 3 and mat2.w == 1 and mat2.h == 1 and mat2.c == 1
305
306    mat1 = ncnn.Mat(1, 2)
307    mat2 = mat1.reshape(2)
308    assert mat2.dims == 1 and mat2.w == 2
309    mat2 = mat1.reshape(2, 1)
310    assert mat2.dims == 2 and mat2.w == 2 and mat2.h == 1
311    mat2 = mat1.reshape(2, 1, 1)
312    assert mat2.dims == 3 and mat2.w == 2 and mat2.h == 1 and mat2.c == 1
313
314    mat1 = ncnn.Mat(1, 2, 3)
315    mat2 = mat1.reshape(6)
316    assert mat2.dims == 1 and mat2.w == 6
317    mat2 = mat1.reshape(2, 3)
318    assert mat2.dims == 2 and mat2.w == 2 and mat2.h == 3
319    mat2 = mat1.reshape(2, 3, 1)
320    assert mat2.dims == 3 and mat2.w == 2 and mat2.h == 3 and mat2.c == 1
321
322    mat1 = ncnn.Mat((1,))
323    mat2 = mat1.reshape((1, 1))
324    assert mat2.dims == 2 and mat2.w == 1 and mat2.h == 1
325    mat2 = mat1.reshape((1, 1, 1))
326    assert mat2.dims == 3 and mat2.w == 1 and mat2.h == 1 and mat2.c == 1
327
328    mat1 = ncnn.Mat((1, 2))
329    mat2 = mat1.reshape((2,))
330    assert mat2.dims == 1 and mat2.w == 2
331    mat2 = mat1.reshape((2, 1))
332    assert mat2.dims == 2 and mat2.w == 2 and mat2.h == 1
333    mat2 = mat1.reshape((2, 1, 1))
334    assert mat2.dims == 3 and mat2.w == 2 and mat2.h == 1 and mat2.c == 1
335
336    mat1 = ncnn.Mat((1, 2, 3))
337    mat2 = mat1.reshape((6,))
338    assert mat2.dims == 1 and mat2.w == 6
339    mat2 = mat1.reshape((2, 3))
340    assert mat2.dims == 2 and mat2.w == 2 and mat2.h == 3 and mat2.c == 1
341    mat2 = mat1.reshape((2, 3, 1))
342    assert mat2.dims == 3 and mat2.w == 2 and mat2.h == 3 and mat2.c == 1
343    with pytest.raises(RuntimeError) as execinfo:
344        mat1.reshape((1, 1, 1, 1))
345    assert "shape must be 1, 2 or 3 dims, not 4" in str(execinfo.value)
346
347
348def test_create():
349    mat = ncnn.Mat()
350    mat.create(1)
351    assert mat.dims == 1 and mat.w == 1
352    mat.create(2, 3)
353    assert mat.dims == 2 and mat.w == 2 and mat.h == 3
354    mat.create(4, 5, 6)
355    assert mat.dims == 3 and mat.w == 4 and mat.h == 5 and mat.c == 6
356
357    mat.create((1,))
358    assert mat.dims == 1 and mat.w == 1
359    mat.create((2, 3))
360    assert mat.dims == 2 and mat.w == 2 and mat.h == 3
361    mat.create((4, 5, 6))
362    assert mat.dims == 3 and mat.w == 4 and mat.h == 5 and mat.c == 6
363    mat.create((7, 8, 9), elemsize=4)
364
365
366def test_create_like():
367    mat2 = ncnn.Mat()
368
369    mat1 = ncnn.Mat(1)
370    mat2.create_like(mat1)
371    assert mat1.dims == mat2.dims and mat1.w == mat2.w
372    mat1 = ncnn.Mat(2, 3)
373    mat2.create_like(mat1)
374    assert mat1.dims == mat2.dims and mat1.w == mat2.w and mat1.h == mat2.h
375    mat1 = ncnn.Mat(4, 5, 6)
376    mat2.create_like(mat1)
377    assert (
378        mat1.dims == mat2.dims
379        and mat1.w == mat2.w
380        and mat1.h == mat2.h
381        and mat1.c == mat2.c
382    )
383
384
385def test_addref_release():
386    mat = ncnn.Mat(1)
387    assert mat.refcount == 1
388
389    mat.addref()
390    assert mat.refcount == 2
391
392    mat.release()
393    assert mat.refcount == None
394
395
396def test_empty():
397    mat = ncnn.Mat()
398    assert mat.empty() == True
399
400    mat = ncnn.Mat(1)
401    assert mat.empty() == False
402
403
404def test_total():
405    mat = ncnn.Mat(1)
406    assert mat.total() == 1
407    mat = ncnn.Mat(2, 3)
408    assert mat.total() == 2 * 3
409    mat = ncnn.Mat(4, 5, 6)
410    assert mat.total() == 4 * 5 * 6
411
412
413def test_elembits():
414    mat = ncnn.Mat(1, elemsize=1, elempack=1)
415    assert mat.elembits() == 8
416    mat = ncnn.Mat(2, elemsize=2, elempack=1)
417    assert mat.elembits() == 16
418    mat = ncnn.Mat(3, elemsize=4, elempack=1)
419    assert mat.elembits() == 32
420
421
422def test_shape():
423    mat = ncnn.Mat(1)
424    shape = mat.shape()
425    assert shape.dims == 1 and shape.w == 1
426    mat = ncnn.Mat(2, 3)
427    shape = mat.shape()
428    assert shape.dims == 2 and shape.w == 2 and shape.h == 3
429    mat = ncnn.Mat(4, 5, 6)
430    shape = mat.shape()
431    assert shape.dims == 3 and shape.w == 4 and shape.h == 5 and shape.c == 6
432
433
434def test_channel_row():
435    mat = ncnn.Mat(2, 3, 4)
436    mat.fill(4.0)
437    channel = mat.channel(1)
438    assert channel.dims == 2 and channel.w == 2 and channel.h == 3 and channel.c == 1
439
440    row = channel.row(1)
441    assert len(row) == 2 and np.abs(row[0] - 4.0) < sys.float_info.min
442
443
444def test_channel_range():
445    mat = ncnn.Mat(1, 2, 3)
446    channel_range = mat.channel_range(0, 2)
447    assert (
448        channel_range.dims == 3
449        and channel_range.w == 1
450        and channel_range.h == 2
451        and channel_range.c == 2
452    )
453
454
455def test_row_range():
456    mat = ncnn.Mat(1, 2)
457    row_range = mat.row_range(0, 2)
458    assert row_range.dims == 2 and row_range.w == 1 and row_range.h == 2
459
460
461def test_range():
462    mat = ncnn.Mat(2)
463    range = mat.range(0, 2)
464    assert range.dims == 1 and range.w == 2
465
466
467def test_getitem_setitem():
468    mat = ncnn.Mat(2)
469    mat.fill(1)
470    assert (
471        np.abs(mat[0] - 1.0) < sys.float_info.min
472        and np.abs(mat[1] - 1.0) < sys.float_info.min
473    )
474
475    mat[0] = 2.0
476    assert (
477        np.abs(mat[0] - 2.0) < sys.float_info.min
478        and np.abs(mat[1] - 1.0) < sys.float_info.min
479    )
480
481
482def test_from_pixels():
483    pixels = np.random.randint(0, 256, size=(300, 400, 3)).astype(np.uint8)  # hwc
484    mat = ncnn.Mat.from_pixels(pixels, ncnn.Mat.PixelType.PIXEL_RGB, 400, 300)  # chw
485    assert mat.dims == 3 and mat.w == 400 and mat.h == 300 and mat.c == 3
486    assert pixels[0, 0, 0] == mat.channel(0).row(0)[0]
487    assert pixels[200, 150, 1] == mat.channel(1).row(200)[150]
488    assert pixels[299, 399, 2] == mat.channel(2).row(299)[399]
489
490    pixels = np.random.randint(0, 256, size=(300, 500, 3)).astype(np.uint8)  # hwc
491    mat = ncnn.Mat.from_pixels(
492        pixels, ncnn.Mat.PixelType.PIXEL_RGB, 400, 300, stride=500 * 3
493    )  # chw
494    assert mat.dims == 3 and mat.w == 400 and mat.h == 300 and mat.c == 3
495    assert pixels[0, 0, 0] == mat.channel(0).row(0)[0]
496    assert pixels[200, 150, 1] == mat.channel(1).row(200)[150]
497    assert pixels[299, 399, 2] == mat.channel(2).row(299)[399]
498
499
500def test_from_pixels_resize():
501    pixels = np.random.randint(0, 256, size=(300, 400, 3)).astype(np.uint8)  # hwc
502    mat = ncnn.Mat.from_pixels_resize(
503        pixels, ncnn.Mat.PixelType.PIXEL_BGR2RGB, 400, 300, 200, 150
504    )  # chw
505    assert mat.dims == 3 and mat.w == 200 and mat.h == 150 and mat.c == 3
506
507    pixels = np.random.randint(0, 256, size=(300, 400, 3)).astype(np.uint8)  # hwc
508    mat = ncnn.Mat.from_pixels_resize(
509        pixels, ncnn.Mat.PixelType.PIXEL_BGR2RGB, 400, 300, 400, 300
510    )  # chw
511    assert mat.dims == 3 and mat.w == 400 and mat.h == 300 and mat.c == 3
512    assert pixels[0, 0, 0] == mat.channel(2).row(0)[0]
513    assert pixels[200, 150, 1] == mat.channel(1).row(200)[150]
514    assert pixels[299, 399, 2] == mat.channel(0).row(299)[399]
515
516    pixels = np.random.randint(0, 256, size=(300, 500, 3)).astype(np.uint8)  # hwc
517    mat = ncnn.Mat.from_pixels_resize(
518        pixels, ncnn.Mat.PixelType.PIXEL_BGR2RGB, 400, 300, 500 * 3, 200, 150
519    )  # chw
520    assert mat.dims == 3 and mat.w == 200 and mat.h == 150 and mat.c == 3
521
522    pixels = np.random.randint(0, 256, size=(300, 500, 3)).astype(np.uint8)  # hwc
523    mat = ncnn.Mat.from_pixels_resize(
524        pixels, ncnn.Mat.PixelType.PIXEL_BGR2RGB, 400, 300, 500 * 3, 400, 300
525    )  # chw
526    assert mat.dims == 3 and mat.w == 400 and mat.h == 300 and mat.c == 3
527    assert pixels[0, 0, 0] == mat.channel(2).row(0)[0]
528    assert pixels[200, 150, 1] == mat.channel(1).row(200)[150]
529    assert pixels[299, 399, 2] == mat.channel(0).row(299)[399]
530
531
532def test_from_pixels_roi():
533    pixels = np.random.randint(0, 256, size=(300, 400, 3)).astype(np.uint8)  # hwc
534    mat = ncnn.Mat.from_pixels_roi(
535        pixels, ncnn.Mat.PixelType.PIXEL_RGB, 400, 300, 100, 75, 200, 150
536    )  # chw
537    assert mat.dims == 3 and mat.w == 200 and mat.h == 150 and mat.c == 3
538    assert pixels[75, 100, 0] == mat.channel(0).row(0)[0]
539    assert pixels[150, 200, 1] == mat.channel(1).row(75)[100]
540    assert pixels[224, 299, 2] == mat.channel(2).row(149)[199]
541
542    pixels = np.random.randint(0, 256, size=(300, 500, 3)).astype(np.uint8)  # hwc
543    mat = ncnn.Mat.from_pixels_roi(
544        pixels, ncnn.Mat.PixelType.PIXEL_RGB, 400, 300, 500 * 3, 100, 75, 200, 150
545    )  # chw
546    assert mat.dims == 3 and mat.w == 200 and mat.h == 150 and mat.c == 3
547    assert pixels[75, 100, 0] == mat.channel(0).row(0)[0]
548    assert pixels[150, 200, 1] == mat.channel(1).row(75)[100]
549    assert pixels[224, 299, 2] == mat.channel(2).row(149)[199]
550
551
552def test_from_pixels_roi_resize():
553    pixels = np.random.randint(0, 256, size=(300, 400, 3)).astype(np.uint8)  # hwc
554    mat = ncnn.Mat.from_pixels_roi_resize(
555        pixels, ncnn.Mat.PixelType.PIXEL_RGB, 400, 300, 100, 75, 200, 150, 100, 75
556    )  # chw
557    assert mat.dims == 3 and mat.w == 100 and mat.h == 75 and mat.c == 3
558
559    pixels = np.random.randint(0, 256, size=(300, 500, 3)).astype(np.uint8)  # hwc
560    mat = ncnn.Mat.from_pixels_roi_resize(
561        pixels,
562        ncnn.Mat.PixelType.PIXEL_RGB,
563        400,
564        300,
565        500 * 3,
566        100,
567        75,
568        200,
569        150,
570        100,
571        75,
572    )  # chw
573    assert mat.dims == 3 and mat.w == 100 and mat.h == 75 and mat.c == 3
574
575
576def test_substract_mean_normalize():
577    pixels = np.random.randint(0, 256, size=(300, 400, 3)).astype(np.uint8)  # hwc
578    mean_vals = [127.5, 127.5, 127.5]
579    norm_vals = [0.007843, 0.007843, 0.007843]
580
581    mat = ncnn.Mat.from_pixels(pixels, ncnn.Mat.PixelType.PIXEL_RGB, 400, 300)  # chw
582    mat.substract_mean_normalize([], norm_vals)
583    assert np.abs(pixels[0, 0, 0] * 0.007843 - mat.channel(0).row(0)[0]) < 1e-5
584
585    mat = ncnn.Mat.from_pixels(pixels, ncnn.Mat.PixelType.PIXEL_RGB, 400, 300)  # chw
586    mat.substract_mean_normalize(mean_vals, [])
587    assert np.abs((pixels[0, 0, 0] - 127.5) - mat.channel(0).row(0)[0]) < 1e-5
588
589    mat = ncnn.Mat.from_pixels(pixels, ncnn.Mat.PixelType.PIXEL_RGB, 400, 300)  # chw
590    mat.substract_mean_normalize(mean_vals, norm_vals)
591    assert (
592        np.abs((pixels[0, 0, 0] - 127.5) * 0.007843 - mat.channel(0).row(0)[0]) < 1e-5
593    )
594