diff --git a/beadDetect.py b/beadDetect.py index 7a32fdf..4bfda16 100755 --- a/beadDetect.py +++ b/beadDetect.py @@ -1,12 +1,10 @@ # import the necessary packages from __future__ import print_function -from PiVideoStream import PiVideoStream + from imutils.video import FPS -from picamera.array import PiRGBArray -from picamera import PiCamera + import numpy as np import argparse -import imutils import time import cv2 import pprint @@ -16,6 +14,14 @@ from mpl_toolkits.mplot3d import Axes3D width = 320 height = 240 +def colordistance(color1, color2): + + d0 = (color1[0]-color2[0]) + d1 = (color1[1]-color2[1]) + d2 = (color1[2]-color2[2]) + return np.math.sqrt(d0*d0 + d1*d1 + d2*d2) + + class FindObjects(): def __init__(self): self.innerOuterRatio = 0.6 # const @@ -40,24 +46,22 @@ class FindObjects(): count = 0 objects = [] temp_objects = [] - objectsIds = [] objectsCandIds = [] - for cnt in contours: - if hierachy[0][count][3] == -1: - family = FindObjects.getFamily([], count, hierachy) + while count != -1: + family = FindObjects.getFamily([], count, hierachy) - dupDict = {} - members = [] - for member in family: - x,y,w,h = cv2.boundingRect(contours[member]); - key = str([x,y,w,h]) + '.key' - if not key in dupDict: - dupDict[key] = member - members.append({ 'id' : member, 'bbox' : [x,y,w,h]}) + dupDict = {} + members = [] + for member in family: + x,y,w,h = cv2.boundingRect(contours[member]); + key = str([x,y,w,h]) + '.key' + if not key in dupDict: + dupDict[key] = member + members.append({ 'id' : member, 'bbox' : [x,y,w,h]}) - objectsCandIds.append(members) + objectsCandIds.append(members) - count += 1 + count = hierachy[0][count][0] for family in objectsCandIds: obj = [] @@ -69,7 +73,7 @@ class FindObjects(): if (perimeter > 0): Q = 4*pi*area/(perimeter*perimeter) - if Q >= 0.7: + if Q > 0.7: diameter = max(member['bbox'][2], member['bbox'][3]) self.maxDiameter = max(self.maxDiameter, diameter) self.minDiameter = min(self.minDiameter, diameter) @@ -103,15 +107,27 @@ class FindObjects(): ap = argparse.ArgumentParser() ap.add_argument("-n", "--num-frames", type=int, default=100, help="# of frames to loop over for FPS test") -ap.add_argument("-d", "--display", type=int, default=-1, +ap.add_argument("-r", "--framerate", type=int, default=30, + help="# of frames to loop over for FPS test") +ap.add_argument("-f", "--filename", type=str, default='piCamera', help="Whether or not frames should be displayed") args = vars(ap.parse_args()) +videoFile = args["filename"] +framerate = args["framerate"] + # created a *threaded *video stream, allow the camera sensor to warmup, # and start the FPS counter -print("[INFO] sampling THREADED frames from `picamera` module...") -vs = PiVideoStream(resolution=(width,height), framerate=30).start() -time.sleep(2.0) +if videoFile == "piCamera": + from PiVideoStream import PiVideoStream + from picamera.array import PiRGBArray + from picamera import PiCamera + vs = PiVideoStream(resolution=(width,height), framerate=framerate).start() + time.sleep(2.0) +else: + vs = cv2.VideoCapture(videoFile) + +print("[INFO] sampling THREADED frames from `" + videoFile + "` at " + str(framerate) + " frame/s") fps = FPS().start() findObjects = FindObjects() @@ -120,7 +136,11 @@ beadColors = [] # loop over some frames...this time using the threaded stream while fps._numFrames < args["num_frames"]: # grab the frame from the threaded video stream - frame = vs.read() + if videoFile == "piCamera": + frame = vs.read() + else: + ret, frame = vs.read() + gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) gray_blurred = cv2.medianBlur(gray,5) @@ -137,7 +157,9 @@ while fps._numFrames < args["num_frames"]: # Contours (_, contours, hierachy) = cv2.findContours(img1_canny.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) - + img1_contours = np.zeros((height,width,3), np.uint8) + img1_contours = cv2.drawContours(img1_contours, contours, -1, (0,255,0), 1) + objects = findObjects.find(contours, hierachy) # print (ids) @@ -166,7 +188,7 @@ while fps._numFrames < args["num_frames"]: mean_color = cv2.mean(roi) img1_colors = cv2.circle(img1_colors,(int(pos[0]),int(pos[1])),int(diameter/2),mean_color,-1) beads.append({'pos' : pos, 'diameter' : diameter, 'color' : mean_color[0:3]}) - img1_objects = cv2.circle(img1_objects,member['pos'],int(diameter/2),(255,255,255),thickness) +# img1_objects = cv2.circle(img1_objects,member['pos'],int(diameter/2),(255,255,255),thickness) else: img1_objects = cv2.rectangle(img1_objects,(x,y),(x+w,y+h),(0,0,255),2) @@ -176,21 +198,30 @@ while fps._numFrames < args["num_frames"]: beadColors.append(bead['color']) # cv2.imshow('Thresholded',img1_thr) - cv2.imshow('detected colors', img1_colors) + cv2.imshow('Contours', img1_contours) + cv2.imshow('Colors', img1_colors) cv2.imshow('Canny',img1_canny) cv2.imshow('Objects',img1_objects) - cv2.waitKey(1) + if videoFile == "piCamera": + cv2.waitKey(1) + else: +# cv2.waitKey(0) + cv2.waitKey(int(1000.0/framerate)) + - # update the FPS counter + # update the FPS counter fps.update() # stop the timer and display FPS information fps.stop() -vs.stop() +if videoFile == "piCamera": + vs.stop() + print("[INFO] elasped time: {:.2f}".format(fps.elapsed())) print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) -print("[INFO] Camera : elasped time: {:.2f}".format(vs.getfps().elapsed())) -print("[INFO] Camera: approx. FPS: {:.2f}".format(vs.getfps().fps())) +if videoFile == "piCamera": + print("[INFO] Camera : elasped time: {:.2f}".format(vs.getfps().elapsed())) + print("[INFO] Camera: approx. FPS: {:.2f}".format(vs.getfps().fps())) # Output stats findObjects.printStats() @@ -218,9 +249,20 @@ ret,label,center=cv2.kmeans(Z,10,None,criteria,10,cv2.KMEANS_PP_CENTERS) print (center) +cnt1 = 0 +for c1 in center: + cnt2 = 0 + for c2 in center: + print ("Color distance["+ str(cnt1) + "," + str(cnt2) + "] = " + str(colordistance(c1, c2))) + cnt2 += 1 + cnt1 += 1 + # Scatter plot of colors fig = plt.figure() ax = fig.add_subplot(111, projection='3d') +ax.set_xlabel('blue') +ax.set_ylabel('green') +ax.set_zlabel('red') ax.scatter(blue, green, red, zdir='z', s=10, c=(0,0,0), lw = 0, depthshade=True) ax.scatter(center[:,2], center[:,1], center[:,0], zdir='z', s=500, facecolors=center, lw = 1, depthshade=True)