opencv 直线检测 java_OpenCV---直线检测

本文介绍了使用OpenCV在Java中进行直线检测的方法,包括经典的HoughLines和改进的HoughLinesP。HoughLines通过检测曲线上的像素点来找到直线,而HoughLinesP则更适用于检测图像中的分段直线,它允许设置最小线长度和最大线间隙来避免误检。
摘要由CSDN通过智能技术生成

直线检测相关

Hough变换是经典的检测直线的算法。其最初用来检测图像中的直线,同时也可以将其扩展,以用来检测图像中简单的结构。

ef29d27089601dfa956e7133b0540431.png

7a80ee4709991f2845c3268592366b5b.png

6eeaf4575deced2fe77c9ae1894cc285.png

变换图示

4b078705613b8ecedbfd39571aa7e435.png

霍夫直线检测的两种方法

1.获取灰度图像2.canny边缘检测3.获取霍夫直线信息4.算出直线位置,画出每条直线

一:HoughLines霍夫变换

def line_detection(image):

gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)

edges= cv.Canny(gray,50,150,apertureSize=3) #apertureSize是sobel算子大小,只能为1,3,5,7lines= cv.HoughLines(edges,1,np.pi/180,200) #函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线for line inlines:

rho,theta= line[0]  #获取极值ρ长度和θ角度

a = np.cos(theta)  #获取角度cos值

b = np.sin(theta)  #获取角度sin值

x0 = a * rho  #获取x轴值

y0 = b * rho  #获取y轴值  x0和y0是直线的中点

x1 = int(x0 + 1000*(-b))  #获取这条直线最大值点x1

y1 = int(y0 + 1000*(a))   #获取这条直线最大值点y1

x2 = int(x0 - 1000 * (-b)) #获取这条直线最小值点x2

y2 = int(y0 - 1000 *(a))  #获取这条直线最小值点y2  其中*1000是内部规则

cv.line(image,(x1,y1),(x2,y2),(0,0,255),2)  #开始划线

cv.imshow("image line",image)

src= cv.imread("./l.png") #读取图片

cv.namedWindow("input image",cv.WINDOW_AUTOSIZE) #创建GUI窗口,形式为自适应

cv.imshow("input image",src) #通过名字将图像和窗口联系

line_detect_possible_demo(src)

cv.waitKey(0) #等待用户操作,里面等待参数是毫秒,我们填写0,代表是永远,等待用户操作

cv.destroyAllWindows() #销毁所有窗口

659fcb0adcb327745f8e76ab554ed874.png

相关知识补充

(一)HoughLines方法

def HoughLines(image, rho, theta, threshold, lines=None, srn=None, stn=None, min_theta=None, max_theta=None): # real signature unknown; restored from __doc__

cv.HoughLines(edges,1,np.pi/180,200)

cv2.HoughLines函数输出的是[float, float]形式的ndarray,其中每个值表示检测到的线(ρ , θ)中浮点点值的参数。

第一个参数image:是canny边缘检测后的图像

第二个参数rho和第三个参数theta:对应直线搜索的步长。在本例中,函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线。

最后一个参数threshold:是经过某一点曲线的数量的阈值,超过这个阈值,就表示这个交点所代表的参数对(rho, theta)在原图像中为一条直线

观察前面的例子得到的结果图片,其中Hough变换看起来就像在图像中查找对齐的边界像素点集合。

但这样会在一些情况下导致虚假检测,如像素偶然对齐或多条直线穿过同样的对齐像素造成的多重检测。

二:HoughLinesP概率霍夫变换(是加强版)使用简单,效果更好,检测图像中分段的直线(而不是贯穿整个图像的直线)

def line_detect_possible_demo(image):

gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)

edges= cv.Canny(gray, 50, 150, apertureSize=3) # apertureSize是sobel算子大小,只能为1,3,5,7lines = cv.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=50,maxLineGap=10) #函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线for line inlines:

print(type(line)) #多维数组

x1,y1,x2,y2= line[0]

cv.line(image,(x1,y1),(x2,y2),(0,0,255),2)

cv.imshow("line_detect_possible_demo",image)

3a36c8c66648b3b87100753c9ed4e34d.png

相关知识补充:

(一)HoughLinesP方法

def HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None): # real signature unknown; restored from __doc__

cv.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=50,maxLineGap=10)

第一个参数是需要处理的原图像,该图像必须为cannay边缘检测后的图像;

第二和第三参数:步长为1的半径和步长为π/180的角来搜索所有可能的直线

第四个参数是阈值,概念同霍夫变换

第五个参数:minLineLength-线的最短长度,比这个线短的都会被忽略。

第六个参数:maxLineGap-两条线之间的最大间隔,如果小于此值,这两条线就会被看成一条线。

这个函数的返回值就是直线的起点和终点。

Java中使用OpenCV进行直线检测可以通过以下步骤实现: 1. 导入OpenCV库 在Java中使用OpenCV需要导入相应的库文件。可以在OpenCV的官网上下载Java版本的库文件(.jar文件)并添加到Java项目中。 2. 读取图片 使用OpenCV的Imgcodecs.imread()函数读取图片并存储为Mat对象。 ```java Mat image = Imgcodecs.imread("path/to/image.jpg"); ``` 3. 转换为灰度图像 使用OpenCV的Imgproc.cvtColor()函数将彩色图像转换为灰度图像。 ```java Mat grayImage = new Mat(); Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_BGR2GRAY); ``` 4. 边缘检测 使用OpenCV的Imgproc.Canny()函数进行边缘检测。 ```java Mat edges = new Mat(); Imgproc.Canny(grayImage, edges, 50, 200); ``` 5. 直线检测 使用OpenCV的Imgproc.HoughLinesP()函数进行直线检测。该函数返回一个MatOfInt4对象,其中每一行都代表一条直线,由四个整数表示:直线起点的x坐标、直线起点的y坐标、直线终点的x坐标、直线终点的y坐标。 ```java Mat lines = new Mat(); Imgproc.HoughLinesP(edges, lines, 1, Math.PI/180, 50, 50, 10); ``` 6. 绘制直线 使用OpenCV的Imgproc.line()函数将检测到的直线绘制在原图上。 ```java for (int i = 0; i < lines.rows(); i++) { double[] line = lines.get(i, 0); Imgproc.line(image, new Point(line[0], line[1]), new Point(line[2], line[3]), new Scalar(0, 0, 255), 3); } ``` 完整代码示例: ```java import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfInt4; import org.opencv.core.Point; import org.opencv.core.Scalar; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; public class LineDetection { public static void main(String[] args) { // Load OpenCV library System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // Read image Mat image = Imgcodecs.imread("path/to/image.jpg"); // Convert to grayscale Mat grayImage = new Mat(); Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_BGR2GRAY); // Edge detection Mat edges = new Mat(); Imgproc.Canny(grayImage, edges, 50, 200); // Line detection Mat lines = new Mat(); Imgproc.HoughLinesP(edges, lines, 1, Math.PI/180, 50, 50, 10); // Draw lines on the image for (int i = 0; i < lines.rows(); i++) { double[] line = lines.get(i, 0); Imgproc.line(image, new Point(line[0], line[1]), new Point(line[2], line[3]), new Scalar(0, 0, 255), 3); } // Display the result Imgcodecs.imwrite("path/to/result.jpg", image); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值