基于图片求体积的算法
发表于|更新于
|字数总计:735|阅读时长:3分钟|阅读量:
浅记录一下学院数模赛的算法流程
题目
自拟场景和尺寸,在有参照物的情况下,依据图片,建立模型估计以下土堆的立方数
思路及算法
思路
-
筛选出需要的土堆和挖掘机部分
-
根据轮廓利用古鲁金定理计算像素体积
-
根据挖掘机在图片中的面积以及实际尺寸计算图片和实际长度的转化关系
-
代入计算的土堆像素体积获得实际体积
因为python的opencv
只能识别HSV
三通道参数,需要根据HSV
表来粗筛选土堆和挖掘机
HSV
颜色参考:
算法
封装了一个计算形心相对图片坐标的函数ShapeHeart
,输入为图片,标识名称,HSV高低数组,返回值为形心坐标cx和cy,和轮廓的像素面积,输出二值化图片,红线轮廓图片以及蓝色形心图片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
import math import cv2 as cv import numpy as np def ShapeHeart(img,name,low,high): img = cv.GaussianBlur(img, (5, 5), 0) cv.imwrite("./pic"+"/"+name+"_Gauss.jpg",img) """ 提取颜色 """ hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV) low_hsv = np.array(low) high_hsv = np.array(high) mask = cv.inRange(hsv, lowerb=low_hsv, upperb=high_hsv) cv.imshow(name+"_Grayscale",mask) cv.waitKey(0) cv.destroyAllWindows() cv.imwrite("./pic"+"/"+name+"_Grayscale.jpg", mask) contours, hierarchy = cv.findContours(mask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) cv.drawContours(img, contours, -1, (0, 0, 255), 1) cv.imwrite("./pic"+"/"+name+"_Outline.jpg",img) cv.imshow(name+"_Outline",img) cv.waitKey(0) cv.destroyAllWindows() areas = [] for c in range(len(contours)): areas.append(cv.contourArea(contours[c])) MAX = areas.index(max(areas)) M = cv.moments(contours[MAX]) cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) cv.circle(img, (cx, cy), 1, (255,0,0), 0) cv.imwrite("./pic" + "/" + name + "_ShapeHeart.jpg", img) area = cv.contourArea(contours[MAX]) return cx, cy, area
|
土堆计算的主函数:
1 2 3 4 5 6 7 8 9
| if __name__ == "__main__": img = cv.imread('tudui.jpg') cx,cy,area = ShapeHeart(img,name="Mound",low=[78, 40, 120],high=[100, 255, 255]) print(cx,cy,area) img1 = img[0:img.shape[0], 0:cx] cx1,cy1,area1 = ShapeHeart(img1,name="Mound1",low=[78, 40, 120],high=[100, 255, 255]) print(cx1,cy1,area1) V = 2*abs(cx-cx1)*math.pi*area/2*math.pow(0.033082679182000536,3) print(V)
|
其中V计算中math.pow
用的是计算获得的像素与实际长度转化关系,这个值准确性有待提高,因为挖掘机的具体参数并未获得,计算过程中没有很好考虑视角造成的长度影响
卡车计算的额外步骤:
1 2 3
| space = (math.cos(math.pi/3)+math.cos(math.pi/6))*0.84*2.22
a = math.sqrt(space/area)
|
这个算法只能初步实现分离物体,如果需要更加精细还需要改进