Skip to content

Instantly share code, notes, and snippets.

@Nannigalaxy
Last active May 31, 2021 18:27
Show Gist options
  • Save Nannigalaxy/22925a60a22fcf78562f7aca09ffa4ba to your computer and use it in GitHub Desktop.
Save Nannigalaxy/22925a60a22fcf78562f7aca09ffa4ba to your computer and use it in GitHub Desktop.
Auto annotation for plain background images.
import cv2
import numpy as np
from matplotlib import pyplot as plt
def get_bbox(path, plot=False):
img = cv2.imread(path)
orig = img.copy()
################
# denoise
###############
dn = cv2.fastNlMeansDenoisingColored(img,None,30,7,21)
############
# mask
############
hsv = cv2.cvtColor(dn, cv2.COLOR_BGR2HSV)
# green color mask
mask = cv2.inRange(hsv, (26, 25, 25), (70, 255,255))
## slice the green
imask = mask>0
mask = np.zeros_like(img, np.uint8)
mask.fill(255)
mask[imask] = img[imask]
###########
# K means
###########
Z = mask.reshape((-1,3))
Z = np.float32(Z)
# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 2
ret,label,center=cv2.kmeans(Z,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)
center = np.uint8(center)
res = center[label.flatten()]
km = res.reshape((img.shape))
################
# bw from km
################
gray = cv2.cvtColor(km,cv2.COLOR_BGR2GRAY)
thresh = 127
bw = cv2.threshold(gray, thresh, 255, cv2.THRESH_BINARY)[1]
########################
# bounding box from bw
########################
ret,thresh = cv2.threshold(bw,50,255,1)
# Remove some small noise if any.
dilate = cv2.dilate(thresh,None)
erode = cv2.erode(dilate,None)
cv2.imshow('gray',erode)
# Find contours with cv2.RETR_CCOMP
contours,hierarchy = cv2.findContours(erode,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
loc = []
for i,cnt in enumerate(contours):
# Check if it is an external contour and its area is more than 100
if hierarchy[0,i,3] == -1 and cv2.contourArea(cnt)>5000:
x,y,w,h = cv2.boundingRect(cnt)
loc.extend(cv2.boundingRect(cnt))
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
if plot:
plt.subplot(231),plt.imshow(orig,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(232),plt.imshow(dn,cmap = 'gray')
plt.title('Highly Denoised Image'), plt.xticks([]), plt.yticks([])
plt.subplot(233),plt.imshow(green,cmap = 'gray')
plt.title('Mask Image'), plt.xticks([]), plt.yticks([])
plt.subplot(234),plt.imshow(km,cmap = 'gray')
plt.title('KM Image'), plt.xticks([]), plt.yticks([])
plt.subplot(235),plt.imshow(bw,cmap = 'gray')
plt.title('BW Image'), plt.xticks([]), plt.yticks([])
plt.subplot(236),plt.imshow(img,cmap = 'gray')
plt.title('Bounding Box'), plt.xticks([]), plt.yticks([])
# plt.savefig('results/result_'+str(img_path.split('/')[1].split('.')[0])+'.png')
plt.show()
return loc
if __name__ == '__main__':
import time
img_path = 'imgs/1.JPG'
st = time.time()
print(get_bbox(img_path))
print('time:',time.time()-st)
@Nannigalaxy
Copy link
Author

I have hardcoded for green leaves. Modify to your need and experiment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment