如何获得轮廓的面积? [英] How to get the area of the contours?

查看:71
本文介绍了如何获得轮廓的面积?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一张这样的照片:

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

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

然后我得到的结果是:

我想像这样得到 2 的面积:

<小时>

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

解决方案

使用

结果图像:

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

免责声明:总的来说,我是 Python 的新手,特别是 OpenCV 的 Python API(C++ 用于 win).非常欢迎评论、改进、突出显示 Python 禁忌!

I have a picture like this:

And then I transform it into binary image and use canny to detect edge of the picture:

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

And then I get the result as:

I want to get the area of 2 like this:


My solution is to use HoughLines to find lines in the picture and calculate the area of triangle formed by lines. However, this way is not precise because the closed area is not a standard triangle. How to get the area of region 2?

解决方案

A simple approach using floodFill and countNonZero could be the following code snippet. My standard quote on contourArea from the help:

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.

Code:

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:

Caveat: findContours has some problems one the right side, where the line is very close to the bottom image border, resulting in possibly omitting some pixels.

Disclaimer: I'm new to Python in general, and specially to the Python API of OpenCV (C++ for the win). Comments, improvements, highlighting Python no-gos are highly welcome!

这篇关于如何获得轮廓的面积?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆