前言
我们使用OpenCV+自己的人脸检测算法的时候,在视频图像中绘制出人脸框,会方便我们的开发和调试过程。
绘制人脸框的过程有:
- 打开摄像头,循环取帧数据
- 转为jpg格式,方便传输
- 人脸检测得到人脸框数据
- 按坐标填涂到Mat上
- 将Mat绘制到窗口
视频采集线程
private class ProcessThread extends Thread {
private VideoCapture mVideoCapture = null;
public static final int CAMERA_WIDTH = 640;
public static final int CAMERA_HEIGHT = 480;
// 存放jpg格式的数据
private MatOfByte mJpegMatOfByte = null;
// 人脸框着色,红色
private static final byte[] DRAW_COLOR = new byte[] {
(byte) 0,
(byte) 0,
(byte) 255
};
public ProcessThread() {
// 打开摄像头
mVideoCapture = new VideoCapture(0);
//mVideoCapture.set(Videoio.CAP_PROP_FRAME_WIDTH, 1280);
//mVideoCapture.set(Videoio.CAP_PROP_FRAME_HEIGHT, 720);
HighGui.namedWindow("采集");
}
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
Mat _imgMat = new Mat();
// 读取摄像头数据
if (!mVideoCapture.read(_imgMat)) {
Log.e(TAG, "ProcessThread: read ERROR");
_imgMat.release();
continue;
}
// 转为jpg格式,便于传输
mJpegMatOfByte = new MatOfByte();
Imgcodecs.imencode(".jpg", _imgMat, mJpegMatOfByte);
byte[] _jpegData = mJpegMatOfByte.toArray();
if (false) {
try (BufferedOutputStream _outputStream = new BufferedOutputStream(new FileOutputStream("save_" + System.currentTimeMillis() + ".jpg"))) {
_outputStream.write(_jpegData);
_outputStream.flush();
} catch (Exception e) {
// TODO: handle exception
Log.e(TAG, "output jpg file: " + e);
}
}
FaceRect _rect = new FaceRect();
_rect = Yourself.getRect();
drawFaceRectOnMat(_rect, _imgMat);
// 加载图像播放
HighGui.imshow("采集", _imgMat);
// 刷新帧
HighGui.waitKey(1);
// 释放内存
mJpegMatOfByte.release();
mJpegMatOfByte = null;
_imgMat.release();
}
}
private static void drawFaceRectOnMat(FaceRect rect, Mat mat) {
if (rect == null || rect.isEmpty()) {
return;
}
for (int i = rect.left; i < rect.left + 20; i++) {
for (int j = rect.top; j < rect.top + 3; j++) {
if (i >= 0 && i < CAMERA_WIDTH && j >= 0 && j < CAMERA_HEIGHT) {
mat.put(j, i, DRAW_COLOR);
}
}
}
for (int i = rect.left; i < rect.left + 3; i++) {
for (int j = rect.top; j < rect.top + 20; j++) {
if (i >= 0 && i < CAMERA_WIDTH && j >= 0 && j < CAMERA_HEIGHT) {
mat.put(j, i, DRAW_COLOR);
}
}
}
for (int i = rect.right; i > rect.right - 20; i--) {
for (int j = rect.top; j < rect.top + 3; j++) {
if (i >= 0 && i < CAMERA_WIDTH && j >= 0 && j < CAMERA_HEIGHT) {
mat.put(j, i, DRAW_COLOR);
}
}
}
for (int i = rect.right; i > rect.right - 3; i--) {
for (int j = rect.top; j < rect.top + 20; j++) {
if (i >= 0 && i < CAMERA_WIDTH && j >= 0 && j < CAMERA_HEIGHT) {
mat.put(j, i, DRAW_COLOR);
}
}
}
for (int i = rect.left; i < rect.left + 20; i++) {
for (int j = rect.bottom; j > rect.bottom - 3; j--) {
if (i >= 0 && i < CAMERA_WIDTH && j >= 0 && j < CAMERA_HEIGHT) {
mat.put(j, i, DRAW_COLOR);
}
}
}
for (int i = rect.left; i < rect.left + 3; i++) {
for (int j = rect.bottom; j > rect.bottom - 20; j--) {
if (i >= 0 && i < CAMERA_WIDTH && j >= 0 && j < CAMERA_HEIGHT) {
mat.put(j, i, DRAW_COLOR);
}
}
}
for (int i = rect.right; i > rect.right - 20; i--) {
for (int j = rect.bottom; j > rect.bottom - 3; j--) {
if (i >= 0 && i < CAMERA_WIDTH && j >= 0 && j < CAMERA_HEIGHT) {
mat.put(j, i, DRAW_COLOR);
}
}
}
for (int i = rect.right; i > rect.right - 3; i--) {
for (int j = rect.bottom; j > rect.bottom - 20; j--) {
if (i >= 0 && i < CAMERA_WIDTH && j >= 0 && j < CAMERA_HEIGHT) {
mat.put(j, i, DRAW_COLOR);
}
}
}
}
}
人脸框的类定义
/**
* 人脸框
*/
public static class FaceRect implements Cloneable {
public int left = 0;
public int top = 0;
public int right = 0;
public int bottom = 0;
public FaceRect() {
}
public FaceRect(int left, int top, int right, int bottom) {
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public int getHeight() {
return bottom - top + 1;
}
public int getWidth() {
return right - left + 1;
}
public boolean isEmpty() {
if (left == 0 && top == 0 && right == 0 && bottom == 0) {
return true;
}
return false;
}
public void reset() {
left = 0;
top = 0;
right = 0;
bottom = 0;
}
public String toString() {
return "(" + left + ", " + top + ")-" + "(" + right + ", " + bottom + ")";
}
@Override
protected FaceRect clone() {
// TODO Auto-generated method stub
return new FaceRect(left, top, right, bottom);
}
}