Обнаружение мелкого объекта - тли на растениях - PullRequest
1 голос
/ 27 марта 2020

В настоящее время я пытаюсь создать детектор тли (зеленого и розового) на растениях, но использую только технику обработки изображений «classi c» (без нейронной сети). Вот изображение, над которым я работаю: 'aphids.jpg'

Я работаю над кодом (см. Ниже). Если вы примените его на изображении, у вас должны быть только растения. Моя проблема в том, что я хочу изолировать тлю, которую можно увидеть на растениях. Их много, но я просто хочу обнаружить самое большое или более очевидное.

В коде есть функция "dge_detect ", над которой я сейчас работаю. Одна из проблем, с которыми я сталкиваюсь, заключается в том, что я могу определить некоторые тли как контур, но при этом они будут принимать простые линии ... Я пытался отбросить эти линии, используя иерархию контуров, но кажется, что эти линии имеют внутренний контур, поэтому я могу ' их легко удалить. Я также попробовал настроить и контрастность, но это не дает такого большого результата.

Я ищу больше идей. Что бы вы попробовали?

Заранее спасибо!

Вот код:

import cv2
import numpy as np
import matplotlib.pyplot as plt

def adjust_gamma(image, gamma=1.0):
    # build a lookup table mapping the pixel values [0, 255] to
    # their adjusted gamma values
    invGamma = 1.0 / gamma
    table = np.array([((i / 255.0) ** invGamma) * 255
        for i in np.arange(0, 256)]).astype("uint8")
    # apply gamma correction using the lookup table
    return cv2.LUT(image, table)

def adjust_contrast(image,alpha=1.0,beta=0):
    new = np.zeros(image.shape,image.dtype)
    for y in range(image.shape[0]):
            for x in range(image.shape[1]):
                for c in range(image.shape[2]):
                        new[y,x,c] = np.clip(alpha*image[y,x,c]+beta,0,255)
    return(new)


def img_process(img):
    (h1, w1) = img.shape[:2]    
    center = (w1 / 2, h1 / 2)
    blur = cv2.GaussianBlur(img.copy(),(5,5),0)
    hsv = cv2.cvtColor(blur,cv2.COLOR_BGR2HSV)  
    #image = img.copy()
    #Boundaries to separate plants from the image
    l_bound = np.array([20,0,0])
    h_bound = np.array([90,250,170])#green 
    mask = cv2.inRange(hsv,l_bound,h_bound)
    res = cv2.bitwise_and(img,img,mask=mask)
    #Find contour plants
    cnt,_ = cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    sort_cnt = sorted(cnt,key=cv2.contourArea,reverse=True)
    cnt = [sort_cnt[i] for i in range(len(sort_cnt)) if cv2.contourArea(sort_cnt[i])>300]
    cv2.drawContours(res, cnt, -1, (0,255,0), -1)
    #Inverse mask to have only the plant in the image
    mask2 = cv2.inRange(res,np.array([0,0,0]),np.array([250,250,250]))
    mask2 = cv2.bitwise_not(mask2)
    res2 = cv2.bitwise_and(img,img,mask=mask2)

        #Augment bright/contrast
    res2=res2*1.45
    res2=res2.astype('uint8')

    #Crop
        res2 = res2[:-50,int(center[0]-300):int(center[0]+550)]


    return res2

def edge_detec(img):
    (h1, w1) = img.shape[:2]    
    center = (w1 / 2, h1 / 2)
    blur = cv2.GaussianBlur(img.copy(),(5,5),0)
    gray = cv2.cvtColor(blur,cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray,30,70,apertureSize = 3)
    edges = edges[:-50,int(center[0]-300):int(center[0]+550)]
    #kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
    #edges = cv2.morphologyEx(edges, cv2.MORPH_GRADIENT, kernel)

    cnt,hierarchy = cv2.findContours(edges,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    cnt = sorted(cnt,key=cv2.contourArea,reverse=True)
    listArea = list(map(cv2.contourArea,cnt))   
    sort_cnt = [x for x in cnt if cv2.contourArea(x)>10]

    cv2.drawContours(edges, sort_cnt, -1, (0,255,0), -1)

    return edges,center,img



### Debut programme
img = cv2.imread('051.jpg')

while True:

    ##Put processing function here
    img_mod = img_process(img)

    cv2.imshow('img',img_mod)

    if cv2.waitKey(1) & 0xFF == 27:
        break


cv2.destroyAllWindows()
...