OpenCv Java 简单的图形轮廓绘制 (5)

初学Opencv实现一点点的功能都感觉很是吃力,所以不得不写点东西记忆一下,不然明天又忘记了

好记星不如烂笔头

我就想能不能处分出图片中的正方形和圆形,标记出来,我们这边就绘制器图像,下一步就是认识图片中的图像

发现轮廓

上图中是我们要区分的画出轮廓的图片看很简单,一个正方形两个圆,并且一个实心圆和一个空心圆

代码:

	public static void main(String[] args) throws IOException {

		try {
			ResourceBundle bundle = ResourceBundle.getBundle("opencv");
			String opencvDllName = bundle.getString("opencv.dllpath");
			System.load(opencvDllName);
		} catch (Exception e) {
			e.printStackTrace();
		}

		Range r1 = new Range(2, 5);
		Range r2 = new Range(1, 3);

		Mat src = Imgcodecs.imread("D:\\svnp\\MyYan\\res\\drawable\\rectangle.png");

		Mat dst = new Mat();

		Imgproc.cvtColor(src, dst, Imgproc.COLOR_BGR2GRAY);

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

		Mat hierarchy = new Mat();

		Imgproc.findContours(dst, contours, hierarchy, Imgproc.CV_BLUR, Imgproc.CHAIN_APPROX_NONE);
		
		Mat background=new Mat(src.size(),CvType.CV_8UC3, new Scalar(0,255,0));
	

		for (int i = 0; i < contours.size(); i++) {

			// Imgproc.drawContours(src,contours,k,new Scalar(255,0,0),1,20,hierarchy);

			// System.out.println(point.dump());

			Imgproc.drawContours(background, contours, i, new Scalar(255, 0, 0), 1, 8, hierarchy);
			// Imgproc.drawMarker(Contours, point, new Scalar(255,0,0));

		}
		HighGui.imshow("ces", background);
		HighGui.waitKey(5);
	
	}

最后显示出来的结果:

我们来分析上面的代码,只有分析才能学到东西啊

1.首先获取图片,并且灰度化,不解释了

Mat src = Imgcodecs.imread("D:\\svnp\\MyYan\\res\\drawable\\rectangle.png");

Mat dst = new Mat();

Imgproc.cvtColor(src, dst, Imgproc.COLOR_BGR2GRAY);

2.创建容器,获取轮廓 所谓的容器是绘制轮廓返回的结果存储的位置

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

	Mat hierarchy = new Mat();

	Imgproc.findContours(canny_r, contours, hierarchy, Imgproc.RETR_TREE,Imgproc.CHAIN_APPROX_SIMPLE);

3.绘制轮廓,并且显示结果

Mat background = new Mat(src.size(), CvType.CV_8UC3, new Scalar(0, 255, 0));

    for (int i = 0; i < contours.size(); i++) {

            Imgproc.drawContours(background, contours, i, new Scalar(255, 0, 0), 1, 8, hierarchy);

        }
        HighGui.imshow("ces", background);
        HighGui.waitKey(5);

主要方法是绘制轮廓的方法

参数含义:

image 数据源

contours 轮廓点集合 List<MatOfPoint>

hierarchy 层级轮廓层级描述 和contours是对应的

第四个参数:int型的mode,定义轮廓的检索模式:

           取值一 RETR_EXTERNAL只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略

           取值二:RETR_LIST   检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关

                  系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓

                  所以hierarchy向量内所有元素的第3、第4个分量都会被置为-1,具体下文会讲到

           取值三:RETR_CCOMP  检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围

                  内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层

           取值四:RETR_TREE, 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内

                   层轮廓还可以继续包含内嵌轮廓。

第五个参数:int型的method,定义轮廓的近似方法:

           取值一:CHAIN_APPROX_NONE 保存物体边界上所有连续的轮廓点到contours向量内

           取值二   CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours

                   向量内,拐点与拐点之间直线段上的信息点不予保留

           取值三和四:CHAIN_APPROX_TC89_L1,CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近

                   似算法

再次可以在第一步图片处理上进行优化

我们用其他的图片进行测试一下:

灰度化之后,可以使用canny进行边缘检测

	    Mat dst = new Mat();

		Imgproc.cvtColor(src, dst, Imgproc.COLOR_BGR2GRAY);
		
		
		Mat canny_r=new Mat();
		
		Imgproc.Canny(dst, canny_r, 90, 180);

 进行了边缘检测之后,再去绘制轮廓,效果会更好

我们当然还可以进一步的优化,进行高斯滤波

	   Imgproc.cvtColor(src, dst, Imgproc.COLOR_BGR2GRAY);
		
		Mat canny_r=new Mat();
		
		Imgproc.Canny(dst, canny_r, 90, 180);
		
		Imgproc.GaussianBlur(canny_r, canny_r, new Size(5, 5),3);

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

		Mat hierarchy = new Mat();

		Imgproc.findContours(canny_r, contours, hierarchy, 
        
        Imgproc.RETR_TREE,Imgproc.CHAIN_APPROX_SIMPLE);

进行了高斯滤波之后

可以看到不进行高斯滤波和进行高斯滤波还是有区别的

我们可以看到的是,其实我们进行绘制轮廓之前可以进行基本的图片处理

 

轮廓的绘制

函数:

image 绘制轮廓的背景图片

contours 轮廓信息

contourIdx 绘制轮廓的索引 -1 标识绘制所有的轮廓点 其他的值标识绘制轮廓的contours.get(0)对应的轮廓点

color 颜色

thickness 线条粗细

lintType :    // C++: enum LineTypes
    public static final int
            FILLED = -1,
            LINE_4 = 4,
            LINE_8 = 8,
            LINE_AA = 16;

 

默认的thickness

thickness=2

 画出其中高和宽度相差大于100的图形

	Mat src = Imgcodecs.imread(filename);// 加载需要被蒙太奇的图片,原图

		Mat dst = new Mat();

		Imgproc.cvtColor(src, dst, Imgproc.COLOR_BGR2GRAY);

		Imgproc.medianBlur(dst, dst,3);
		
		Mat oepn=Imgproc.getStructuringElement(Imgproc.CV_SHAPE_RECT, new Size(5,5));

		Imgproc.morphologyEx(dst, dst, Imgproc.MORPH_HITMISS,oepn,new Point(-1,-1));

		Imgproc.threshold(dst,dst,0,255,Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);

		List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
		Mat hierarchy = new Mat();
		Imgproc.findContours(dst, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_NONE);
		for (int i = 0; i < contours.size(); i++) {
			// 外边界
			Rect rect = Imgproc.boundingRect(contours.get(i));
			double w = rect.width;
			double h = rect.height;
			if(Math.abs(w-h)>100) {
				Imgproc.drawContours(src, contours,i+1, new Scalar(255, 255, 0), 2,Imgproc.LINE_8,hierarchy);
				
			}
		}
		HighGui.imshow("原图", src);
//	    HighGui.imshow("矩形操作", dst2);
		HighGui.waitKey(0);

Imgproc.drawContours(src, contours,0, new Scalar(255, 255, 0), 2,Imgproc.LINE_8);    
当第三个值contoursIdx的值确定的是时候,其实就是绘制的contours.get(contoursIdx)所表示的轮廓,当第三个值contoursIdx的值确定的是时候,表示绘制所有的轮廓

什么是轮廓

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

可以看到的是轮廓是存储在MatOfPoint,我们查看MatOfPoint发现是一些像素点,

轮廓是像素点组成的数组,集合

轮廓分析

我们可以从轮廓这里面或者到一个矩阵rect

Rect rect = Imgproc.boundingRect(contours.get(i));

并且获取到顶点,和矩阵的长度和宽度

		System.out.println(rect.tl()+"**********"+rect.br());
		double w = rect.width;
		double h = rect.height;

 

我们可以绘制具体位置的图形,比如我要绘制六边形的轮廓

我们通过简单的位置可以定位到最左侧的图形并绘制出其轮廓

我觉得我们设置是可以对MatOfPoint进行分析,轮廓分析,比如最简单的正方形,如果说rect.x=rect.y我们就可以认准为正方形

在一群图像中进行识别正方形

希望对你有所帮助

 

 

 

 

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Contours 是一个用于计算图像轮廓的库。它提供了一些方法和工具来分析和提取图像中的物体边缘。 要使用 Java Contours,你首先需要导入相应的库。然后,你可以加载图像,并使用 Contours 库中的方法来计算图像的轮廓。这些方法可以帮助你找到图像中物体的边缘,并返回一个表示轮廓的数据结构。 以下是一个简单的示例代码,演示如何使用 Java Contours 来计算图像的轮廓: ```java import org.opencv.core.*; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.utils.Converters; import java.util.ArrayList; import java.util.List; public class ContoursExample { public static void main(String[] args) { // 加载图像 Mat image = Imgcodecs.imread("path/to/your/image.jpg"); // 转换为灰度图像 Mat gray = new Mat(); Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY); // 二值化处理 Mat binary = new Mat(); Imgproc.threshold(gray, binary, 0, 255, Imgproc.THRESH_BINARY); // 查找轮廓 List<MatOfPoint> contours = new ArrayList<>(); Mat hierarchy = new Mat(); Imgproc.findContours(binary, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); // 在图像上绘制轮廓 Mat result = new Mat(); Imgproc.drawContours(image, contours, -1, new Scalar(0, 0, 255), 2); // 显示结果 Imgcodecs.imwrite("path/to/save/result.jpg", image); } } ``` 请确保你已经正确地安装了 OpenCV 并配置了 Java 开发环境。这个示例演示了如何加载图像、将其转换为灰度图像、进行二值化处理,然后使用 Contours 库查找并绘制轮廓。你可以根据自己的需求调整代码并探索更多的 Contours 功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值