opencv计算植物叶面积_叶直径_叶周长_python

2024-01-23 09:50

本文主要是介绍opencv计算植物叶面积_叶直径_叶周长_python,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

项目简介
实习方法
源码分享

项目简介:

利用python自带的opencv库来计算植物叶片的叶面积、叶直径和叶周长,拍摄图片就可以直接得到真实的叶面积、叶直径和叶周长。

实现方法:

首先,我们需要这样拍摄一张植物的图片,需要一个黑色的底板,一张A4纸,拍摄时需要将植物叶面放平,A4纸的四个直角都需要拍摄进照片中,确保A4纸与底下的黑色卡纸在照片边上有黑边(既是为了方便拍摄,也是为了方便计算):

然后我们的步骤是:

找出照片中的最大轮廓(此时理所当然是我们的A4纸)→进行图像的矫正透视变换将照片的黑边去掉

如何一步到位拿到真实值?

我们知道要想得到真实的叶面积、叶直径和叶周长,需要一些已知长度的东西来作为比例对照物,这里我选择用A4纸来作为现实比例对照物,通过

公式(1):测得植物像素值/植物真实值=测得A4纸像素值/A4真实值

这里面的“测得植物像素值”“测得A4纸像素值”和“A4真实值”我们都知道,那么就可以计算植物真实值。

如何得到植物的真实叶面积?

去黑边照片→找到最大轮廓(理所当然是植物轮廓)→得到轮廓的像素面积→公式(1)计算

如何得到植物的真实叶直径?

去黑边照片→找到最大轮廓(理所当然是植物轮廓)→对该轮廓画圆→得到圆的直径(直径即为植物叶直径)→公式(1)计算

如何得到植物的真实叶周长?

去黑边照片→找到最大轮廓(理所当然是植物轮廓)→得到该轮廓周长(该轮廓周长即为植物叶周长)→公式(1)计算

源码分享:

img1为带黑边的原始图像,warp_imgs为图像矫正透视变换后的去黑边图像,其余py文件分享在下面,计算周长的代码自行去获取轮廓周长套公式(1)进行计算:

get_area_final.py:

import cv2
import numpy as npdef sort_contours_size(cnts):"""根据大小对轮廓进行排序"""cnts_sizes = []for contour in cnts:cnt_size = cv2.contourArea(contour)cnts_sizes.append([cnt_size,contour])cnts_sizes.sort(key=lambda x:x[0], reverse=True)return cnts_sizesdef get_area_main(path):img = cv2.imread(path)#变成单通道的黑白图片gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#二值化 返回阈值和二值化后图thresh,binary = cv2.threshold(gray,150,255,cv2.THRESH_BINARY)# cv2.imshow("img1",binary)# cv2.waitKey(0)# cv2.destroyAllWindows()# 查找轮廓 返回轮廓和层级contours, hierarchy = cv2.findContours(binary.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 绘制轮廓会直接修改原图img_copy = img.copy()cv2.drawContours(img_copy, contours, -1, (0, 0, 255), 2)# cv2.imshow('img_con', img_copy)# cv2.waitKey(0)# cv2.destroyAllWindows()contour_sizes = sort_contours_size(contours)cnt = contour_sizes[1][1](x, y), radius = cv2.minEnclosingCircle(cnt)center = (int(x), int(y))radius = int(radius)# print(center,radius)cv2.circle(img_copy, center, radius, (255, 0, 0), 2)# cv2.imshow('img_con2', img_copy)# cv2.waitKey(0)# cv2.destroyAllWindows()p_zhi = contour_sizes[0][0]p_ye = contour_sizes[1][0]# print(p_zhi,p_ye)s_zhi = 623.7  # 纸29.7 21s_ye = (p_ye * s_zhi) / p_zhizhi_chang_jia=img.shape[0]zhi_changzheng=29.7ye_long_zheng=(zhi_changzheng*2*radius)/zhi_chang_jiareturn s_ye,ye_long_zheng
# path="warp_imgs/warp3.jpg"
# img = cv2.imread(path)
# print(img.shape[0])

get_warp_img_final.py:

import cv2
import numpy as npminArea = 1000
filter = 4
scale = 2
wp = 210 * scale
hp = 297 * scale
def getContours(img):imgG = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)imgBlur = cv2.GaussianBlur(imgG,(5,5),1)imgCanny = cv2.Canny(imgBlur,100,100)kernel = np.ones((5,5))imgDial = cv2.dilate(imgCanny,kernel,iterations=3)imgThre = cv2.erode(imgDial,kernel,iterations=2)# cv2.imshow('res',imgCanny)# cv2.imshow('res2',imgThre)contours, hiearchy = cv2.findContours(imgThre,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)finalCountours = []for i in contours:area = cv2.contourArea(i)if area> minArea:# 计算轮廓的周长,true表示轮廓为封闭peri = cv2.arcLength(i,True)#进行轮廓的多边拟合appprox = cv2.approxPolyDP(i,0.02*peri,True)bbox = cv2.boundingRect(appprox)if filter > 0 :if(len(appprox))==filter:finalCountours.append([len(appprox),area,appprox,bbox,i,peri])else:finalCountours.append([len(appprox), area, appprox, bbox, i,peri])# 对第二个数值面积进行排序,为升序,找出轮廓的最大值finalCountours = sorted(finalCountours, key=lambda x: x[1], reverse=True)for con in finalCountours:cv2.drawContours(img,con[4],-1, (0, 0, 255), 4)return img,finalCountoursdef reorder(myPoints):#print(myPoints.shape)myPointsNew = np.zeros_like(myPoints)myPoints = myPoints.reshape((4,2))add = myPoints.sum(1)myPointsNew[0] = myPoints[np.argmin(add)]myPointsNew[3] = myPoints[np.argmax(add)]diff = np.diff(myPoints,axis=1)myPointsNew[1]= myPoints[np.argmin(diff)]myPointsNew[2] = myPoints[np.argmax(diff)]# print(myPoints)# print(myPoints)return myPointsNewdef warpImg (img,points,w,h,pad=20):# print(points)points =reorder(points)pts1 = np.float32(points)pts2 = np.float32([[0,0],[w,0],[0,h],[w,h]])matrix = cv2.getPerspectiveTransform(pts1,pts2)imgWarp = cv2.warpPerspective(img,matrix,(w,h))imgWarp = imgWarp[pad:imgWarp.shape[0]-pad,pad:imgWarp.shape[1]-pad]return imgWarpdef get_warp_main(path):img = cv2.imread(path)img = cv2.resize(img, (0, 0), None, 0.5, 0.5)imgcon, cons= getContours(img)if(len(cons)!=0):maxbox = cons[0][2]new_maxbox = reorder(maxbox)# cv2.imshow('img', imgcon)imgWarp = warpImg(imgcon, new_maxbox, wp, hp)# cv2.imshow('imgWarp',imgWarp)name = path.split('/')[-1]cv2.imwrite("./warp_imgs/warp{}".format(name), imgWarp)

main_final.py:

"""利用opencv读取并显示一个目录下的全部图片"""
import os
import cv2
from get_area_final import get_area_main
from get_warp_img_final import get_warp_main
path = './img1'
# 读取path文件夹下所有文件的名字
imagelist = os.listdir(path)
print(imagelist)
i = 0
for imgname in imagelist:if (imgname.endswith(".jpg")):full_path = path + '/' + imgnameget_warp_main(full_path)name = imgname.split('.')[0]print('name:',imgname,"完成")i += 1
print(i)path = './warp_imgs'
# 读取path文件夹下所有文件的名字
imagelist = os.listdir(path)
print(imagelist)
i = 0
for imgname in imagelist:if (imgname.endswith(".jpg")):full_path = path + '/' + imgnameget_area,get_long = get_area_main(full_path)name = imgname.split('.')[0]print('name:',imgname,"area:",get_area,"long:",get_long)i += 1
print(i)

如果这篇文章能够帮助到你的话,还请点个赞赞呀!

Guff_hys_python数据结构,大数据开发学习,python实训项目-CSDN博客

11
22
33

OpenCV是一个开源的计算机视觉和机器学习软件库。它由一系列用C++和Python编写的函数构成,可以在Windows、Linux和Mac操作系统上运行。OpenCV提供了一系列用于图像处理、计算机视觉、模式识别和机器学习的工具和算法,包括图像处理、特征检测、目标识别、运动跟踪、立体视觉和深度学习等功能。OpenCV的应用领域包括医学图像处理、人脸识别、行人检测、自动驾驶、机器人视觉和增强现实等。由于其功能强大和易用性,OpenCV已经成为计算机视觉和图像处理领域的重要工具之一。

这篇关于opencv计算植物叶面积_叶直径_叶周长_python的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/636016

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

XTU 1237 计算几何

题面: Magic Triangle Problem Description: Huangriq is a respectful acmer in ACM team of XTU because he brought the best place in regional contest in history of XTU. Huangriq works in a big compa