Fixed up Video detector
This commit is contained in:
parent
7ef0df48dd
commit
fb8bdcd895
@ -30,6 +30,7 @@ import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfPoint;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@ -66,10 +67,6 @@ public class VideoDetector extends Detector {
|
||||
|
||||
|
||||
// Parameters
|
||||
private static final float PIXEL_THRESHOLD = 40f; // Luminosity (brightness channel of YUV_420_888)
|
||||
private static final int BLUR_KERNEL_SIZE = 5;
|
||||
private static final int DILATE_KERNEL_SIZE = 5;
|
||||
private static final float CONTOUR_THRESHOLD = 250;
|
||||
private static final float ALARM_THRESHOLD = 0.5f; // Percent of pixels changed
|
||||
private static final long START_DELAY = 1000; // milliseconds
|
||||
private static final android.util.Size IMAGE_RES = new android.util.Size(640, 480);
|
||||
@ -140,7 +137,6 @@ public class VideoDetector extends Detector {
|
||||
isDetectionRunning = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Permission handling
|
||||
*/
|
||||
@ -172,17 +168,16 @@ public class VideoDetector extends Detector {
|
||||
Image image = imageProxy.getImage();
|
||||
assert image != null;
|
||||
|
||||
if (image != null) {
|
||||
|
||||
Mat mat = extractYChannel(image);
|
||||
Mat currentMat = extractYChannel(image);
|
||||
|
||||
Mat mat = currentMat.clone();
|
||||
debugMat(mat, imageView2);
|
||||
mat = processImage(mat);
|
||||
debugMat(mat, imageView1);
|
||||
|
||||
int n = 0;
|
||||
n = countNonZeroPixels(mat);
|
||||
Mat processed = processImage(mat);
|
||||
|
||||
debugMat(processed, imageView1);
|
||||
|
||||
int n = countNonZeroPixels(processed);
|
||||
int pixelCount = image.getWidth() * image.getHeight();
|
||||
float percentChanged = (float)n / pixelCount;
|
||||
// report violation
|
||||
@ -190,11 +185,8 @@ public class VideoDetector extends Detector {
|
||||
reportViolation("Video", n);
|
||||
}
|
||||
}
|
||||
}
|
||||
imageProxy.close();
|
||||
});
|
||||
|
||||
|
||||
// Create Preview
|
||||
Preview preview = new Preview.Builder().build();
|
||||
// Specify which Camera to use
|
||||
@ -217,26 +209,42 @@ public class VideoDetector extends Detector {
|
||||
* @param image: OpenCV Mat file that should be processed
|
||||
*/
|
||||
private Mat processImage(Mat image){
|
||||
|
||||
// Preprocess Image
|
||||
Mat preprocessed = image.clone();
|
||||
preprocessed = addGaussianBlur(preprocessed, new Size(21, 21));
|
||||
preprocessed = addBlur(preprocessed, new Size(3, 3));
|
||||
|
||||
if (previousImage == null) {
|
||||
previousImage = image;
|
||||
previousImage = preprocessed;
|
||||
return null;
|
||||
}
|
||||
|
||||
Mat mat = addGaussianBlur(image, BLUR_KERNEL_SIZE);
|
||||
mat = thresholdPixels(mat, previousImage);
|
||||
mat = dilateNonZero(mat, DILATE_KERNEL_SIZE);
|
||||
mat = thresholdContourArea(mat, CONTOUR_THRESHOLD);
|
||||
// Process Image
|
||||
Mat processed = preprocessed.clone();
|
||||
processed = thresholdPixels(processed, previousImage, 25);
|
||||
processed = dilateBinaryMat(processed, new Size(3,3));
|
||||
processed = dilateBinaryMat(processed, new Size(3,3));
|
||||
processed = thresholdContourArea(processed, 500);
|
||||
|
||||
previousImage = image.clone();
|
||||
return mat;
|
||||
previousImage = preprocessed.clone();
|
||||
return processed;
|
||||
}
|
||||
|
||||
|
||||
/** OpenCV helper methods **/
|
||||
private Mat addGaussianBlur(Mat inputMat, Size kernelSize){
|
||||
Mat outputMat = new Mat();
|
||||
Imgproc.GaussianBlur(inputMat, outputMat, kernelSize, 0);
|
||||
return outputMat;
|
||||
}
|
||||
|
||||
private Mat addBlur(Mat inputMat, Size kernelSize){
|
||||
Mat outputMat = new Mat();
|
||||
Imgproc.blur(inputMat, outputMat, kernelSize);
|
||||
return outputMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Android Image to OpenCV Mat file with only y-Channel
|
||||
*
|
||||
* @param img: Android Image
|
||||
* @return yChannel of Image in OpenCV Mat Format
|
||||
*/
|
||||
private Mat extractYChannel(@NonNull Image img) {
|
||||
ByteBuffer yBuffer = img.getPlanes()[0].getBuffer();
|
||||
byte[] yData = new byte[yBuffer.remaining()];
|
||||
@ -248,54 +256,14 @@ public class VideoDetector extends Detector {
|
||||
return yMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Threshold all Pixels
|
||||
* @param inputMat: Input Image
|
||||
* @param previousImage: previous Image (openCV Mat)
|
||||
* @return Binary Mat Image
|
||||
*/
|
||||
private Mat thresholdPixels(Mat inputMat, Mat previousImage){
|
||||
private Mat thresholdPixels(Mat inputMat, Mat previousImage, int threshold){
|
||||
Mat diffImage = new Mat();
|
||||
Core.absdiff(inputMat, previousImage, diffImage);
|
||||
|
||||
Mat binaryMat = new Mat();
|
||||
Imgproc.threshold(diffImage, binaryMat, VideoDetector.PIXEL_THRESHOLD, 255, Imgproc.THRESH_BINARY);
|
||||
|
||||
Imgproc.threshold(diffImage, binaryMat, threshold, 255, Imgproc.THRESH_BINARY);
|
||||
return binaryMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dilate Pixels of Binary Image
|
||||
* @param inputMat: Input Image
|
||||
* @param kernelSize: kernel Size
|
||||
* @return binary Image with dilated Pixels
|
||||
*/
|
||||
private Mat dilateNonZero(Mat inputMat, int kernelSize){
|
||||
Mat dilatedMat = new Mat();
|
||||
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new org.opencv.core.Size(kernelSize, kernelSize));
|
||||
Imgproc.dilate(inputMat, dilatedMat, kernel);
|
||||
return dilatedMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Gaussian Blur to OpenCV Mat Image
|
||||
* @param inputMat: Input Image
|
||||
* @param kernelSize: kernel Size
|
||||
* @return Mat Image
|
||||
*/
|
||||
private Mat addGaussianBlur(Mat inputMat, int kernelSize){
|
||||
Mat outputMat = new Mat();
|
||||
Imgproc.GaussianBlur(inputMat, outputMat, new org.opencv.core.Size(kernelSize, kernelSize), 0);
|
||||
return outputMat;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filter Contour Areas by Size
|
||||
* @param inputMat: Input Image
|
||||
* @param areaThreshold: Threshold
|
||||
* @return Binary Mat Image
|
||||
*/
|
||||
private Mat thresholdContourArea(Mat inputMat, float areaThreshold){
|
||||
List<MatOfPoint> contours = new ArrayList<>();
|
||||
Mat hierarchy = new Mat();
|
||||
@ -315,11 +283,13 @@ public class VideoDetector extends Detector {
|
||||
return outputMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all Pixels that are non Zero
|
||||
* @param inputImage: Input Image in OpenCV Mat Format
|
||||
* @return Count of Pixels that are non zero
|
||||
*/
|
||||
private Mat dilateBinaryMat(Mat inputMat, Size kernelSize){
|
||||
Mat dilatedMat = new Mat();
|
||||
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, kernelSize);
|
||||
Imgproc.dilate(inputMat, dilatedMat, kernel);
|
||||
return dilatedMat;
|
||||
}
|
||||
|
||||
private int countNonZeroPixels(Mat inputImage) {
|
||||
if (inputImage != null)
|
||||
return Core.countNonZero(inputImage);
|
||||
@ -327,11 +297,8 @@ public class VideoDetector extends Detector {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show OpenCV Mat on ImageView
|
||||
* @param mat: current OpenCV Mat Image
|
||||
* @param imageView: ImageView xml-Element
|
||||
*/
|
||||
|
||||
|
||||
private void debugMat(Mat mat, ImageView imageView) {
|
||||
if (imageView == null || mat == null)
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user