一种根据图像面积估计其体积的方法

如图,选择APMCM2019年A题,要求根据该图像中红线圈住的二氧化硅晶体面积估计其体积。
在这里插入图片描述
首先对图像进行二值化出理,得到其边缘在这里插入图片描述
可以通过计算其像素点个数获得其面积,但通过面积推断体积时较为复杂。可能普遍的想法是用球体去近似,但精确度不够高,这里我们使用古鲁金定理给出了一种方法
首先求该图形的形心坐标,然后过形心坐标做垂线平分图形为面积相等的两部分。再任选其中一部分求其形心,这样我们就可以使用古鲁金定理了,示意图为
在这里插入图片描述
即我们采用其某部分面旋转体体积来近似,计算公式为
V = π p S V=\pi pS
其中p为形心到垂线距离,S为图形面积。
代码为

CalVolumeThroughArea.py import cv2 as cv
import numpy as np


datas = []


for i in range(497, 611, 1): m = i
i = '.\\data\\0' + str(i) + '.bmp'


img = cv.imread(i, 0) height = img.shape[0]

ret, thresh = cv.threshold(img, 127, 255, 0)
img2, contours, hierarchy = cv.findContours(thresh, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)


dataEachImage = 0


for j in range(len(contours)): cnt = contours[j]

# compute the area in the contour[j], 50.2655 is the area of crucible and 847887 is the amount of pixels
# of crucible
mask = np.zeros(img.shape, np.uint8) cv.drawContours(mask, [cnt], 0, 255, -1) pixelPoints = cv.findNonZero(mask)
area = len(pixelPoints) * 50.2655 / 847887
# moments of contours[j] M = cv.moments(cnt)
# compute the centroid coordinate if M['m00'] != 0:
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])

else:



cx = 0
cy = 0



if cx != 0 and cy != 0:
x, y, w, h = cv.boundingRect(cnt) for a in range(y, y + h + 1, 1):
mask[a, cx] = 255


for a in range(0, cx, 1):
for b in range(0, height, 1): mask[b, a] = 0
# process the new contour
newRet, newThresh = cv.threshold(mask, 127, 255, 0)
newImg2, newContours, newHierarchy = cv.findContours(newThresh, cv.RETR_EXTERNAL,

cv.CHAIN_APPROX_SIMPLE)


# moments of newContours
newM = cv.moments(newContours[0])
# compute the centroid coordinate if newM['m00'] != 0:
ncx = int(newM['m10'] / newM['m00'])
ncy = int(newM['m01'] / newM['m00'])

else:



ncx = 0
ncy = 0



radius = abs(ncx - cx) * 8 / 1039 perimeter = 2 * 3.1415926 * radius dataEachImage += perimeter * area / 2

datas.append(dataEachImage)  i = m



output = open(".\\results\\Volume.xls", 'w', encoding='gbk') output.write('pictureNum\tVolume\n')
for a in range(len(datas)): output.write(str(a + 497)) output.write('\t')


output.write(str(datas[a])) output.write('\t') output.write('\n')
output.close()

我们使用大量图片进行测试,结果为
在这里插入图片描述
看起来效果还算不错。

发布了5 篇原创文章 · 获赞 19 · 访问量 799

猜你喜欢

转载自blog.csdn.net/weixin_43518179/article/details/104737933