使用opencv相关函数确定图片中的直线问题
фора 快跑 人气:0使用opencv相关函数确定图片中的直线
#pip install opencv-python==4.4.0.42 opencv-contrib-python==4.4.0.42 import cv2 import numpy as np from matplotlib import pyplot as plt import matplotlib.image as mpimg import matplotlib as mpl from PIL import Image mpl.rcParams['figure.dpi'] = 200 #加载图像 img = cv2.imread('test.png') plt.axis('off') plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.show() #灰度图像 img1 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #cornerHarris要求img是flaot32位 img1 = np.float32(img1) #Harris角点检测函数 # • img - 数据类型为 float32 的输入图像。 # • blockSize - 角点检测中要考虑的领域大小。 # • ksize - Sobel 求导中使用的窗口大小 # • k - Harris 角点检测方程中的自由参数,取值参数为 [0,04,0.06]. dst = cv2.cornerHarris(img1,10,3,0.04) plt.axis('off') plt.imshow(dst, cmap='gray') plt.show() #膨胀 dst = cv2.dilate(dst,None) plt.axis('off') plt.imshow(dst, cmap='gray') plt.show() #显示经过处理后的图片 threshold = 0.01*dst.max() img[dst>threshold]=[255,0,0] #[255,0,0] - 点的颜色:蓝色, [0,255,0] - 绿色, [0,0,255] - 红色, #[0,0,0] -白色, [255,255,255] - 黑色 plt.axis('off') plt.imshow(img, cmap='gray') plt.show() #使用另一种角点检测函数 corners = cv2.goodFeaturesToTrack(gray, 6, 0.01, 5) corners = np.int0(corners) for i in corners: x, y = i.ravel() cv2.circle(img, (x, y), 5, [0,0,0], -1) plt.axis('off') plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.show() #直线检测 img = cv2.imread("road.jpeg") plt.axis('off') plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.show() #canny 方法检测边缘 返回二值图像 edges = cv2.Canny(gray, 150, 300) plt.axis('off') plt.imshow(edges, cmap='gray') plt.show() #HoughLinesP方法判断哪些边缘是直线 lines = cv2.HoughLinesP(edges, rho=1.0,theta=np.pi/180,threshold=20,minLineLength=30,maxLineGap=10) line_img = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8) line_color = [0, 255, 0] line_thickness = 2 dot_color = [0, 255, 0] dot_size = 3 #讲检测的直线叠加到原图 for line in lines: for x1, y1, x2, y2 in line: cv2.line(line_img, (x1, y1), (x2, y2), line_color, line_thickness) cv2.circle(line_img, (x1, y1), dot_size, dot_color, -1) cv2.circle(line_img, (x2, y2), dot_size, dot_color, -1) final = cv2.addWeighted(img, 0.8, line_img, 1.0, 0.0) plt.axis('off') plt.imshow(cv2.cvtColor(final, cv2.COLOR_BGR2RGB)) plt.show()
OpenCV:直线检测
主要介绍OpenCV自带的直线检测函数HoughLines()的用法,这个函数的第一个参数是一个二值化图像,所以在进行霍夫变换之前要首先进行二值化,或者进行Canny 边缘检测。第二和第三个值分别代表β 和 θ 的精确度。
第四个参数是阈值,只有累加其中的值高于阈值时才被认为是一条直线,也可以把它看成能检测到的直线的最短长度(以像素点为单位)。返回值就是(β; θ)。β 的单位是像素,θ的单位是弧度。
看代码
#直线检测 #使用霍夫直线变换做直线检测,前提条件:边缘检测已经完成 import cv2 as cv import numpy as np import matplotlib.pylab as plt #标准霍夫线变换 def line_detection(image): gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) edges = cv.Canny(gray, 50, 150, apertureSize=3) #apertureSize参数默认其实就是3 cv.imshow("edges", edges) lines = cv.HoughLines(edges, 1, np.pi/180, 80) for line in lines: rho, theta = line[0] #line[0]存储的是点到直线的极径和极角,其中极角是弧度表示的。 a = np.cos(theta) #theta是弧度 b = np.sin(theta) x0 = a * rho #代表x = r * cos(theta) y0 = b * rho #代表y = r * sin(theta) x1 = int(x0 + 1000 * (-b)) #计算直线起点横坐标 y1 = int(y0 + 1000 * a) #计算起始起点纵坐标 x2 = int(x0 - 1000 * (-b)) #计算直线终点横坐标 y2 = int(y0 - 1000 * a) #计算直线终点纵坐标 注:这里的数值1000给出了画出的线段长度范围大小,数值越小,画出的线段越短,数值越大,画出的线段越长 cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) #点的坐标必须是元组,不能是列表。 cv.imshow("image-lines", image) #统计概率霍夫线变换 def line_detect_possible_demo(image): gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) edges = cv.Canny(gray, 50, 150, apertureSize=3) # apertureSize参数默认其实就是3 lines = cv.HoughLinesP(edges, 1, np.pi / 180, 60, minLineLength=60, maxLineGap=5) for line in lines: x1, y1, x2, y2 = line[0] cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) cv.imshow("line_detect_possible_demo",image) src = cv.imread(r'..\edge.jpg') print(src.shape) cv.namedWindow('input_image', cv.WINDOW_AUTOSIZE) cv.imshow('input_image', src) line_detection(src) src = cv.imread(r'..\edge.jpg') #调用上一个函数后,会把传入的src数组改变,所以调用下一个函数时,要重新读取图片 line_detect_possible_demo(src) cv.waitKey(0) cv.destroyAllWindows()
看效果
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
加载全部内容