最长线检测 - python - opencv
Longest line detection - python - opencv
我需要检测给定图像中最长的线,我的图像将类似于:
我在细化后试过,但是细化后的图像像素化了,而且没有保留直线。
还有其他解决办法吗?
谢谢
光辉
您如何看待这个解决方案?
我已经在代码中包含了解释。大致的思路是做一个阈值,把黑色区域提取出来,然后寻找轮廓,挑出最长的那个。
扩张已经完成了所有的工作,已经挑出了指针,但我在里面留下了一些替代代码,用于寻找最长的轮廓以备不时之需。
#!/usr/bin/env python
import sys
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
print img.shape
h, w = img.shape[:2]
# Drop top and bottom area of image with black parts.
img= img[100:h-100, :]
h, w = img.shape[:2]
# Threshold image
ret,th1 = cv2.threshold(img,50,255,cv2.THRESH_BINARY)
# get rid of thinner lines
kernel = np.ones((5,5),np.uint8)
th1 = cv2.dilate(th1,kernel,iterations = 3)
# Determine contour of all blobs found
_, contours0, hierarchy = cv2.findContours( th1.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
contours = [cv2.approxPolyDP(cnt, 3, True) for cnt in contours0]
# Draw all contours
vis = np.zeros((h, w, 3), np.uint8)
cv2.drawContours( vis, contours, -1, (128,255,255), 3, cv2.LINE_AA)
# Draw the contour with maximum perimeter (omitting the first contour which is outer boundary of image
# Not necessary in this case
vis2 = np.zeros((h, w, 3), np.uint8)
perimeter=[]
for cnt in contours[1:]:
perimeter.append(cv2.arcLength(cnt,True))
print perimeter
print max(perimeter)
maxindex= perimeter.index(max(perimeter))
print maxindex
cv2.drawContours( vis2, contours, maxindex +1, (255,0,0), -1)
# Show all images
titles = ['Original Image','Threshold','Contours', 'Result']
images=[img, th1, vis, vis2]
for i in xrange(4):
plt.subplot(2,2,i+1)
plt.imshow(images[i],'gray')
plt.title(titles[i]), plt.xticks([]), plt.yticks([])
plt.show()
[编辑]
您可以添加一些代码来确定等高线的主轴,如下所示:
# Determine and draw main axis
length = 300
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)
print np.pi , angle
print angle * np.pi / 180.0
print np.cos(angle * np.pi / 180.0)
x2 = int(round(x + length * np.cos((angle-90) * np.pi / 180.0)))
y2 = int(round(y + length * np.sin((angle-90) * np.pi / 180.0)))
cv2.line(vis2, (int(x), int(y)), (x2,y2), (0,255,0),5)
print x,y,x2,y2
我需要检测给定图像中最长的线,我的图像将类似于:
我在细化后试过,但是细化后的图像像素化了,而且没有保留直线。
还有其他解决办法吗?
谢谢 光辉
您如何看待这个解决方案?
我已经在代码中包含了解释。大致的思路是做一个阈值,把黑色区域提取出来,然后寻找轮廓,挑出最长的那个。
扩张已经完成了所有的工作,已经挑出了指针,但我在里面留下了一些替代代码,用于寻找最长的轮廓以备不时之需。
#!/usr/bin/env python
import sys
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
print img.shape
h, w = img.shape[:2]
# Drop top and bottom area of image with black parts.
img= img[100:h-100, :]
h, w = img.shape[:2]
# Threshold image
ret,th1 = cv2.threshold(img,50,255,cv2.THRESH_BINARY)
# get rid of thinner lines
kernel = np.ones((5,5),np.uint8)
th1 = cv2.dilate(th1,kernel,iterations = 3)
# Determine contour of all blobs found
_, contours0, hierarchy = cv2.findContours( th1.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
contours = [cv2.approxPolyDP(cnt, 3, True) for cnt in contours0]
# Draw all contours
vis = np.zeros((h, w, 3), np.uint8)
cv2.drawContours( vis, contours, -1, (128,255,255), 3, cv2.LINE_AA)
# Draw the contour with maximum perimeter (omitting the first contour which is outer boundary of image
# Not necessary in this case
vis2 = np.zeros((h, w, 3), np.uint8)
perimeter=[]
for cnt in contours[1:]:
perimeter.append(cv2.arcLength(cnt,True))
print perimeter
print max(perimeter)
maxindex= perimeter.index(max(perimeter))
print maxindex
cv2.drawContours( vis2, contours, maxindex +1, (255,0,0), -1)
# Show all images
titles = ['Original Image','Threshold','Contours', 'Result']
images=[img, th1, vis, vis2]
for i in xrange(4):
plt.subplot(2,2,i+1)
plt.imshow(images[i],'gray')
plt.title(titles[i]), plt.xticks([]), plt.yticks([])
plt.show()
[编辑]
您可以添加一些代码来确定等高线的主轴,如下所示:
# Determine and draw main axis
length = 300
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)
print np.pi , angle
print angle * np.pi / 180.0
print np.cos(angle * np.pi / 180.0)
x2 = int(round(x + length * np.cos((angle-90) * np.pi / 180.0)))
y2 = int(round(y + length * np.sin((angle-90) * np.pi / 180.0)))
cv2.line(vis2, (int(x), int(y)), (x2,y2), (0,255,0),5)
print x,y,x2,y2