Kotlin OpenCV 图像图像51图片轮廓获取
在OpenCV库中,Imgproc.adaptiveThreshold、Imgproc.findContours 和 Imgproc.boundingRect 这三个方法在图像处理和分析中非常有用。以下是它们的详细作用:
Imgproc.adaptiveThreshold | 解释 |
---|---|
作用 | 该方法用于将灰度图像二值化。与普通的阈值处理不同,adaptiveThreshold 可以根据图像局部区域的亮度变化自适应地确定每个像素的阈值。 |
使用场景 | 适用于光照不均匀的图像,在全局阈值不能很好区分前景和背景时,adaptiveThreshold 可以生成更准确的二值图像。 |
src | 输入的灰度图像。 |
dst | 输出的二值图像。 |
maxValue | 阈值分割后的最大值(通常为255)。 |
adaptiveMethod | 自适应方法,可以是 ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C。 |
thresholdType | 阈值类型,通常为 THRESH_BINARY 或 THRESH_BINARY_INV。 |
blockSize | 用于计算阈值的邻域大小。 |
C | 从计算出的平均值或加权平均值中减去的常数,用于微调。 |
Imgproc.findContours | 解释 |
---|---|
作用 | 该方法用于检测图像中的轮廓。它可以识别二值图像中的连通分量,并将这些连通分量的边缘表示为轮廓。 |
使用场景 | 常用于对象检测、形状分析、物体识别等任务中,是许多高层次图像分析算法的基础。 |
image | 输入的二值图像,通常是经过阈值处理的结果。 |
contours | 输出的轮廓列表,其中每个轮廓都是一个点的列表。 |
hierarchy | 可选的层次结构信息,用于描述轮廓之间的嵌套关系。 |
mode | 轮廓的检索模式,如 RETR_EXTERNAL(只检索外部轮廓)或 RETR_TREE(检索所有轮廓并重构嵌套层次)。 |
method | 轮廓的近似方法,如 CHAIN_APPROX_SIMPLE(压缩水平、垂直和对角线段,保留端点)或 CHAIN_APPROX_NONE(保留所有点)。 |
Imgproc.boundingRect | 解释 |
---|---|
作用 | 该方法用于计算并返回包围特定点集或轮廓的最小矩形边框。 |
使用场景 | 常用于从图像中提取感兴趣区域(ROI),或进一步分析特定区域的内容。 |
points | 输入的点集或轮廓,可以是一个 Mat 或 List 对象。 |
输出 | 返回一个 Rect 对象,表示包围点集的矩形框,包含位置和尺寸信息(即 x, y, width, height)。 |
kotlin
package com.xu.com.xu.image
import org.opencv.core.Core
import org.opencv.core.Mat
import org.opencv.core.MatOfPoint
import org.opencv.core.Scalar
import org.opencv.highgui.HighGui
import org.opencv.imgcodecs.Imgcodecs
import org.opencv.imgproc.Imgproc
import java.io.File
import java.util.*
object Contour {
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-4.9\\x64\\" + System.mapLibraryName(Core.NATIVE_LIBRARY_NAME))
} else {
File("lib\\opencv-4.9\\x86\\" + System.mapLibraryName(Core.NATIVE_LIBRARY_NAME))
}
System.load(lib.absolutePath)
}
println("OpenCV: ${Core.VERSION}")
}
@JvmStatic
fun main(args: Array<String>) {
val image = Imgcodecs.imread("C:\\Users\\xuyq\\Desktop\\1.png")
val gray = Mat()
Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY)
val binary = Mat()
// 灰度图像自适应阈值二值化
Imgproc.adaptiveThreshold(
gray,
binary,
255.0,
Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,
Imgproc.THRESH_BINARY_INV,
11,
2.0
)
val contours = mutableListOf<MatOfPoint>()
val hierarchy = Mat()
// 检测图像中的轮廓
Imgproc.findContours(binary, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE)
for (contour in contours) {
// 计算并返回包围特定点集或轮廓的最小矩形边框
val rect = Imgproc.boundingRect(contour)
// 过滤小区域
if (rect.width > 28 || rect.height > 28) {
rect.x -= 15
rect.y -= 15
rect.width += 30
rect.height += 30
Imgproc.rectangle(image, rect, Scalar(0.0, 0.0, 255.0), 2)
}
}
HighGui.imshow("src", image)
HighGui.waitKey(0)
}
}