python 基于opencv实现玉米籽粒计数

有效避免籽粒摆放紧密而导致识别不准确的问题

背景采用黑色卡纸(不反光即可)

称重后可以进行百粒重计算

 

import time
import cv2,os
import numpy as np


def myfunc(img):
    # img = cv2.imread(t_)
    font = cv2.FONT_HERSHEY_COMPLEX
    kernel = np.ones((5,5), np.uint8)

    h,w,c = img.shape
    img = cv2.resize(img,(int(1000*(w/h)),1000))#(w,h)
    # cv2.imshow('ori', img)
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 灰度处理
    # cv2.imshow('gray_img', gray_img)
    ret, th1 = cv2.threshold(gray_img, 150, 255, cv2.THRESH_BINARY)
    # cv2.imshow('th1', th1)
    erosion = cv2.erode(th1, kernel, iterations=1)  # 腐蚀
    # cv2.imshow('erosion', erosion)
    dist_img = cv2.distanceTransform(erosion, cv2.DIST_L1, cv2.DIST_MASK_3)  # 距离变换
    # cv2.imshow('ditancechange', dist_img)
    dist_output = cv2.normalize(dist_img, 0, 1.0, cv2.NORM_MINMAX)  # 归一化  这里的归一化取得了什么效果?
    a = 130 #显示程度
    b = 0.23#腐蚀程度  多次参数调整也无法避免籽粒出现粘连的情况

    # cv2.imshow('dist_output', dist_output * a)

    ret, th2 = cv2.threshold(dist_output*a, b, 255, cv2.THRESH_BINARY)#这里调整系数 发现a = 120 b = 0.27比较符合正常的籽粒大小
    # cv2.imshow('th2', th2)

    kernel = np.ones((3,3), np.uint8)
    opening = cv2.morphologyEx(th2, cv2.MORPH_OPEN, kernel)

    # cv2.imshow('opening', opening)
    opening = np.array(opening, np.uint8)
    contours, hierarchy = cv2.findContours(opening, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # 轮廓提取

    count_ = 0
    Allarea_circle = 0

    for cnt in contours:
        (x, y), radius = cv2.minEnclosingCircle(cnt)#画圆
        center = (int(x), int(y))#中心点
        radius = int(radius)#半径
        # circle1_img = cv2.circle(opening, center, radius, (128,0,128), 2)
        # cv2.imshow('circle1_img',circle1_img)#黑白图的实际结果 测试用
        cv2.circle(img, center, radius, (128, 0, 128), 1)#画圆

        # circle_img = cv2.circle(img, center, radius, (128,0,128), 1)#画圆
        # cv2.imshow('circle_img',circle_img)

        area_circle=3.14*radius*radius
        Allarea_circle +=area_circle
        count_ += 1
    aver_area_circle = Allarea_circle / count_#计算平均玉米粒外接圆半径

    count = 0
    for cnt in contours:#在这里使用外接圆的面积来增加容错率
        (x, y), radius = cv2.minEnclosingCircle(cnt)
        center = (int(x), int(y))
        radius = int(radius)
        area_circle=3.14*radius*radius

        if area_circle>=2*aver_area_circle:#判断两个籽粒黏连的情况

            img = cv2.putText(img, str(count)+'  '+str(count+1), center, font, 0.5, (0, 0, 255))
            count += 2#半径过大就算作两个
        else:
            img = cv2.putText(img, str(count), center, font, 0.5, (0, 0, 255))
            count += 1

    img=cv2.putText(img,('Findall='+str(count)),(10,40),font,1,(0,20,255),2)#添加文字到图上 总数

    cv2.imshow('circle_img',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    print('玉米粒共有:',count)

    x = input("称重结果?  (g):")
    try:#用于判断百粒重数字键入 形式是否正确
        s = "百粒重:%fg" %((eval(x) / count)*100)
        print(s)
    except:
        print("请输入百粒重 单位g")
        time.sleep(1)

opp = 0
while opp<=10:
    opp+=1
    wenben = input("把图片拖拽到当前窗口来获得文件路径..... enter 以得到结果")
    if os.path.exists(wenben):#用于判断文件路径的输入是否正确
        t_ = cv2.imread(wenben)
        myfunc(t_)
    else:
        print("输入错误????????")
else:
    print("made by ZKY \n晚安小点点")
    time.sleep(2)
    print("")
    time.sleep(3)

你可能感兴趣的:(opencv,python,计算机视觉)