使用 Google Face Detection ML Kit 在现有照片周围绘制一个框
Posted
技术标签:
【中文标题】使用 Google Face Detection ML Kit 在现有照片周围绘制一个框【英文标题】:Drawing a Box Around Face To Existed Photos with Google Face Detection ML Kit 【发布时间】:2021-07-12 06:25:20 【问题描述】:我们在 android 中实现了用于人脸检测的 Android ML Kit。它的作用就像魅力一样,可以检测人脸。
问题:当检测到多个人脸时,我们想在检测到的人脸周围绘制矩形
我们做了什么:
已实现
implementation 'com.google.android.gms:play-services-mlkit-face-detection:16.1.5'
创建了一个自定义视图:
class FaceView(val theContext : Context, val bounds : Rect) : View(theContext)
override fun onDraw(canvas: Canvas?)
super.onDraw(canvas)
val myPaint = Paint()
myPaint.color = Color.BLACK
myPaint.style = Paint.Style.STROKE
myPaint.strokeWidth = 10f
canvas?.drawRect(bounds, myPaint)
试图在我们从人脸对象 ML 套件创建的边界上绘制一个矩形
val result = detector.process(image).addOnSuccessListener faces ->
for (face in faces)
val bounds = face.boundingBox
val view = FaceView(requireContext(), bounds)
binding.actionRoot.addView(view)
val lp : ConstraintLayout.LayoutParams =
ConstraintLayout.LayoutParams(bounds.width(),bounds.height())
lp.startToStart = binding.actionPhoto.id
lp.topToTop = binding.actionPhoto.id
lp.marginStart = bounds.right
lp.topMargin = bounds.bottom
view.layoutParams = lp
结果:
我们如何为我们从 URI(不是从 CameraX)生成的每个人脸绘制一个矩形并使其可点击?
【问题讨论】:
【参考方案1】:这里可以参考项目,不过是java代码
https://github.com/kkdroidgit/FaceDetect
【讨论】:
感谢您的回复。我检查了它,我可以用这种方法在脸部周围画一个矩形。但我也需要是可点击的(选择要改变的脸),并且项目中提供的功能不包括它。我的目的不是创建绘制的位图,而是创建图像视图。【参考方案2】:-- 虽然 ML 套件提供检测到的人脸的矩形。我认为 Google Developers 让我们更轻松,自动绘制矩形并将人脸作为独立的位图对象提供。
对于我的解决方案:
我使用@anonymous 建议的示例项目在脸部周围画线。
首先,我从提供的面部矩形中获得了起点、终点、底部和顶部。 (这个矩形是从原始位图创建的,而不是从图像视图中创建的。所以矩形点属于我使用的原始位图)。
由于 Rect 点不属于 ImageView 而属于位图本身,我们需要在 ImageView 上找到相关的 rect 点(或者创建一个缩放的位图并在其上检测人脸)。我们将这些点计算为原始位图中的百分比。
虽然我们在示例项目中使用原始点来绘制线条。我们实现了一个带有透明背景的视图,使用计算点来使面部矩形可点击。
-作为最后一件事,我们为每个面创建了位图。
detector.process(theImage)
.addOnSuccessListener faces ->
val bounds = face.boundingBox
val screenWidth = GetScreenWidth().execute()
// val theImage = InputImage.fromBitmap(tempBitmap,0)
val paint = Paint()
paint.strokeWidth = 1f
paint.color = Color.RED
paint.style = Paint.Style.STROKE
val theStartPoint = if(bounds.left < 0) 0 else bounds.left
val theEndPoint = if(bounds.right > tempBitmap.width) tempBitmap.width else bounds.right
val theTopPoint = if(bounds.top < 0) 0 else bounds.top
val theBottomPoint = if(bounds.bottom > tempBitmap.height) tempBitmap.height else bounds.bottom
val faceWidth = theEndPoint - theStartPoint
val faceHeight = theBottomPoint - theTopPoint
Log.d(Statics.LOG_TAG, "Face width : $faceWidth Face Height $faceHeight")
val startPointPercent = theStartPoint.toFloat() / tempBitmap.width.toFloat()
val topPointPercent = theTopPoint.toFloat() / tempBitmap.height.toFloat()
Log.d(Statics.LOG_TAG, "Face start point percent : $startPointPercent Face top percent $topPointPercent")
val faceWidthPercent = faceWidth / tempBitmap.width.toFloat()
val faceHeightPercent = faceHeight / tempBitmap.height.toFloat()
Log.d(Statics.LOG_TAG, "Face width percent: $faceWidthPercent Face Height Percent $faceHeightPercent")
val faceImage = ConstraintLayout(requireContext())
faceImage.setBackgroundColor(Color.TRANSPARENT)
binding.actionRoot.addView(faceImage)
val boxWidth = screenWidth.toFloat()*faceWidthPercent
val boxHeight = screenWidth.toFloat()*faceHeightPercent
Log.d(Statics.LOG_TAG, "Box width : $boxWidth Box Height $boxHeight")
val lp : ConstraintLayout.LayoutParams =
ConstraintLayout.LayoutParams(
boxWidth.toInt(),
boxHeight.toInt()
)
lp.startToStart = binding.actionPhoto.id
lp.topToTop = binding.actionPhoto.id
lp.marginStart = (screenWidth * startPointPercent).toInt()
lp.topMargin = (screenWidth * topPointPercent).toInt()
faceImage.layoutParams = lp
val theFaceBitmap = Bitmap.createBitmap(
tempBitmap,
theStartPoint,
theTopPoint,
faceWidth,
faceHeight)
if (face.trackingId != null)
val id = face.trackingId
faceImage.setOnClickListener
binding.actionPhoto.setImageBitmap(theFaceBitmap)
结果:
【讨论】:
以上是关于使用 Google Face Detection ML Kit 在现有照片周围绘制一个框的主要内容,如果未能解决你的问题,请参考以下文章
face detection,landmark, recognition with deeplearning
在 C++ 中反序列化 cnn_face_detection_model_v1
dlib:无法打开 face_landmark_detection_ex 进行阅读?