如何解决OpenCV - 计算图像中两个边缘之间的距离
我正在尝试计算图像中两个边缘之间的距离(以像素数为单位)。我已经使用 cv2.warpPerspective
方法校正了图像透视,并将生成的图像转换为灰度,然后使用高斯模糊进行过滤。我尝试了各种阈值方法,发现 cv2.ADAPTIVE_THRESH_GAUSSIAN
效果最好。从自适应高斯阈值的结果可以看出,其他方法噪声太大或错过了对象左侧的第二个边缘。
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Load the image
imgRoadvR10 = cv2.imread('sampleimage.jpg') # image is already corrected for perspective warp using cv2.warpPerspective
# convert to grayscale
imgRoadvR10_GrayPersp = cv2.cvtColor(imgRoadvR10,cv2.COLOR_BGR2GRAY)
# gaussian blur
a10lvR10_gblur = cv2.GaussianBlur(imgRoadvR10_GrayPersp,(5,5),0)
# Try different thresholding methods
ret,a10lvR10_th1 = cv2.threshold(a10lvR10_gblur,127,255,cv2.THRESH_BINARY)
a10lvR10_th2 = cv2.adaptiveThreshold(a10lvR10_gblur,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,11,2)
a10lvR10_th3 = cv2.adaptiveThreshold(a10lvR10_gblur,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY_INV,2)
# Otsu's thresholding
ret2,a10lvR10_th4 = cv2.threshold(a10lvR10_gblur,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
print(ret2)
# Plot results
plt.figure()
titles = ['Original Image','Global Thresholding (v = 127)','Adaptive Mean Thresholding','Adaptive Gaussian Thresholding','OTSU Thresholding']
images = [a10lvR10_gblur,a10lvR10_th1,a10lvR10_th2,a10lvR10_th3,a10lvR10_th4]
for i in range(5):
plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
我想找到这个矩形对象的宽度。宽度是从左侧的第二个边缘到右侧的边缘测量的(见下图):
如何测量宽度?我一直在阅读形态学操作和边缘检测,但不确定下一步如何进行。任何建议将不胜感激
解决方法
这不是最好的主意,我认为可以获得更合乎逻辑和更简单的解决方案。但是,这个想法可能对您有所帮助。
import cv2
import numpy as np
#load image
im = cv2.imread("test3.jpg",1)
#Convert to gray
mask = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
#convert to black and white
mask = cv2.threshold(mask,127,255,cv2.THRESH_BINARY)[1]
#try to remove noise
#you can just use median blur or any other method
mask = cv2.erode(mask,np.ones((8,0),"uint8"))
mask = cv2.dilate(mask,np.ones((32,"uint8"))
mask = cv2.medianBlur(mask,9)
#save cleaned image
cv2.imwrite("out1.jpg",mask)
输出图像的更清晰版本:
out1:
接下来我们可以得到线条的坐标。我从左边得到了第一行的坐标。我认为您必须稍微更改代码才能获得侧边栏的坐标。
h = len(mask) - 1
def count(row):
counter = 0
for i in range(0,len(row)):
if row[i] == 255:
break
counter += 1
return counter
def line(im,pt1,pt2,color,thickness):
im = cv2.line(
img=im,pt1=pt1,pt2=pt2,color=color,thickness=thickness,lineType=cv2.LINE_AA,)
return im
def center(x1,y1,x2,y2):
return (int((x1 + x2) / 2),int((y1 + y2) / 2))
topLeft = count(mask[0])
bottomLeft = count(mask[h])
# to shadow and hide the old left line
mask = line(mask,(topLeft,(bottomLeft,h),(0,80)
topRight = count(mask[0])
bottomRight = count(mask[h])
# to shadow and hide the old right line
mask = line(mask,(topRight,(bottomRight,80)
mask = cv2.cvtColor(mask,cv2.COLOR_GRAY2BGR)
# to draw new clean left line
mask = line(mask,(128,255),25)
# to draw new clean right line
mask = line(mask,25)
a = center(topLeft,bottomLeft,h)
b = center(topRight,bottomRight,h)
mask = line(mask,a,b,25)
cv2.imwrite("out2.jpg",mask)
out2:
现在您可以计算“a”和“b”之间的距离。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。