image-processing - 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,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,11,2)
a10lvR10_th3 = cv2.adaptiveThreshold(a10lvR10_gblur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY_INV,11,2)
# Otsu's thresholding
ret2,a10lvR10_th4 = cv2.threshold(a10lvR10_gblur,0,255,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, 0), "uint8"))
mask = cv2.medianBlur(mask, 9)
#save cleaned image
cv2.imwrite("out1.jpg", mask)
输出图像的更简洁版本:
输出1:
接下来我们可以得到线条的坐标。我得到了左边第一行的坐标。我认为您必须稍微更改代码才能获得侧边栏的坐标。
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, 0), (bottomLeft, h), (0, 0, 0), 80)
topRight = count(mask[0])
bottomRight = count(mask[h])
# to shadow and hide the old right line
mask = line(mask, (topRight, 0), (bottomRight, h), (0, 0, 0), 80)
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
# to draw new clean left line
mask = line(mask, (topLeft, 0), (bottomLeft, h), (128, 0, 255), 25)
# to draw new clean right line
mask = line(mask, (topRight, 0), (bottomRight, h), (128, 0, 255), 25)
a = center(topLeft, 0, bottomLeft, h)
b = center(topRight, 0, bottomRight, h)
mask = line(mask, a, b, (128, 0, 255), 25)
cv2.imwrite("out2.jpg", mask)
输出2:
现在您可以计算“a”和“b”之间的距离。
推荐阅读
- reactjs - Gatsby Keycloak 集成
- javascript - 未捕获的类型错误:除法不是函数
- swift - Xcode 11.6 在运行测试时崩溃 - 缺少库
- javascript - 如何在 Firestore Web 中将值另存为双精度值?
- java - 无法在函数中获取定义的变量值
- photoshop - Photoshop 条件重命名脚本
- reactjs - 如何创建状态改变时改变图标的两个条件和从API下载的条件
- javascript - react native - 如何从 sqlite 表中获取“狗”列表?
- node.js - 从nodejs中的其他模型sequelize中检索数据
- node.js - nginx没有设置远程客户端ip地址