Skip to content

Commit 752b98d

Browse files
committed
v2.3.0_20190924
Updated OpenCVForUnity version to 2.3.7. Rewrote ComicFilter to improve processing efficiency.
1 parent aa3f860 commit 752b98d

File tree

6 files changed

+267
-139
lines changed

6 files changed

+267
-139
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using OpenCVForUnity.CoreModule;
22
using OpenCVForUnity.ImgprocModule;
3+
using OpenCVForUnity.UnityUtils;
34
using System;
45

56
namespace NatCamWithOpenCVForUnityExample
@@ -9,14 +10,58 @@ public class ComicFilter
910
{
1011

1112
Mat grayMat;
12-
Mat lineMat;
1313
Mat maskMat;
14-
Mat bgMat;
14+
Mat screentoneMat;
1515
Mat grayDstMat;
16-
byte[] grayPixels;
17-
byte[] maskPixels;
1816

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)
2065
{
2166
if (src == null)
2267
throw new ArgumentNullException("src == null");
@@ -27,81 +72,105 @@ public void Process(Mat src, Mat dst)
2772
{
2873
grayMat.Dispose();
2974
grayMat = null;
30-
lineMat.Dispose();
31-
lineMat = null;
3275
maskMat.Dispose();
3376
maskMat = null;
34-
bgMat.Dispose();
35-
bgMat = null;
77+
screentoneMat.Dispose();
78+
screentoneMat = null;
3679
grayDstMat.Dispose();
3780
grayDstMat = null;
38-
39-
grayPixels = null;
40-
maskPixels = null;
4181
}
4282
grayMat = grayMat ?? new Mat(src.height(), src.width(), CvType.CV_8UC1);
43-
lineMat = lineMat ?? new Mat(src.height(), src.width(), CvType.CV_8UC1);
4483
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)
4897
{
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);
50107
}
51-
grayDstMat = grayDstMat ?? new Mat(src.height(), src.width(), CvType.CV_8UC1);
52108

53-
grayPixels = grayPixels ?? new byte[grayMat.cols() * grayMat.rows() * grayMat.channels()];
54-
maskPixels = maskPixels ?? new byte[maskMat.cols() * maskMat.rows() * maskMat.channels()];
55109

110+
// binarize.
111+
Imgproc.threshold(grayMat, grayDstMat, brackThresh, 255.0, Imgproc.THRESH_BINARY);
56112

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);
61116

62-
for (int i = 0; i < grayPixels.Length; i++)
117+
// draw main line.
118+
if (drawMainLine)
63119
{
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)
66123
{
67-
grayPixels[i] = 0;
68-
maskPixels[i] = 1;
124+
Imgproc.blur(maskMat, grayMat, blurSize);
125+
Imgproc.dilate(grayMat, maskMat, kernel_dilate);
69126
}
70-
else if (70 <= grayPixels[i] && grayPixels[i] < 120)
127+
else
71128
{
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);
73138
}
74139
else
75140
{
76-
grayPixels[i] = 255;
77-
maskPixels[i] = 1;
141+
Core.bitwise_not(maskMat, grayMat);
142+
grayMat.copyTo(grayDstMat, maskMat);
78143
}
79144
}
80145

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);
89146

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+
}
91159
}
92160

93161
public void Dispose()
94162
{
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+
98166
grayDstMat =
99-
bgMat =
167+
screentoneMat =
100168
maskMat =
101-
lineMat =
102-
grayMat = null;
103-
grayPixels =
104-
maskPixels = null;
169+
grayMat =
170+
grayLUT =
171+
kernel_dilate =
172+
kernel_erode =
173+
contrastAdjustmentsLUT = null;
105174
}
106175
}
107176
}

Assets/NatCamWithOpenCVForUnityExample/Scripts/Utils/NatCamPreviewToMatHelper.cs

+9-25
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,13 @@
66
using System.Collections;
77
using UnityEngine;
88

9-
#if OPENCV_USE_UNSAFE_CODE && UNITY_2018_2_OR_NEWER
10-
using Unity.Collections.LowLevel.Unsafe;
11-
using Unity.Collections;
12-
#endif
13-
149
namespace NatCamWithOpenCVForUnity.UnityUtils.Helper
1510
{
1611
/// <summary>
1712
/// NatCamPreview to mat helper.
18-
/// v 1.0.7
13+
/// v 1.0.8
1914
/// Depends on NatCam version 2.3 or later.
20-
/// Depends on OpenCVForUnity version 2.3.3 or later.
15+
/// Depends on OpenCVForUnity version 2.3.7 or later.
2116
/// </summary>
2217
public class NatCamPreviewToMatHelper : WebCamTextureToMatHelper
2318
{
@@ -34,7 +29,6 @@ public override float requestedFPS
3429
}
3530
}
3631

37-
// protected byte[] pixelBuffer;
3832
protected bool didUpdateThisFrame = false;
3933

4034
protected CameraDevice natCamCameraDevice;
@@ -119,23 +113,22 @@ protected override IEnumerator _Initialize()
119113

120114
isInitWaiting = true;
121115

122-
123-
#if UNITY_ANDROID && !UNITY_EDITOR
124-
// Wait for one frame until ready to accurately reflects current screen orientation to the direction of a camera image.
125-
yield return null;
126-
#endif
127-
116+
#if (UNITY_IOS || UNITY_ANDROID) && !UNITY_EDITOR
128117
// Checks camera permission state.
129-
if (CameraDevice.GetDevices() == null)
118+
IEnumerator coroutine = hasUserAuthorizedCameraPermission();
119+
yield return coroutine;
120+
121+
if (!(bool)coroutine.Current)
130122
{
131123
isInitWaiting = false;
132124
initCoroutine = null;
133125

134126
if (onErrorOccurred != null)
135-
onErrorOccurred.Invoke(ErrorCode.CAMERA_DEVICE_NOT_EXIST);
127+
onErrorOccurred.Invoke(ErrorCode.CAMERA_PERMISSION_DENIED);
136128

137129
yield break;
138130
}
131+
#endif
139132

140133
// Creates the camera
141134
var devices = CameraDevice.GetDevices();
@@ -364,15 +357,7 @@ public override Mat GetMat()
364357
return (rotatedFrameMat != null) ? rotatedFrameMat : frameMat;
365358
}
366359

367-
#if OPENCV_USE_UNSAFE_CODE && UNITY_2018_2_OR_NEWER
368-
unsafe
369-
{
370-
var ptr = (IntPtr)NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(preview.GetRawTextureData<byte>());
371-
Utils.copyToMat(ptr, frameMat);
372-
}
373-
#else
374360
Utils.fastTexture2DToMat(preview, frameMat, false);
375-
#endif
376361

377362
FlipMat(frameMat, flipVertical, flipHorizontal);
378363
if (rotatedFrameMat != null)
@@ -454,7 +439,6 @@ protected override void ReleaseResources()
454439
natCamCameraDevice = null;
455440
preview = null;
456441

457-
// pixelBuffer = null;
458442
didUpdateThisFrame = false;
459443

460444
if (frameMat != null)

0 commit comments

Comments
 (0)