opencv - 如何获得轮廓的面积?

标签 opencv computer-vision

我有这样一张图片:
origin picture

然后我将其转换为二值图像并使用 canny 检测图片的边缘:

gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)
edge = Image.fromarray(edges)

然后我得到的结果是:
edge pic
我想这样得到 2 的面积:
enter image description here


我的解决办法是用HoughLines在图片中找直线,计算直线组成的三角形的面积。但是,这种方式并不精确,因为闭合区域不是标准三角形。如何获取区域2的面积?

最佳答案

使用 floodFill 的简单方法和 countNonZero可能是以下代码片段。我在 contourArea 上的标准报价来自帮助:

The function computes a contour area. Similarly to moments, the area is computed using the Green formula. Thus, the returned area and the number of non-zero pixels, if you draw the contour using drawContours or fillPoly, can be different. Also, the function will most certainly give a wrong results for contours with self-intersections.

代码:

import cv2
import numpy as np

# Input image
img = cv2.imread('images/YMMEE.jpg', cv2.IMREAD_GRAYSCALE)

# Needed due to JPG artifacts
_, temp = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY)

# Dilate to better detect contours
temp = cv2.dilate(temp, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)))

# Find largest contour
cnts, _ = cv2.findContours(temp, cv2.RETR_EXTERNAL , cv2.CHAIN_APPROX_NONE)
largestCnt = []
for cnt in cnts:
    if (len(cnt) > len(largestCnt)):
        largestCnt = cnt

# Determine center of area of largest contour
M = cv2.moments(largestCnt)
x = int(M["m10"] / M["m00"])
y = int(M["m01"] / M["m00"])

# Initiale mask for flood filling
width, height = temp.shape
mask = img2 = np.ones((width + 2, height + 2), np.uint8) * 255
mask[1:width, 1:height] = 0

# Generate intermediate image, draw largest contour, flood filled
temp = np.zeros(temp.shape, np.uint8)
temp = cv2.drawContours(temp, largestCnt, -1, 255, cv2.FILLED)
_, temp, mask, _ = cv2.floodFill(temp, mask, (x, y), 255)
temp = cv2.morphologyEx(temp, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)))

# Count pixels in desired region
area = cv2.countNonZero(temp)

# Put result on original image
img = cv2.putText(img, str(area), (x, y), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, 255)

cv2.imshow('Input', img)
cv2.imshow('Temp image', temp)

cv2.waitKey(0)

临时图片:

Temporary image

结果图片:

Result image

警告:findContours 在右侧有一些问题,线条非常靠近底部图像边界,导致可能遗漏一些像素。

免责声明:总的来说,我是 Python 的新手,特别是 OpenCV 的 Python API(最好是 C++)。非常欢迎评论、改进和突出 Python 禁忌!

关于opencv - 如何获得轮廓的面积?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55467031/

相关文章:

OpenCV-Stereo : How to check the validity of a 3D point (x, y,z)?

python - 在 Swift 中运行 Python

python - 在图像中绘制隐式函数(Python,[OpenCV])

performance - Opencv级联训练时间

python - 使用 OpenCv-python 的失真效果

python - 使用SSIM尝试比较图像并尝试分别获取亮度,对比度和结构

c++ - 我们如何跳过帧,计算帧数并使用视频阅读器获取当前帧

machine-learning - Caffe中Tiling层的用途是什么

c++ - 如何着手一个非常基本的计算机视觉算法

algorithm - 引导滤波器如何保持强边缘?