#B. Vandeportaele 29/01/2020 import numpy as np import cv2 #########################################" def mesureStats(cnt): #voir https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_properties/py_contour_properties.html M = cv2.moments(cnt) area = cv2.contourArea(cnt) perimeter = cv2.arcLength(cnt,True) #x,y,w,h = cv2.boundingRect(cnt) #aspect_ratio = float(w)/h rect = cv2.minAreaRect(cnt) #print("rect:"+str(rect)) l=rect[1][1] m=rect[1][0] w=max(l,m) h=min(l,m) #print("w:"+str(w)) #print("h:"+str(h)) if h>0: aspect_ratio = float(w)/h else: aspect_ratio = 10000000 area = cv2.contourArea(cnt) hull = cv2.convexHull(cnt) hull_area = cv2.contourArea(hull) if hull_area>0: solidity = float(area)/hull_area else: solidity=1000000 return area,perimeter,aspect_ratio,solidity ######################################### def isGrainDeRiz(cnt): area,perimeter,aspect_ratio,solidity=mesureStats(cnt) #définir une condition permettant de segmenter les grains isolés par rapport aux amas if aspect_ratio>1.9 and area<200 and area>20 and solidity>0.8: return True else: return False #########################################" im = cv2.imread('riz.jpg') imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) #seuil fixe -> nécessite un réglage manuel du seuil qui fait changer les résultats #ret,thresh = cv2.threshold(imgray,127,255,0) #le seuil qui semble optimal #ret,thresh = cv2.threshold(imgray,160,255,0) #seuillage otsu après filtre gaussien -> lisse trop #blur = cv2.GaussianBlur(imgray,(5,5),0) #ret3,thresh = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) #seuillage otsu ret3,thresh = cv2.threshold(imgray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) #kernel = np.ones((5,5),np.uint8) kernel = np.ones((3,3),np.uint8) thresh = cv2.erode(thresh,kernel,iterations = 2) thresh = cv2.dilate(thresh,kernel,iterations = 1) #thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel,iterations = 1) cv2.imshow('image1',thresh) contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #image, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_TC89_L1) #image, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_TC89_KCOS) cv2.imshow('image',imgray) cv2.imshow('image',thresh) img=im #affichage de tous les contours en vert #img = cv2.drawContours(im, contours, -1, (0,255,0), 1) #affichage du contours 4 en rouge #cnt = contours[4] #img = cv2.drawContours(img, [cnt], 0, (0,0,255), 1) #mesureStats(cnt) #cnt = contours[25] #img = cv2.drawContours(img, [cnt], 0, (255,0,0), 1) #mesureStats(cnt) Debug=False #mettre à True pour afficher les étapes du traitement #Debug=True methode=1 if methode==1: compteur=0 for i in range(0,len(contours)): #print(i) if isGrainDeRiz(contours[i]): compteur=compteur+1 #affiche les grains de riz isolé en rouge plein img = cv2.drawContours(img, [contours[i]], 0, (0,0,255), -1) else: #affiche les amas de grains de riz en bleu et uniquement les contours img = cv2.drawContours(img, [contours[i]], 0, (255,0,0), 1) if Debug: cv2.imshow('image',img) cv2.waitKey(0) cv2.destroyAllWindows() print(str(compteur)+ " grains de riz isolés trouvés") elif methode==2: #autre approche basée comparaison de forme, plus simple à implémenter mais moins bons résultats #https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contours_more_functions/py_contours_more_functions.html compteur=0 for i in range(0,len(contours)): ret = cv2.matchShapes(contours[0],contours[i],1,0.0) if ret<0.8: compteur=compteur+1 #affiche les grains de riz isolé en rouge plein img = cv2.drawContours(img, [contours[i]], 0, (0,0,255), -1) else: #affiche les amas de grains de riz en bleu et uniquement les contours img = cv2.drawContours(img, [contours[i]], 0, (255,0,0), 1) if Debug: cv2.imshow('image',img) cv2.waitKey(0) cv2.destroyAllWindows() print(str(compteur)+ " grains de riz isolés trouvés") cv2.imwrite('riz_out.png',img) cv2.imshow('image',img) cv2.waitKey(0) cv2.destroyAllWindows()