python - 找到形状的确切边缘
问题描述
我想计算红外相机产生的图像中形状的面积。
我有大量的矩阵,它们是由红外相机产生的。在每个矩阵/图像中,我主要有一个带有斑点图像的背景,这是红外辐射的来源。我继续使用它的方法是使用 Python OpenCV 通过使背景无效并计算形状中的像素数来隔离源图像。问题是在每张图像中,图像的一部分也变成了背景,所以我无法获得完整的图像,就像我想要的那样。
import cv2
import numpy as np
from matplotlib import pyplot as plt
PPmm = 81/55 #Pixel per mm
img = np.genfromtxt('Image 5 Z_plane = 141.0_contour_plot.csv', delimiter= ',')
img_cv = cv2.resize(img,(81,81))
np.savetxt('testing.csv', img_cv, delimiter= ',')
img = (img_cv*255).astype(np.uint8)
edges = cv2.Canny(img,150,250)
se = np.ones((7,7), dtype='uint8')
# Perform morphology
image_close = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, se)
# Your code now applied to the closed image
cnt = cv2.findContours(image_close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
mask = np.zeros(img.shape[:2], np.uint8)
cv2.drawContours(mask, cnt, -1, 255, -1)
non_zero_pixel_count = (np.count_nonzero(mask))
Area_in_mm = non_zero_pixel_count*(1/PPmm)**2
print("Area of shape = {0:1f}mm^2".format(Area_in_mm))
plt.subplot(121)
plt.imshow(img,cmap = 'gray')
plt.title('Original Image')
plt.xticks([])
plt.yticks([])
plt.subplot(122)
plt.imshow(mask,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
[enter image description here][1]
plt.show()
形状面积为:58.093278mm^2。如果我手动计算,大约我会得到 68mm^2。在圆形图像中,情况更糟,我得到的面积是原来的两倍
圆形图像
方形图像
解决方案
要获得形状的确切边缘,您可以这样做
- 临界点
- 寻找轮廓
- 计算所有非零像素
找到轮廓形状后,您可以使用cv2.countNonZero()
查找所有白色像素,然后使用校准的像素度量来计算面积(我的面积不同,因为我不是精确的原始图像)
import cv2
image = cv2.imread('2.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 20, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(image,[c], 0, (36,255,12), 2)
area = cv2.countNonZero(thresh)
cv2.putText(image, "Area: {}".format(area), (40, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (156, 188, 24), 1)
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.imwrite('thresh.png', thresh)
cv2.imwrite('image.png', image)
cv2.waitKey()
推荐阅读
- bash - sed 命令在文件中添加额外的字符
- flowtype - 如何在不嵌入文字的情况下创建 Flow Union 运行时细化
- django - django管理页面登录导致IIS崩溃,每次都需要重启iis
- c++ - _tfopen 出现错误 22 的可能原因是什么?
- java - Json反序列化错误Spring Boot测试 - 无法构造实例
- python-3.x - 如何安装上下文?
- matlab - 使用 Matlab 构建时,OpenCV 无法链接 libtiff
- nativescript - 在 WebView 中填充 HTML 表单
- python - 在减少之前屏蔽一维张量的特定元素
- sql - 从 Postgresql 的视图中选择随机样本