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.Mat;
|
||||||
import org.opencv.core.MatOfPoint;
|
import org.opencv.core.MatOfPoint;
|
||||||
import org.opencv.core.Scalar;
|
import org.opencv.core.Scalar;
|
||||||
|
import org.opencv.core.Size;
|
||||||
import org.opencv.imgproc.Imgproc;
|
import org.opencv.imgproc.Imgproc;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -66,10 +67,6 @@ public class VideoDetector extends Detector {
|
|||||||
|
|
||||||
|
|
||||||
// Parameters
|
// 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 float ALARM_THRESHOLD = 0.5f; // Percent of pixels changed
|
||||||
private static final long START_DELAY = 1000; // milliseconds
|
private static final long START_DELAY = 1000; // milliseconds
|
||||||
private static final android.util.Size IMAGE_RES = new android.util.Size(640, 480);
|
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;
|
isDetectionRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission handling
|
* Permission handling
|
||||||
*/
|
*/
|
||||||
@ -172,29 +168,25 @@ public class VideoDetector extends Detector {
|
|||||||
Image image = imageProxy.getImage();
|
Image image = imageProxy.getImage();
|
||||||
assert image != null;
|
assert image != null;
|
||||||
|
|
||||||
if (image != null) {
|
Mat currentMat = extractYChannel(image);
|
||||||
|
|
||||||
Mat mat = extractYChannel(image);
|
Mat mat = currentMat.clone();
|
||||||
|
debugMat(mat, imageView2);
|
||||||
|
|
||||||
debugMat(mat, imageView2);
|
Mat processed = processImage(mat);
|
||||||
mat = processImage(mat);
|
|
||||||
debugMat(mat, imageView1);
|
|
||||||
|
|
||||||
int n = 0;
|
debugMat(processed, imageView1);
|
||||||
n = countNonZeroPixels(mat);
|
|
||||||
|
|
||||||
int pixelCount = image.getWidth() * image.getHeight();
|
int n = countNonZeroPixels(processed);
|
||||||
float percentChanged = (float)n / pixelCount;
|
int pixelCount = image.getWidth() * image.getHeight();
|
||||||
// report violation
|
float percentChanged = (float)n / pixelCount;
|
||||||
if (percentChanged * 100 > ALARM_THRESHOLD) {
|
// report violation
|
||||||
reportViolation("Video", n);
|
if (percentChanged * 100 > ALARM_THRESHOLD) {
|
||||||
}
|
reportViolation("Video", n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
imageProxy.close();
|
imageProxy.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Create Preview
|
// Create Preview
|
||||||
Preview preview = new Preview.Builder().build();
|
Preview preview = new Preview.Builder().build();
|
||||||
// Specify which Camera to use
|
// Specify which Camera to use
|
||||||
@ -217,26 +209,42 @@ public class VideoDetector extends Detector {
|
|||||||
* @param image: OpenCV Mat file that should be processed
|
* @param image: OpenCV Mat file that should be processed
|
||||||
*/
|
*/
|
||||||
private Mat processImage(Mat image){
|
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) {
|
if (previousImage == null) {
|
||||||
previousImage = image;
|
previousImage = preprocessed;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat mat = addGaussianBlur(image, BLUR_KERNEL_SIZE);
|
// Process Image
|
||||||
mat = thresholdPixels(mat, previousImage);
|
Mat processed = preprocessed.clone();
|
||||||
mat = dilateNonZero(mat, DILATE_KERNEL_SIZE);
|
processed = thresholdPixels(processed, previousImage, 25);
|
||||||
mat = thresholdContourArea(mat, CONTOUR_THRESHOLD);
|
processed = dilateBinaryMat(processed, new Size(3,3));
|
||||||
|
processed = dilateBinaryMat(processed, new Size(3,3));
|
||||||
|
processed = thresholdContourArea(processed, 500);
|
||||||
|
|
||||||
previousImage = image.clone();
|
previousImage = preprocessed.clone();
|
||||||
return mat;
|
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) {
|
private Mat extractYChannel(@NonNull Image img) {
|
||||||
ByteBuffer yBuffer = img.getPlanes()[0].getBuffer();
|
ByteBuffer yBuffer = img.getPlanes()[0].getBuffer();
|
||||||
byte[] yData = new byte[yBuffer.remaining()];
|
byte[] yData = new byte[yBuffer.remaining()];
|
||||||
@ -248,54 +256,14 @@ public class VideoDetector extends Detector {
|
|||||||
return yMat;
|
return yMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private Mat thresholdPixels(Mat inputMat, Mat previousImage, int threshold){
|
||||||
* Threshold all Pixels
|
|
||||||
* @param inputMat: Input Image
|
|
||||||
* @param previousImage: previous Image (openCV Mat)
|
|
||||||
* @return Binary Mat Image
|
|
||||||
*/
|
|
||||||
private Mat thresholdPixels(Mat inputMat, Mat previousImage){
|
|
||||||
Mat diffImage = new Mat();
|
Mat diffImage = new Mat();
|
||||||
Core.absdiff(inputMat, previousImage, diffImage);
|
Core.absdiff(inputMat, previousImage, diffImage);
|
||||||
|
|
||||||
Mat binaryMat = new Mat();
|
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;
|
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){
|
private Mat thresholdContourArea(Mat inputMat, float areaThreshold){
|
||||||
List<MatOfPoint> contours = new ArrayList<>();
|
List<MatOfPoint> contours = new ArrayList<>();
|
||||||
Mat hierarchy = new Mat();
|
Mat hierarchy = new Mat();
|
||||||
@ -315,11 +283,13 @@ public class VideoDetector extends Detector {
|
|||||||
return outputMat;
|
return outputMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private Mat dilateBinaryMat(Mat inputMat, Size kernelSize){
|
||||||
* Count all Pixels that are non Zero
|
Mat dilatedMat = new Mat();
|
||||||
* @param inputImage: Input Image in OpenCV Mat Format
|
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, kernelSize);
|
||||||
* @return Count of Pixels that are non zero
|
Imgproc.dilate(inputMat, dilatedMat, kernel);
|
||||||
*/
|
return dilatedMat;
|
||||||
|
}
|
||||||
|
|
||||||
private int countNonZeroPixels(Mat inputImage) {
|
private int countNonZeroPixels(Mat inputImage) {
|
||||||
if (inputImage != null)
|
if (inputImage != null)
|
||||||
return Core.countNonZero(inputImage);
|
return Core.countNonZero(inputImage);
|
||||||
@ -327,11 +297,8 @@ public class VideoDetector extends Detector {
|
|||||||
return 0;
|
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) {
|
private void debugMat(Mat mat, ImageView imageView) {
|
||||||
if (imageView == null || mat == null)
|
if (imageView == null || mat == null)
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user