Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 计算有机形状的周长_Python_Image Processing - Fatal编程技术网

Python 计算有机形状的周长

Python 计算有机形状的周长,python,image-processing,Python,Image Processing,我使用Python计算黑白图像的面积或不规则形状,方法是将白色像素数乘以单个像素的面积 但是,现在我还需要计算这个不规则形状的周长。这个形状可能有洞。下面是一个示例图像: 有没有办法解决这个问题? 我不是一个完全的新手,但我也不是一个程序员。我想是有经验的初学者吧 提前谢谢 编辑: 有些事情我仍然不明白,但这对我很有用: import cv2 import numpy as np def import_image(filename): original_image = cv2.i

我使用Python计算黑白图像的面积或不规则形状,方法是将白色像素数乘以单个像素的面积

但是,现在我还需要计算这个不规则形状的周长。这个形状可能有洞。下面是一个示例图像:

有没有办法解决这个问题? 我不是一个完全的新手,但我也不是一个程序员。我想是有经验的初学者吧

提前谢谢

编辑: 有些事情我仍然不明白,但这对我很有用:

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) 

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

我包括了两种非常相似的方法。这两种方法都使用opencv库及其魔力。如果您对如何实现这一点的简化版本感兴趣,那么第二个版本主要在那里

方法1(首选)

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

将cv2作为cv导入
img=cv.imread('img.jpg',0)#获取您的图像
边缘=cv2.Canny(img,100200)
然后你可以计算像素数得到周长

更多关于这方面的信息可以找到


方法2

  • 首先,使用拉普拉斯算子得到图像的梯度大小
  • 然后,您可以移动到步骤3或执行此操作以获得更精确的结果。使用“非最大抑制”使边变薄1像素。这并不容易,但你可以在上面的canny链接中找到对其背后思想的解释

  • 计算剩余像素以获得周长

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

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

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

    只需使用来查找白色区域的轮廓,通常,在
    查找轮廓之前,您必须先执行阈值,但由于您的图像是黑白的,因此您可以忽略它


    对于周长,只需使用您想要的轮廓即可。

    查看OpenCV
    findContours()
    。。。看这里。它包含MATLAB代码,但至少应该告诉您足够多的信息,以避免下面的答案中所示的解决方案。谢谢,建议的最后一种方法对我有效。1:沿轮廓计算像素严重低估了周长。2:Canny和Laplacian零交叉都是在灰度图像中查找边缘的方法。OP中的图像是二进制的,不需要做任何复杂的事情来找到周长。
    closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)