我在opencvandroid2.4.11的例子下工作,它使用摄像头检测人脸。 我不是在找到的脸上画一个矩形,而是在脸上画一个蒙版(png图像)。 但是为了在脸上显示图像,png图像的背景是黑色的,并且是透明的。在
在FdActivity.java在
public void onCameraViewStarted(int width, int height) {
mGray = new Mat();
mRgba = new Mat();
//Load my mask png
Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.mask_1);
mask = new Mat();
Utils.bitmapToMat(image, mask);
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
mGray = inputFrame.gray();
if (mAbsoluteFaceSize == 0) {
int height = mGray.rows();
if (Math.round(height * mRelativeFaceSize) > 0) {
mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
}
mNativeDetector.setMinFaceSize(mAbsoluteFaceSize);
}
MatOfRect faces = new MatOfRect();
if (mDetectorType == JAVA_DETECTOR) {
if (mJavaDetector != null)
mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2,
new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());
}
else if (mDetectorType == NATIVE_DETECTOR) {
if (mNativeDetector != null)
mNativeDetector.detect(mGray, faces);
}
else {
Log.e(TAG, "Detection method is not selected!");
}
Rect[] facesArray = faces.toArray();
for (int i = 0; i < facesArray.length; i++) {
overlayImage(mRgba, mask, facesArray[i]);
}
return mRgba;
}
public Mat overlayImage(Mat background, Mat foregroundMask, Rect faceRect)
{
Mat mask = new Mat();
Imgproc.resize(this.mask, mask, faceRect.size());
Mat source = new Mat();
Imgproc.resize(foregroundMask, source, background.size());
mask.copyTo( background.submat( new Rect((int) faceRect.tl().x, (int) faceRect.tl().y, mask.cols(), mask.rows())) );
source.release();
mask.release();
return background;
}
注意:我将解释一般原理并给出一个Python实现示例,因为我没有设置Android开发环境。将其移植到Java应该相当简单。请将代码作为单独的答案发布。在
您需要执行与
addWeighted
操作类似的操作,即操作但是,在你的例子中,α需要是一个矩阵(也就是说,我们需要不同的每像素混合系数)。在
示例图像
让我们用一些示例图像来说明这一点。我们可以使用Lena图像作为示例面:
此图像作为透明覆盖:
这张图片是一张没有透明度的覆盖图:
混合矩阵
为了获得α矩阵,我们可以使用阈值法确定前景(覆盖)和背景(面部)遮罩,或者使用输入图像中的alpha通道(如果可用)。在
对值在0.0范围内的浮点图像执行此操作非常有用。。1.0条。然后我们可以将两个面具之间的关系表示为
也就是说,两个面具加在一起就得到了所有的面具。在
对于RGBA格式的覆盖图像,我们得到以下前景和背景遮罩:
当我们使用RGB格式的阈值、腐蚀和模糊时,我们得到了以下前景和背景遮罩:
加权和
现在我们可以计算两个加权部分:
^{pr2}$对于RGBA覆盖,前景和背景部分如下所示:
对于RGB覆盖,前景和背景部分如下所示:
最后将它们相加,将图像转换回0-255范围内的8位整数。在
操作结果如下(分别为RGBA和RGB覆盖):
代码示例-RGB覆盖
代码示例-RGBA覆盖
相关问题 更多 >
编程相关推荐