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

这篇具有很好参考价值的文章主要介绍了opencv计算植物叶面积_叶直径_叶周长_python。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

项目简介:

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

opencv 根据面积计算直径,opencv实战项目,python实训项目,opencv,python,人工智能,学习方法,pycharm,计算机视觉,程序人生

实现方法:

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

opencv 根据面积计算直径,opencv实战项目,python实训项目,opencv,python,人工智能,学习方法,pycharm,计算机视觉,程序人生

opencv 根据面积计算直径,opencv实战项目,python实训项目,opencv,python,人工智能,学习方法,pycharm,计算机视觉,程序人生

然后我们的步骤是:

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

opencv 根据面积计算直径,opencv实战项目,python实训项目,opencv,python,人工智能,学习方法,pycharm,计算机视觉,程序人生

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

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

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

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

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

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

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

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

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

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

源码分享:

opencv 根据面积计算直径,opencv实战项目,python实训项目,opencv,python,人工智能,学习方法,pycharm,计算机视觉,程序人生

opencv 根据面积计算直径,opencv实战项目,python实训项目,opencv,python,人工智能,学习方法,pycharm,计算机视觉,程序人生

opencv 根据面积计算直径,opencv实战项目,python实训项目,opencv,python,人工智能,学习方法,pycharm,计算机视觉,程序人生

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

get_area_final.py:

import cv2
import numpy as np

def 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_sizes

def 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 21
    s_ye = (p_ye * s_zhi) / p_zhi
    zhi_chang_jia=img.shape[0]
    zhi_changzheng=29.7
    ye_long_zheng=(zhi_changzheng*2*radius)/zhi_chang_jia
    return 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 np

minArea = 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,finalCountours



def 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 myPointsNew


def 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 imgWarp



def 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 + '/' + imgname
        get_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 + '/' + imgname
        get_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博客

1 1
2 2
3 3

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

到了这里,关于opencv计算植物叶面积_叶直径_叶周长_python的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++ 设计一个Rectangle类,计算周长,面积,并绘制出来

    我们先创建具有属性length(长度)和width(宽度)的类Rectangle(长方形),这两个属性的默认值为1。分别提供计算长方形 perimeter (周长)和 area (面积)的 成员函数 。另外,为 length 和 width 两个属性提供 设置 和 获取 函数。设置函数应该验证length和width是大于0.0且小于20.0的 浮点数 。  

    2024年02月05日
    浏览(39)
  • chatgpt赋能python:Python计算面积和周长的简单方法

    Python是一门高级编程语言,已经成为了当前世界上最受欢迎的编程语言之一。在Python中,我们可以使用一些简单的方法来计算面积和周长。本文将介绍几种用Python计算面积和周长的简单方法。 矩形 矩形是最简单的图形之一。Python可以轻松计算矩形的面积和周长。 输出结果:

    2024年02月05日
    浏览(51)
  • java定义能计算圆的面积、周长的类 Circle

    定义能计算圆的面积、周长的类 Circle,半径r为私有数据变量,其值由类circle的构造方法初始化,类circle提供读取半径r的方法getr();t算面积的方法area();计算周长的方法circlelength()。再定义类Circlecomputer,其包含程序运行所需的方法main,请设计程序完成初始化数据变量和

    2024年02月08日
    浏览(42)
  • 定义一个圆类Circle,成员变量:半径 radius;成员方法:构造方法、get和set半径的方法、计算面积和周长的方法。

    (1)定义一个圆类Circle,成员变量:半径 radius;成员方法:构造方法、get和set半径的方法、        计算面积和周长的方法。定义圆柱和圆锥类,定义相应的变量成员和成员方法。使用以上类编         程,输出圆的面积和圆柱、圆锥的体积。

    2024年02月12日
    浏览(44)
  • 编写一个类为Rectangle。该类有两个属性: 长(length)和宽(width),计算矩形面积周长。写另外一个类,来检验自己编写的类中的方法是否正确。

    编写一个类为Rectangle. 该类有两个属性: 长(length)和宽(width)默认值为1,该两个变量为私有的,即private. 其它方法为: 构造方法:public Rectangle();   Public Rentangle(double length, double width); 方法: 矩形对象调用该方法,可以得到面积:public double getArea() 矩形对象调用该方法,可以

    2024年02月05日
    浏览(45)
  • c语言求圆的面积和周长(c语言求圆的面积和周长,半径为5)

    用c语言计算圆周长和面积编程有两种。 #include #define PI 3.1415926 int main(){ double r,l,s; printf(\\\"请输入半径:\\\"); scanf(\\\"%lf\\\",r); if(r=0)printf(\\\"输入错误!\\\"); else { l=PI*2*r; s=PI*r*r; printf(\\\"周长=%lf 面积=%lfn。\\\",l,s); (return 0;) #include #include #define PI 3.14 void main() { float r; double c; double s; printf(\\\"请输入

    2024年02月07日
    浏览(36)
  • 定义矩形类,求其面积和周长(java)

    编写一个 矩形 类 R ectangle,该类拥有: 两个 成员变量 : Length(私有,双精度型); // 存放矩形的长;      Width(私有,双精度型); // 存放矩形的宽;       两个构造方法 :     1.Rectangle ( )            // 将高和宽设为0          2.Rectangle (double l,double W

    2024年04月12日
    浏览(38)
  • JavaScript实现输入圆的半径,输出周长、体积和面积的代码

    以下为输入圆的半径,输出周长、体积和面积实现结果的代码和运行截图 目录 前言 一、请输入圆的半径,输出周长、体积和面积 1.1运行流程及思想 1.2代码段 1.3 JavaScript语句代码 1.4运行截图 1.若有选择,您可以在目录里进行快速查找; 2.本博文代码可以根据题目要求实现相关

    2024年02月07日
    浏览(39)
  • OpenCV 通过计算连通域面积过滤面积小的区域–Python

    代码参考:https://blog.csdn.net/u014264373/article/details/119486850 通过卷积神经网络预测图像的分割结果时,会发现分割外部出现了小面积的连通域。 常识告诉我们,这么小的物体一定不是我们的分割目标,因此,我们通过后处理的方法把它过滤掉,可以提高分割准确度。 这种小面积

    2024年02月08日
    浏览(60)
  • 计算机竞赛 python+深度学习+opencv实现植物识别算法系统

    🔥 优质竞赛项目系列,今天要分享的是 🚩 基于深度学习的植物识别算法研究与实现 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:4分 工作量:4分 创新点:4分 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/postgraduate Google DeepMind公司研究员与牛津大学计算

    2024年02月12日
    浏览(76)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包