前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android OpenCV(三十八):凸包检测

Android OpenCV(三十八):凸包检测

作者头像
Vaccae
发布2021-07-07 19:11:16
1.1K0
发布2021-07-07 19:11:16
举报
文章被收录于专栏:微卡智享微卡智享

凸包

凸包(Convex Hull)是一个计算几何(图形学)中的概念。在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包。X的凸包可以用X内所有点(X1,...Xn)的凸组合来构造.在二维欧几里得空间中,凸包可想象为一条刚好包着所有点的橡皮圈。用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点。

凸包

凸包缺陷

凸包缺陷

如图所示,黑色的轮廓线为convexity hull(凸包),而convexity hull(凸包)与手掌之间的部分为convexity defects(凸包缺陷).

API

代码语言:javascript
复制
public static void convexHull(MatOfPoint points, MatOfInt hull, boolean clockwise) 
  • 参数一:points,输入的二维点集。
  • 参数二:hull,输出凸包点索引集合。索引指的是第一个参数中二维点集的索引。
  • 参数三:clockwise,方向标志位。true时,凸包顺序为顺时针方向;false时,凸包顺序为逆时针方向。
代码语言:javascript
复制
public static void convexityDefects(MatOfPoint contour, MatOfInt convexhull, MatOfInt4 convexityDefects)
  • 参数一:contour,输入的轮廓。
  • 参数二:convexhull,上面convexHull方法的输出结果hull。
  • 参数三:convexityDefects,凸包缺陷特征集合。每个convexity defect区域有四个特征量:起始点(startPoint),结束点(endPoint),距离convexity hull最远点(farPoint),最远点到convexity hull的距离(depth)。

算法

[217] Jack Sklansky. Finding the convex hull of a simple polygon. Pattern Recognition Letters, 1(2):79–83, 1982.

操作

代码语言:javascript
复制
/**
 * 凸包检测,凸包缺陷
 *
 * @author yidong
 * @date 2020/10/13
 */
class ConvexHullActivity : AppCompatActivity() {

    private lateinit var mBinding: ActivityConvexHullBinding
    private lateinit var mSource: Mat
    private lateinit var mGray: Mat


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_convex_hull)
        val bgr = Utils.loadResource(this, R.drawable.star)
        mSource = Mat()
        mGray = Mat()

        Imgproc.cvtColor(bgr, mGray, Imgproc.COLOR_BGR2GRAY)
        Imgproc.cvtColor(bgr, mSource, Imgproc.COLOR_BGR2RGB)
        mBinding.ivLena.showMat(mSource)
        doConvexHull()
    }

    private fun doConvexHull() {
        val binary = Mat()
        Imgproc.threshold(mGray, binary, 25.0, 255.0, Imgproc.THRESH_BINARY)
        
        val tmp = mSource.clone()
        val contours = mutableListOf<MatOfPoint>()
        val hierarchy = Mat()
        Imgproc.findContours(
            binary,
            contours,
            hierarchy,
            Imgproc.RETR_TREE,
            Imgproc.CHAIN_APPROX_SIMPLE
        )

        for (contour in contours) {
            val hull = MatOfInt()
            val defects = MatOfInt4()
            Imgproc.convexHull(contour, hull)
            val indexList = hull.toList()
            val contourList = contour.toList()
            for (i in 0 until indexList.size) {
                val index = indexList[i % indexList.size]
                val nextIndex = indexList[(i + 1) % indexList.size]
                val point = contourList[index]
                Imgproc.circle(
                    tmp,
                    point,
                    10,
                    Scalar(255.0, 255.0, 0.0),
                    2,
                    Imgproc.LINE_8,
                    0
                )
                Log.d(App.TAG, contourList[i].toString())
                Imgproc.line(
                    tmp,
                    point,
                    contourList[nextIndex],
                    Scalar(255.0, 255.0, 0.0),
                    10,
                    Imgproc.LINE_8,
                    0
                )
            }

            Imgproc.convexityDefects(contour, hull, defects)
            val defectsList = defects.toList()
            for (i in 0 until defectsList.size step 4) {
                val start = contourList[defectsList[i]]
                val end = contourList[defectsList[i + 1]]
                val far = contourList[defectsList[i + 2]]
                Imgproc.line(
                    tmp,
                    start,
                    far,
                    Scalar(0.0, 0.0, 205.0),
                    8,
                    Imgproc.LINE_8,
                    0
                )
                Imgproc.line(
                    tmp,
                    far,
                    end,
                    Scalar(0.0, 0.0, 205.0),
                    8,
                    Imgproc.LINE_8,
                    0
                )

                Imgproc.line(
                    tmp,
                    end,
                    start,
                    Scalar(0.0, 0.0, 205.0),
                    2,
                    Imgproc.LINE_8,
                    0
                )
            }
            mBinding.ivResult.showMat(tmp)
        }

        binary.release()
        hierarchy.release()
        tmp.release()
    }

    override fun onDestroy() {
        mSource.release()
        mGray.release()
        super.onDestroy()
    }
}

效果

下图中,黄色部分为凸包,蓝色部分为凸包缺陷。

凸包与凸包缺陷

源码

https://github.com/onlyloveyd/LearningAndroidOpenCV

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微卡智享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 凸包
  • 凸包缺陷
  • API
  • 算法
  • 操作
  • 效果
  • 源码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档