Opencv——根据颜色特征识别位置

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/wx19900503/article/details/92645553

根据图像中局部颜色特征,获取该位置

一、根据特定颜色切割,输出二值化图像

public static void inRange(Mat src,
                           Scalar lowerb,
                           Scalar upperb,
                           Mat dst)

例如 new Scalar(28,10,255);

    public Scalar(double v0, double v1, double v2) {
        this.val = new double[]{v0, v1, v2, 0.0D};
    }

相当于颜色数组,mac可以通过数码测试计来获取

计算规则为:

  • For every element of a single-channel input array: 单通道计算规则

dst(I)= lowerb(I)_0 <= src(I)_0 <= upperb(I)_0

  • For two-channel arrays: 二通道

dst(I)= lowerb(I)_0 <= src(I)_0 <= upperb(I)_0 land lowerb(I)_1 <= src(I)_1 <= upperb(I)_1

三通道处理方式一样,每个通道都大于等于lowerb小于upperb

输出二值化图像,在范围内,标记255及白色不在该范围内标记0黑色

二、获取该图像轮廓:

public static void findContours(Mat image,
                                java.util.List<MatOfPoint> contours,
                                Mat hierarchy,
                                int mode,
                                int method)

获取图像轮廓 List<MatOfPoint> ,满足该函数策略的轮廓集合

Imgproc.RETR_EXTERNAL 只检测最外围轮廓;Imgproc.RETR_CCOMP:能获取外层和内层轮廓

Imgproc.CHAIN_APPROX_SIMPLE:仅保存轮廓的拐点信息,例如矩形只需要四个点来保存

目前还没怎么用到其他参数,具体还需要通过实际尝试,得出结论

三、根据轮廓,画出矩阵,查看符合条件的图形

public static void rectangle(Mat img,
                             Point pt1,
                             Point pt2,
                             Scalar color,
                             int thickness,
                             int lineType,
                             int shift)

通过函数 public static Rect boundingRect(MatOfPoint points):计算并返回指定点集的最小右上边界矩形,水平垂直的矩阵

获取该矩阵:

int x = rect.x;
int y = rect.y;
int w = rect.width;
int h = rect.height;

rectangle画出矩形查看,我们根据获取的坐标点的四个坐标,其实就可以大概定位到所需要的位置

四、Demo代码如下:


        Mat img = Imgcodecs.imread(originalImgPath);
        //克隆图像mat
        Mat dstImage = img.clone();

        Imgproc.medianBlur(img, dstImage, 7);

        //输出图片查看
        Imgcodecs.imwrite("/Users/wuxi/Desktop/medianBlur.jpg",dstImage);

        Mat mask = new Mat();

        Core.inRange(dstImage, new Scalar(0,0,240), new Scalar(30,30,255), mask); 
        //输出图片查看,二值化图片
        Imgcodecs.imwrite("/Users/wuxi/Desktop/erzhihua.jpg",mask);

        List<MatOfPoint> contours = new ArrayList<>();

        Imgproc.findContours(mask,contours,new Mat(),Imgproc.RETR_EXTERNAL,Imgproc.CHAIN_APPROX_SIMPLE);

        JSONObject jsonObject = new JSONObject();
        List<Map> list=new ArrayList<>();

        System.out.println("contours"+contours.size());
        for (MatOfPoint cnt : contours) {

            Rect rect = Imgproc.boundingRect(cnt);

            int x = rect.x;
            int y = rect.y;
            int w = rect.width;
            int h = rect.height;
       // 如果存在多个轮廓,需要自己通过该矩阵特征过滤不需要的轮廓
            Map<String, Integer> map = new HashMap<String, Integer>();
                map.put("x",x);
                map.put("y",y);
            
            Imgproc.rectangle(img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),new Scalar(0, 0,255), 2); //线的宽度
            //输出图片查看
            Imgcodecs.imwrite("/Users/wuxi/Desktop/juxing2.jpg",img);

原始图像:

矩阵图像

参考:

https://blog.csdn.net/eric_e/article/details/79591025

https://blog.csdn.net/qq_19707521/article/details/78367684

https://docs.opencv.org/3.4.2/javadoc/index.html

https://docs.opencv.org/java/2.4.7/overview-summary.html

猜你喜欢

转载自blog.csdn.net/wx19900503/article/details/92645553