opencv4.0.0图像处理:图像目标尺寸检测java版(四)

以前在网上浏览到一篇英文文章,讲的是如何利用opencv实现图像目标尺寸检测,不过原文的实现代码是python;对于java程序员来说不方便调用,故本人采用java语言实现了同样的功能(由于精力及技术问题,延至今日才有java版本的实现),代码未有完善之处,如相关方法的参数值等,尚需后续补充

原文地址:https://www.pyimagesearch.com/2016/03/28/measuring-size-of-objects-in-an-image-with-opencv/
在此感谢原作者及网上相关参考文章(特别是雷锋网的翻译版本,貌似链接已经失效)

其基本思路是先获取图片中图像目标的轮廓,然后获取其旋转矩阵,并对旋转矩阵的坐标顺时针排序,然后获取其矩阵边框的中点坐标,最后是计算对称中点的欧氏距离(像素),最后再根据参照物的像素与英寸的比例计算实际距离

部分java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 图像目标尺寸检测
* @param args
*/
public static void main(String[] args) {

//Mat image = imread("images/test6.png");
Mat image = imread("images/example_01.png");
Mat gray = new Mat();
Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY);

Imgproc.GaussianBlur(gray, gray, new Size(7,7), 0);

Mat edges = new Mat();
Imgproc.Canny(image, edges, 50, 150);
//Imgproc.Canny(image, edges,100.0, 200.0,3,true);

Mat kernel1=Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8,8), new Point(4,4));
Imgproc.dilate(edges, edges, kernel1 ,new Point(-1,-1),1);

Mat kernel=Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(9,9), new Point(-1,-1));
Imgproc.erode(edges, edges, kernel,new Point(-1,-1),1);

List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(edges.clone(), contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
//……
}

最后效果如图:

我们发现,其中的测量对象的尺寸并不是百分之百准确,原文分析了两个原因:

1)图像的拍摄视角问题,不是绝对的90度角度

2)拍摄相机的相关参数校准问题

坚持原创技术分享,您的支持是我前进的动力!