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

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

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值