Kotlin OpenCV 图像图像50 Haar 级联分类器模型
- [1 OpenCV Haar 级联分类器模型](#1 OpenCV Haar 级联分类器模型)
- [2 Kotlin OpenCV Haar 测试代码](#2 Kotlin OpenCV Haar 测试代码)
1 OpenCV Haar 级联分类器模型
Haar级联分类器是一种用于对象检测(如人脸检测)的机器学习算法。它由Paul Viola和Michael Jones在2001年提出,通常用于实时检测,因为它速度快且性能良好。
基本原理 | 解释 |
---|---|
Haar特征 | Haar特征是从图像中提取的简单矩形特征,通过比较相邻区域的像素值来描述图像的局部特征。 常见的Haar特征有边缘特征、线条特征和四边形特征。 每个Haar特征值由区域内像素的加权和计算得到,具体公式为特征值 = 黑色区域像素值总和 - 白色区域像素值总和。 |
积分图(Integral Image) | 积分图是一种图像表示方法,方便快速计算矩形区域的像素和。 通过积分图,可以在常数时间内计算任意矩形区域的像素和。 |
级联分类器(Cascade Classifier) | 级联分类器由一系列弱分类器(如决策树桩)组成,每个弱分类器使用一个或多个Haar特征进行分类。 弱分类器按顺序排列,每个分类器将图像区域分为正例(目标对象)和负例(非目标对象)。 如果某个区域被认为是负例,则立即停止检测;如果被认为是正例,则继续传递到下一个分类器。 这种级联结构大大提高了检测速度,因为大部分非目标区域在早期就被排除。 |
文件夹 | 用途 | 特点 |
---|---|---|
lbpcascades | 包含基于局部二值模式 (Local Binary Patterns, LBP) 的级联分类器文件。LBP 是一种有效的纹理特征描述符,在对象检测中表现良好。 | 计算效率高: LBP 特征计算简单,因此在对象检测时速度较快。 鲁棒性: 对光照变化和其他环境变化有较好的鲁棒性。 常用分类器: 人脸检测等。 |
hogcascades | 包含基于方向梯度直方图 (Histogram of Oriented Gradients, HOG) 特征的级联分类器文件。HOG 特征在检测行人等对象时表现良好。 | 特征描述能力强: HOG 特征能够捕捉对象的形状和外观信息。 高检测精度: 尤其在检测行人方面有较高的精度。 |
haarcascades_cuda | 包含利用 CUDA 加速的 Haar 特征级联分类器文件。这些分类器利用 GPU 进行加速计算,提高检测速度。 类似于 haarcascades 文件夹中的文件,是加速版本。 | 高性能: 利用 GPU 的并行计算能力,大幅提升检测速度。 需要支持 CUDA 的 GPU: 需要系统安装 CUDA 并支持相应的 GPU 硬件。 |
haarcascades | 包含基于 Haar 特征的级联分类器文件。这是 OpenCV 中最常用的对象检测分类器之一。 | 历史悠久: Haar 级联分类器是最早用于人脸检测的算法之一。 计算复杂度适中: 相比 LBP 更复杂,但特征描述能力也更强。 广泛应用: 用于人脸、眼睛、微笑等对象的检测。 |
haarcascades_cuda 和 haarcascades 文件的主要区别在于它们是否利用 CUDA 加速进行对象检测。
haarcascades/haarcascades_cuda 文件夹 | 用途 |
---|---|
haarcascade_eye.xml | 用于检测人眼。 |
haarcascade_eye_tree_eyeglasses.xml | 用于检测戴眼镜的人眼。 |
haarcascade_frontalcatface.xml | 用于检测猫的正面脸部。 |
haarcascade_frontalcatface_extended.xml | 用于检测猫的正面脸部(扩展版本)。 |
haarcascade_frontalface_alt.xml | 用于检测人脸的另一个版本。 |
haarcascade_frontalface_alt2.xml | 用于检测人脸的另一个替代版本。 |
haarcascade_frontalface_alt_tree.xml | 用于检测人脸的另一个替代版本(树状结构)。 |
haarcascade_frontalface_default.xml | 用于检测人脸的默认版本。 |
haarcascade_fullbody.xml | 用于检测人体的完整体。 |
haarcascade_lefteye_2splits.xml | 用于检测左眼(两部分)。 |
haarcascade_license_plate_rus_16stages.xml | 用于检测俄罗斯车牌(16阶段)。 |
haarcascade_lowerbody.xml | 用于检测人体的下半身。 |
haarcascade_profileface.xml | 用于检测人脸的侧面(侧脸)。 |
haarcascade_righteye_2splits.xml | 用于检测右眼(两部分)。 |
haarcascade_russian_plate_number.xml | 用于检测俄罗斯车牌号码。 |
haarcascade_smile.xml | 用于检测微笑。 |
haarcascade_upperbody.xml | 用于检测人体的上半身。 |
hogcascades文件夹 | 用途 |
---|---|
hogcascade_pedestrians.xml | 用于在图像或视频中检测行人。 |
lbpcascades文件夹 | 用途 |
---|---|
lbpcascade_frontalcatface.xml | 用于检测猫的正面脸部。 |
lbpcascade_frontalface.xml | 用于检测人脸的正面部分。 |
lbpcascade_frontalface_improved.xml | 用于检测人脸的正面部分,改进版本。 |
lbpcascade_profileface.xml | 用于检测人脸的侧面部分。 |
lbpcascade_silverware.xml | 用于检测银器(如刀、叉、勺等餐具)。 |
2 Kotlin OpenCV Haar 测试代码
kotlin
package com.xu.com.xu.image
import org.opencv.core.MatOfRect
import org.opencv.core.Point
import org.opencv.core.Scalar
import org.opencv.highgui.HighGui
import org.opencv.imgcodecs.Imgcodecs
import org.opencv.imgproc.Imgproc
import org.opencv.objdetect.CascadeClassifier
import java.io.File
import java.util.*
object FaceDetect {
init {
val os = System.getProperty("os.name")
val type = System.getProperty("sun.arch.data.model")
if (os.uppercase(Locale.getDefault()).contains("WINDOWS")) {
val lib = if (type.endsWith("64")) {
File("lib\\opencv\\x64\\" + System.mapLibraryName("opencv_java4100"))
} else {
File("lib\\opencv\\x86\\" + System.mapLibraryName("opencv_java4100"))
}
System.load(lib.absolutePath)
}
}
@JvmStatic
fun main(args: Array<String>) {
face()
}
private fun face() {
val facebook = CascadeClassifier("lib/opencv/data/haarcascades/haarcascade_frontalface_alt2.xml")
val image = Imgcodecs.imread("C:\\Users\\hyacinth\\Desktop\\1.png")
val face = MatOfRect()
facebook.detectMultiScale(image, face)
val reacts = face.toArray()
println("匹配到 " + reacts.size + " 个人脸")
for (i in reacts.indices) {
Imgproc.rectangle(
image,
Point(reacts[i].x.toDouble(), reacts[i].y.toDouble()),
Point((reacts[i].x + reacts[i].width).toDouble(), (reacts[i].y + reacts[i].height).toDouble()),
Scalar(0.0, 0.0, 255.0), 2
)
Imgproc.putText(
image,
i.toString(),
Point(reacts[i].x.toDouble(), reacts[i].y.toDouble()),
Imgproc.FONT_HERSHEY_SCRIPT_SIMPLEX,
1.0,
Scalar(0.0, 0.0, 255.0),
2,
Imgproc.LINE_AA,
false
)
}
HighGui.imshow("人脸识别", image)
HighGui.waitKey(0)
}
}