1
1
using OpenCVForUnity . CoreModule ;
2
2
using OpenCVForUnity . ImgprocModule ;
3
+ using OpenCVForUnity . UnityUtils ;
3
4
using System ;
4
5
5
6
namespace NatCamWithOpenCVForUnityExample
@@ -9,14 +10,58 @@ public class ComicFilter
9
10
{
10
11
11
12
Mat grayMat ;
12
- Mat lineMat ;
13
13
Mat maskMat ;
14
- Mat bgMat ;
14
+ Mat screentoneMat ;
15
15
Mat grayDstMat ;
16
- byte [ ] grayPixels ;
17
- byte [ ] maskPixels ;
18
16
19
- public void Process ( Mat src , Mat dst )
17
+ Mat grayLUT ;
18
+ Mat contrastAdjustmentsLUT ;
19
+ Mat kernel_dilate ;
20
+ Mat kernel_erode ;
21
+ Size blurSize ;
22
+ int brackThresh ;
23
+ bool drawMainLine ;
24
+ bool useNoiseFilter ;
25
+
26
+
27
+ public ComicFilter ( int brackThresh = 60 , int grayThresh = 120 , int thickness = 5 , bool useNoiseFilter = true )
28
+ {
29
+ this . brackThresh = brackThresh ;
30
+ this . drawMainLine = ( thickness != 0 ) ;
31
+ this . useNoiseFilter = useNoiseFilter ;
32
+
33
+ grayLUT = new Mat ( 1 , 256 , CvType . CV_8UC1 ) ;
34
+ byte [ ] lutArray = new byte [ 256 ] ;
35
+ for ( int i = 0 ; i < lutArray . Length ; i ++ )
36
+ {
37
+ if ( brackThresh <= i && i < grayThresh )
38
+ lutArray [ i ] = 255 ;
39
+ }
40
+ Utils . copyToMat ( lutArray , grayLUT ) ;
41
+
42
+ if ( drawMainLine )
43
+ {
44
+ kernel_dilate = new Mat ( thickness , thickness , CvType . CV_8UC1 , new Scalar ( 1 ) ) ;
45
+
46
+ int erode = ( thickness >= 5 ) ? 2 : 1 ;
47
+ kernel_erode = new Mat ( erode , erode , CvType . CV_8UC1 , new Scalar ( 1 ) ) ;
48
+
49
+ int blur = ( thickness >= 4 ) ? thickness - 1 : 3 ;
50
+ blurSize = new Size ( blur , blur ) ;
51
+
52
+ contrastAdjustmentsLUT = new Mat ( 1 , 256 , CvType . CV_8UC1 ) ;
53
+ byte [ ] contrastAdjustmentsLUTArray = new byte [ 256 ] ;
54
+ for ( int i = 0 ; i < contrastAdjustmentsLUTArray . Length ; i ++ )
55
+ {
56
+ int a = ( int ) ( i * 1.5f ) ;
57
+ contrastAdjustmentsLUTArray [ i ] = ( a > byte . MaxValue ) ? ( byte ) 255 : ( byte ) a ;
58
+
59
+ }
60
+ Utils . copyToMat ( contrastAdjustmentsLUTArray , contrastAdjustmentsLUT ) ;
61
+ }
62
+ }
63
+
64
+ public void Process ( Mat src , Mat dst , bool isBGR = false )
20
65
{
21
66
if ( src == null )
22
67
throw new ArgumentNullException ( "src == null" ) ;
@@ -27,81 +72,105 @@ public void Process(Mat src, Mat dst)
27
72
{
28
73
grayMat . Dispose ( ) ;
29
74
grayMat = null ;
30
- lineMat . Dispose ( ) ;
31
- lineMat = null ;
32
75
maskMat . Dispose ( ) ;
33
76
maskMat = null ;
34
- bgMat . Dispose ( ) ;
35
- bgMat = null ;
77
+ screentoneMat . Dispose ( ) ;
78
+ screentoneMat = null ;
36
79
grayDstMat . Dispose ( ) ;
37
80
grayDstMat = null ;
38
-
39
- grayPixels = null ;
40
- maskPixels = null ;
41
81
}
42
82
grayMat = grayMat ?? new Mat ( src . height ( ) , src . width ( ) , CvType . CV_8UC1 ) ;
43
- lineMat = lineMat ?? new Mat ( src . height ( ) , src . width ( ) , CvType . CV_8UC1 ) ;
44
83
maskMat = maskMat ?? new Mat ( src . height ( ) , src . width ( ) , CvType . CV_8UC1 ) ;
45
- //create a striped background.
46
- bgMat = new Mat ( src . height ( ) , src . width ( ) , CvType . CV_8UC1 , new Scalar ( 255 ) ) ;
47
- for ( int i = 0 ; i < bgMat . rows ( ) * 2.5f ; i = i + 4 )
84
+ grayDstMat = grayDstMat ?? new Mat ( src . height ( ) , src . width ( ) , CvType . CV_8UC1 ) ;
85
+
86
+ if ( screentoneMat == null )
87
+ {
88
+ // create a striped screentone.
89
+ screentoneMat = new Mat ( src . height ( ) , src . width ( ) , CvType . CV_8UC1 , new Scalar ( 255 ) ) ;
90
+ for ( int i = 0 ; i < screentoneMat . rows ( ) * 2.5f ; i = i + 4 )
91
+ {
92
+ Imgproc . line ( screentoneMat , new Point ( 0 , 0 + i ) , new Point ( screentoneMat . cols ( ) , - screentoneMat . cols ( ) + i ) , new Scalar ( 0 ) , 1 ) ;
93
+ }
94
+ }
95
+
96
+ if ( src . type ( ) == CvType . CV_8UC1 )
48
97
{
49
- Imgproc . line ( bgMat , new Point ( 0 , 0 + i ) , new Point ( bgMat . cols ( ) , - bgMat . cols ( ) + i ) , new Scalar ( 0 ) , 1 ) ;
98
+ src . copyTo ( grayMat ) ;
99
+ }
100
+ else if ( dst . type ( ) == CvType . CV_8UC3 )
101
+ {
102
+ Imgproc . cvtColor ( src , grayMat , ( isBGR ) ? Imgproc . COLOR_BGR2GRAY : Imgproc . COLOR_RGB2GRAY ) ;
103
+ }
104
+ else
105
+ {
106
+ Imgproc . cvtColor ( src , grayMat , ( isBGR ) ? Imgproc . COLOR_BGRA2GRAY : Imgproc . COLOR_RGBA2GRAY ) ;
50
107
}
51
- grayDstMat = grayDstMat ?? new Mat ( src . height ( ) , src . width ( ) , CvType . CV_8UC1 ) ;
52
108
53
- grayPixels = grayPixels ?? new byte [ grayMat . cols ( ) * grayMat . rows ( ) * grayMat . channels ( ) ] ;
54
- maskPixels = maskPixels ?? new byte [ maskMat . cols ( ) * maskMat . rows ( ) * maskMat . channels ( ) ] ;
55
109
110
+ // binarize.
111
+ Imgproc . threshold ( grayMat , grayDstMat , brackThresh , 255.0 , Imgproc . THRESH_BINARY ) ;
56
112
57
- Imgproc . cvtColor ( src , grayMat , Imgproc . COLOR_RGBA2GRAY ) ;
58
- bgMat . copyTo ( grayDstMat ) ;
59
- Imgproc . GaussianBlur ( grayMat , lineMat , new Size ( 3 , 3 ) , 0 ) ;
60
- grayMat . get ( 0 , 0 , grayPixels ) ;
113
+ // draw striped screentone.
114
+ Core . LUT ( grayMat , grayLUT , maskMat ) ;
115
+ screentoneMat . copyTo ( grayDstMat , maskMat ) ;
61
116
62
- for ( int i = 0 ; i < grayPixels . Length ; i ++ )
117
+ // draw main line.
118
+ if ( drawMainLine )
63
119
{
64
- maskPixels [ i ] = 0 ;
65
- if ( grayPixels [ i ] < 70 )
120
+ Core . LUT ( grayMat , contrastAdjustmentsLUT , maskMat ) ; // = grayMat.convertTo(maskMat, -1, 1.5, 0);
121
+
122
+ if ( useNoiseFilter )
66
123
{
67
- grayPixels [ i ] = 0 ;
68
- maskPixels [ i ] = 1 ;
124
+ Imgproc . blur ( maskMat , grayMat , blurSize ) ;
125
+ Imgproc . dilate ( grayMat , maskMat , kernel_dilate ) ;
69
126
}
70
- else if ( 70 <= grayPixels [ i ] && grayPixels [ i ] < 120 )
127
+ else
71
128
{
72
- grayPixels [ i ] = 100 ;
129
+ Imgproc . dilate ( maskMat , grayMat , kernel_dilate ) ;
130
+ }
131
+ Core . absdiff ( grayMat , maskMat , grayMat ) ;
132
+ Imgproc . threshold ( grayMat , maskMat , 25 , 255.0 , Imgproc . THRESH_BINARY ) ;
133
+ if ( useNoiseFilter )
134
+ {
135
+ Imgproc . erode ( maskMat , grayMat , kernel_erode ) ;
136
+ Core . bitwise_not ( grayMat , maskMat ) ;
137
+ maskMat . copyTo ( grayDstMat , grayMat ) ;
73
138
}
74
139
else
75
140
{
76
- grayPixels [ i ] = 255 ;
77
- maskPixels [ i ] = 1 ;
141
+ Core . bitwise_not ( maskMat , grayMat ) ;
142
+ grayMat . copyTo ( grayDstMat , maskMat ) ;
78
143
}
79
144
}
80
145
81
- grayMat . put ( 0 , 0 , grayPixels ) ;
82
- maskMat . put ( 0 , 0 , maskPixels ) ;
83
- grayMat . copyTo ( grayDstMat , maskMat ) ;
84
-
85
- Imgproc . Canny ( lineMat , lineMat , 20 , 120 ) ;
86
- lineMat . copyTo ( maskMat ) ;
87
- Core . bitwise_not ( lineMat , lineMat ) ;
88
- lineMat . copyTo ( grayDstMat , maskMat ) ;
89
146
90
- Imgproc . cvtColor ( grayDstMat , dst , Imgproc . COLOR_GRAY2RGBA ) ;
147
+ if ( dst . type ( ) == CvType . CV_8UC1 )
148
+ {
149
+ grayDstMat . copyTo ( dst ) ;
150
+ }
151
+ else if ( dst . type ( ) == CvType . CV_8UC3 )
152
+ {
153
+ Imgproc . cvtColor ( grayDstMat , dst , ( isBGR ) ? Imgproc . COLOR_GRAY2BGR : Imgproc . COLOR_GRAY2RGB ) ;
154
+ }
155
+ else
156
+ {
157
+ Imgproc . cvtColor ( grayDstMat , dst , ( isBGR ) ? Imgproc . COLOR_GRAY2BGRA : Imgproc . COLOR_GRAY2RGBA ) ;
158
+ }
91
159
}
92
160
93
161
public void Dispose ( )
94
162
{
95
- foreach ( var mat in new [ ] { grayMat , lineMat , maskMat , bgMat , grayDstMat } )
96
- if ( mat != null )
97
- maskMat . Dispose ( ) ;
163
+ foreach ( var mat in new [ ] { grayMat , maskMat , screentoneMat , grayDstMat , grayLUT , kernel_dilate , kernel_erode , contrastAdjustmentsLUT } )
164
+ if ( mat != null ) mat . Dispose ( ) ;
165
+
98
166
grayDstMat =
99
- bgMat =
167
+ screentoneMat =
100
168
maskMat =
101
- lineMat =
102
- grayMat = null ;
103
- grayPixels =
104
- maskPixels = null ;
169
+ grayMat =
170
+ grayLUT =
171
+ kernel_dilate =
172
+ kernel_erode =
173
+ contrastAdjustmentsLUT = null ;
105
174
}
106
175
}
107
176
}
0 commit comments