使用OpenCV在Android应用中检测运动和人脸

在开发Android应用时,一直在寻找一种简单的图像处理运动检测方法。OpenCV作为一个开源的计算机视觉和机器学习软件库,非常适合需求,因为它已经被移植到Android环境中。

OpenCV4Android提供了一个接口,可以访问手机内置的摄像头,以便捕获摄像头帧进行进一步处理。可以在官方的示例中查看代码是如何使用的。在应用中,捕获输入帧,然后使用库提供的算法进行运动检测。

使用代码

以下是使用OpenCV4Android进行运动检测的代码示例。

public Mat onCameraFrame(CvCameraViewFrame inputFrame) { if (isNotRealTimeProcessing()) { try { streamingLock.lock(); capturedFrame = inputFrame.rgba(); } finally { streamingLock.unlock(); } if (!frameProcessing && !isUploadInProgress) { frameProcessing = true; capturedFrame.copyTo(processingFrame); fireProcessingAction(ProcessingAction.PROCESS_FRAME); } return capturedFrame; } else { return processFrame(inputFrame.rgba()); } }

检测运动的一种简单方法是将帧转换为灰度,并计算帧之间的差异。

public final class BasicDetector extends BaseDetector implements IDetector { private static final String TAG = AppConfig.LOG_TAG_APP + ":BasicDetector"; public static final int N = 4; private Mat[] buf = null; private int last = 0; private List contours = new ArrayList(); private int threshold; private Mat hierarchy = new Mat(); public BasicDetector(int threshold) { this.threshold = threshold; } @Override public Mat detect(Mat source) { Size size = source.size(); int i, idx1 = last, idx2; Mat silh; if (buf == null || buf[0].width() != size.width || buf[0].height() != size.height) { if (buf == null) { buf = new Mat[N]; } for (i = 0; i < N; i++) { if (buf[i] != null) { buf[i].release(); buf[i] = null; } buf[i] = new Mat(size, CvType.CV_8UC1); buf[i] = Mat.zeros(size, CvType.CV_8UC1); } } Imgproc.cvtColor(source, buf[last], Imgproc.COLOR_BGR2GRAY); idx2 = (last + 1) % N; last = idx2; silh = buf[idx2]; Core.absdiff(buf[idx1], buf[idx2], silh); Imgproc.threshold(silh, silh, threshold, 255, Imgproc.THRESH_BINARY); contours.clear(); Imgproc.findContours(silh, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); Imgproc.drawContours(source, contours, -1, contourColor, contourThickness); return source; } }

另一种方法是使用背景减法技术来检测运动。

public final class BackgroundSubtractorDetector extends BaseDetector implements IDetector { private static final double LEARNING_RATE = 0.1; private static final int MIXTURES = 4; private static final int HISTORY = 3; private static final double BACKGROUND_RATIO = 0.8; private Mat buf = null; private BackgroundSubtractorMOG bg; private Mat fgMask = new Mat(); private List contours = new ArrayList(); private Mat hierarchy = new Mat(); public BackgroundSubtractorDetector() { bg = new BackgroundSubtractorMOG(HISTORY, MIXTURES, BACKGROUND_RATIO); } public BackgroundSubtractorDetector(double backgroundRatio) { bg = new BackgroundSubtractorMOG(HISTORY, MIXTURES, backgroundRatio / 100.0); } @Override public Mat detect(Mat source) { Size size = source.size(); if (buf == null || buf.width() != size.width || buf.height() != size.height) { if (buf == null) { buf = new Mat(size, CvType.CV_8UC1); buf = Mat.zeros(size, CvType.CV_8UC1); } } Imgproc.cvtColor(source, buf, Imgproc.COLOR_RGBA2RGB); bg.apply(buf, fgMask, LEARNING_RATE); Imgproc.erode(fgMask, fgMask, new Mat()); Imgproc.dilate(fgMask, fgMask, new Mat()); Imgproc.cvtColor(fgMask, silh, Imgproc.COLOR_GRAY2RGBA); contours.clear(); Imgproc.findContours(fgMask, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); Imgproc.drawContours(source, contours, -1, contourColor, contourThickness); return source; } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485