霍夫变换
在获取图像边缘的基础上,对特定的几何形状边缘,如直线、圆,通过图形霍夫变换把图像从平面空间坐标转换到霍夫空间坐标。
霍夫变换不仅能识别直线,也能够识别任何形状,常见的有圆形、椭圆形。
霍夫直线
下面是霍夫直线的api代码
HoughLinesP(Mat image, Mat lines, double rho, double theta, int threshold)
- imgae:表示输入图像,8位通道,一般为二值图像
- lines:表示输出的点坐标图像 每一行代表一条直线[(x0,y0),(x,y)]四个像素点
- rho:表示极坐标空间的r值,每次的步长,一般设置为1
- theta:表示角度,一般为 PI/180.0
- threshold:表示极坐标中该点数的累计数,该点累计数越大,则得到的直线就越长,假设取值30的话,表示大于30个像素长度才会被检测到
下面通过一个代码来展示霍夫直线
Mat m1 = Imgcodecs.imread("C:\\test\\bmp.png" );
HighGui.imshow("原图",m1);
Mat s1 = new Mat();
Imgproc.Canny(m1,s1,50,150);//边缘检测
Mat s2 = new Mat();//存放直线坐标点的Mat对象
//霍夫直线,检测到的结果会放在s2
Imgproc.HoughLinesP(s1,s2,1,Math.PI/180.0,50);
//获取Mat 的每一行 ,然后取出4个坐标点
int[] data = new int[4];
for (int i = 0; i < s2.rows() ; i++) {
//直线获取rows
s2.get(i,0,data);
Point pt1 = new Point(data[0],data[1]);
Point pt2 = new Point(data[2],data[3]);
System.out.println(pt1);
System.out.println(pt2);
Imgproc.line(m1,pt1,pt2,new Scalar(0,0,255),2,Imgproc.LINE_AA,0);
}
霍夫圆检测
霍夫圆的api检测代码如下
HoughCircles(Mat image, Mat circles, int method, double dp, double minDist, double param1, double param2, int minRadius)
- image:8位单通道的灰度图像
- circles:输出的三个向量的数组 圆心和半径(x,y,r)
- method:一般填写 Imgproc.HOUGH_GRADIENT 基于梯度变换
- dp:图片分辨率,数值越大 就会减小分辨率 ,当为2的时候 为原图的一半
- minDist:区分两个圆心之间的最小距离,通常用于降噪,在此范围内则认为同一个圆
- param1:Canny边缘检测是最高阈值
- param2:累加器阈值,值越大,越有可能是圆
- minRadius:检测最大的半径,单位像素
下面通过代码展示
Mat m1 = Imgcodecs.imread("C:\\test\\yb.jpg" );
HighGui.imshow("原图",m1);
Mat s1 = new Mat();//转换灰度图像
Imgproc.cvtColor(m1,s1,Imgproc.COLOR_BGR2GRAY);
//由于原图过于花哨,所以要通过模糊降低噪声
Imgproc.GaussianBlur(s1,s1,new Size(0,0),3);
Mat s2 = new Mat();
//霍夫圆检测
Imgproc.HoughCircles(s1,s2, Imgproc.HOUGH_GRADIENT,1,80,100,30,10,200);
float[] data = new float[3];//获取每一列的数据
for (int i = 0; i < s2.cols() ; i++) {
//圆形获取cols
s2.get(0,i,data);
Point pt1 = new Point((int)data[0],(int)data[1]);
float r = data[2];
System.out.println(pt1 +" "+r);
Imgproc.circle(m1,pt1,(int)r,new Scalar(0,0,255),2);
}
注意事项
如果不确定s2也就是那个输出的Mat对象是什么深度格式的话
可以使用System.out.println(s2) 输出一下,上面写着深度格式
再根据之前发的深度表,在填写data数组的类型
[OpenCV学习日记-java]-02-Mat对象基本操作 : 详细介绍数据类型
在进行霍夫直线的时候 获取 rows
而进行霍夫圆的时候就要获取 cols
详细的请仔细观看上面的代码