计算有机形状的周长

时间:2019-07-03 15:20:37

标签: python image-processing

我已经使用Python通过将白色像素的数量乘以单个像素的面积来计算黑白图像上的面积或不规则形状。

但是,现在我还需要计算这种不规则形状的周长。该形状中可能有孔。这是一个示例图片:

Sample Image

有什么想法可以解决这个问题吗? 我不是一个完全的新手,但我也不是编码员。我猜是经验丰富的初学者。

谢谢。

编辑: 有些事情我还是不明白,但这对我有用:

import cv2
import numpy as np



def import_image(filename):
    original_image = cv2.imread(filename, cv2.IMREAD_UNCHANGED)
    return original_image

#getting original file
img = import_image('PerimeterImage.jpg')

#converting to gray
img_grey = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#set a thresh
thresh = 1

#get threshold image
ret,thresh_img = cv2.threshold(img_grey, thresh, 255, cv2.THRESH_BINARY)

#find contours
image, contours, hierarchy = cv2.findContours(thresh_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

#create an empty image for contours
img_contours = np.zeros(img.shape)

perimeter = 0

for c in contours:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.0001 * peri, True)
    cv2.drawContours(img_contours, [approx], -1, (0, 0, 255), 1)
    perimeter = perimeter + peri

print(f'Perimeter = {int(round(perimeter,0))} pixels')

#show image
cv2.imshow('Output', img_contours)
cv2.waitKey(0)

#save image
cv2.imwrite('contours.jpg', img_contours) 

2 个答案:

答案 0 :(得分:1)

只需使用cv.findContours来找到白色区域的轮廓,通常,您必须在findContours之前进行阈值处理,但是由于您的图像是黑白的,因此您可以忽略它。

对于周长,只需使用cv.arcLength作为您想要的轮廓。

答案 1 :(得分:-1)

我认为没有简单的方法可以做到这一点。

我包括了两种非常相似的方法。两种方法都使用opencv库及其魔术。如果您对简化方法感兴趣,则主要在第二个。

方法1 (首选)

我认为这对您来说是最简单的选择。

import cv2 as cv
img = cv.imread('img.jpg', 0) #Get your image
edges = cv2.Canny(img,100,200)

然后您可以对像素进行计数以获得周长。

关于此的更多信息,请参见here


方法2

  1. 首先,使用拉普拉斯算子获得图像梯度幅度。
laplacian = cv.Laplacian(img, cv.CV_64F)
  1. 然后,您可以移至步骤3或执行此操作以获得更准确的结果。使用非最大抑制使边缘变薄1个像素。这并不容易,但是您可以在上方的精明链接中找到有关此想法的解释。

  2. 计算剩余像素以获取周长。

您应该知道这将是不完美的,因为还会计算物体内部的黑点之类的东西。如果你不想 您可以使用以下方法在非最大抑制之前执行关闭操作:

closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

注意:这些解决方案假定您输入的图像将始终与您提供的图像相同。如果不是,则必须进行一些更改。