OpenCV Android 形状识别

public static int san_Num=0,rect_Num=0,lin_Num=0,star_Num=0,yuan_Num=0;
 
public  static Mat shapeDetect(Mat result) {
        san_Num = 0;
        rect_Num = 0;
        lin_Num = 0;
        star_Num = 0;
        yuan_Num = 0;
        //#使用自适应阈值分割
        Mat grayImage = new Mat();
        Imgproc.cvtColor(result, grayImage, Imgproc.COLOR_BGR2GRAY);
        Mat edges = new Mat();
        Mat canny_all_hierarchy = new Mat();
        Mat edge1=new Mat();
        try {
            Mat canny_new_img = result.clone();
            Imgproc.GaussianBlur(grayImage, grayImage, new Size(3, 3), 0, 0, Core.BORDER_DEFAULT);
            Imgproc.threshold(grayImage, edges, 0, 255, Imgproc.THRESH_BINARY + Imgproc.THRESH_OTSU);

            List<MatOfPoint> canny_all_contours = new ArrayList<MatOfPoint>();
            Core.bitwise_not(edges, edges);
            Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));   //  指定腐蚀膨胀核
            Imgproc.dilate(edges, edges, kernel); 
            Imgproc.dilate(edges, edges, kernel); 

            Imgproc.findContours(edges, canny_all_contours, canny_all_hierarchy,
                    Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
              //边缘化之后再查找所有的轮廓
              edge1 = edges.clone();

            for (MatOfPoint c : canny_all_contours) {
                int area = 0;
                area = (int) Imgproc.contourArea(c);
                Log.i("ShapeDetect", "识别面积:" + area);
                //300、800、500  if (area > 500&&800<area)
                double peri = Imgproc.arcLength(new MatOfPoint2f(c.toArray()), true);
                Log.i("ShapeDetect", "识别周长:" + peri);
                if (area > 50 && area < 6000) {
                    DetectShape(new MatOfPoint2f(c.toArray()));//统计形状个数
                }
            }
            Log.e("Shape", "三角形个数:" + san_Num + "矩形个数:" + rect_Num + "菱形个数:" + lin_Num
                    + "五角形个数:" + star_Num + "圆形个数:" + yuan_Num + "个数" + canny_all_contours.size());
        }catch (Exception e){

        }
        return edge1;
}

识别

   private static void DetectShape (MatOfPoint2f c){
        int area = 0;
        area = (int) Imgproc.contourArea(c);
        String shape = "";
        //计算轮廓的周长
        double peri = Imgproc.arcLength(c, true);
        if (area > 100 && area < 7000) {
            double side_lenght = peri / 4;//计算出菱形或者正方形的边长,用于判断菱形与正方形和矩形的区别
            MatOfPoint2f approx = new MatOfPoint2f();
            //得到大概值
            Imgproc.approxPolyDP(c, approx, 0.04* peri, true);
            int s = approx.toList().size();
            Log.e("TAG", "大小" + s);

            //如果是三角形形状,则有三个顶点
            if (approx.toList().size() == 3) {
                san_Num++;
                shape = "triangle";
            }
            //如果有四个顶点,则是正方形或者长方形
            else if (approx.toList().size() == 4) {
                double area1 = 0, minArea = 0;
                area1 = Imgproc.contourArea(c);
                RotatedRect rect1 = Imgproc.minAreaRect(c);
                minArea = rect1.size.area();
                double rec = area1 / minArea;
                if (rec >= 0.83 && rec < 1.15) {
                    shape = "rectangle";
                    rect_Num++;
                } else {
                    lin_Num++;
                    shape = "rhombus";
                }
            }
            //如果是五角形,则有五个顶点
            else if (approx.toList().size() >= 10 && approx.toList().size() <= 13) {
                shape = "pentagon";
                star_Num++;
            }
            //除了以上情况之外,我们假设为圆形 圆形可用霍夫检测
            // else if(approx.toList().size()>13){
            else {
                yuan_Num++;
                shape = "circle";
            }
        }
     }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值