1
- use crate :: core:: { ColourModel , Image } ;
2
1
use crate :: core:: padding:: * ;
2
+ use crate :: core:: { ColourModel , Image } ;
3
3
use crate :: processing:: Error ;
4
4
use ndarray:: prelude:: * ;
5
5
use ndarray:: { s, Zip } ;
16
16
type Data ;
17
17
18
18
/// Perform a convolution returning the resultant data
19
+ /// applies the default padding of zero padding
19
20
fn conv2d ( & self , kernel : ArrayView3 < Self :: Data > ) -> Result < Self , Error > ;
20
21
/// Performs the convolution inplace mutating the containers data
22
+ /// applies the default padding of zero padding
21
23
fn conv2d_inplace ( & mut self , kernel : ArrayView3 < Self :: Data > ) -> Result < ( ) , Error > ;
24
+ /// Perform a convolution returning the resultant data
25
+ /// applies the default padding of zero padding
26
+ fn conv2d_with_padding (
27
+ & self ,
28
+ kernel : ArrayView3 < Self :: Data > ,
29
+ strategy : & dyn PaddingStrategy < Self :: Data > ,
30
+ ) -> Result < Self , Error > ;
31
+ /// Performs the convolution inplace mutating the containers data
32
+ /// applies the default padding of zero padding
33
+ fn conv2d_inplace_with_padding (
34
+ & mut self ,
35
+ kernel : ArrayView3 < Self :: Data > ,
36
+ strategy : & dyn PaddingStrategy < Self :: Data > ,
37
+ ) -> Result < ( ) , Error > ;
22
38
}
23
39
24
40
fn kernel_centre ( rows : usize , cols : usize ) -> ( usize , usize ) {
34
50
type Data = T ;
35
51
36
52
fn conv2d ( & self , kernel : ArrayView3 < Self :: Data > ) -> Result < Self , Error > {
53
+ self . conv2d_with_padding ( kernel, & ZeroPadding { } )
54
+ }
55
+
56
+ fn conv2d_inplace ( & mut self , kernel : ArrayView3 < Self :: Data > ) -> Result < ( ) , Error > {
57
+ * self = self . conv2d_with_padding ( kernel, & ZeroPadding { } ) ?;
58
+ Ok ( ( ) )
59
+ }
60
+
61
+ fn conv2d_with_padding (
62
+ & self ,
63
+ kernel : ArrayView3 < Self :: Data > ,
64
+ strategy : & dyn PaddingStrategy < Self :: Data > ,
65
+ ) -> Result < Self , Error > {
37
66
if self . shape ( ) [ 2 ] != kernel. shape ( ) [ 2 ] {
38
67
Err ( Error :: ChannelDimensionMismatch )
39
68
} else {
45
74
46
75
if shape. 0 > 0 && shape. 1 > 0 {
47
76
let mut result = Self :: zeros ( shape) ;
48
- let tmp = self . pad ( ( row_offset, col_offset) , & ZeroPadding { } ) ;
77
+ let tmp = self . pad ( ( row_offset, col_offset) , strategy ) ;
49
78
50
79
Zip :: indexed ( tmp. windows ( kernel. dim ( ) ) ) . apply ( |( i, j, _) , window| {
51
80
let mult = & window * & kernel;
59
88
}
60
89
}
61
90
62
- fn conv2d_inplace ( & mut self , kernel : ArrayView3 < Self :: Data > ) -> Result < ( ) , Error > {
63
- * self = self . conv2d ( kernel) ?;
91
+ fn conv2d_inplace_with_padding (
92
+ & mut self ,
93
+ kernel : ArrayView3 < Self :: Data > ,
94
+ strategy : & dyn PaddingStrategy < Self :: Data > ,
95
+ ) -> Result < ( ) , Error > {
96
+ * self = self . conv2d_with_padding ( kernel, strategy) ?;
64
97
Ok ( ( ) )
65
98
}
66
99
}
@@ -82,6 +115,26 @@ where
82
115
fn conv2d_inplace ( & mut self , kernel : ArrayView3 < Self :: Data > ) -> Result < ( ) , Error > {
83
116
self . data . conv2d_inplace ( kernel)
84
117
}
118
+
119
+ fn conv2d_with_padding (
120
+ & self ,
121
+ kernel : ArrayView3 < Self :: Data > ,
122
+ strategy : & dyn PaddingStrategy < Self :: Data > ,
123
+ ) -> Result < Self , Error > {
124
+ let data = self . data . conv2d_with_padding ( kernel, strategy) ?;
125
+ Ok ( Self {
126
+ data,
127
+ model : PhantomData ,
128
+ } )
129
+ }
130
+
131
+ fn conv2d_inplace_with_padding (
132
+ & mut self ,
133
+ kernel : ArrayView3 < Self :: Data > ,
134
+ strategy : & dyn PaddingStrategy < Self :: Data > ,
135
+ ) -> Result < ( ) , Error > {
136
+ self . data . conv2d_inplace_with_padding ( kernel, strategy)
137
+ }
85
138
}
86
139
87
140
#[ cfg( test) ]
0 commit comments