- renamed

git-svn-id: http://moon:8086/svn/software/trunk/projects/opencv@312 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
2016-09-17 13:34:41 +00:00
parent 4fb15f2147
commit 1174f0e1fc
Executable
+219
View File
@@ -0,0 +1,219 @@
# 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
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
width = 320
height = 240
class FindObjects():
def __init__(self):
self.innerOuterRatio = 0.6 # const
self.meanThickness = 0
self.meanOuterDiameter = 0
self.meanInnerDiameter = 0
self.maxDiameter = -10000
self.minDiameter = +10000
self.pp = pprint.PrettyPrinter(indent=4)
@staticmethod
def getFamily(family, parentId, hierachy):
family.append(parentId)
if hierachy[0][parentId][2] != -1:
return FindObjects.getFamily(family, hierachy[0][parentId][2], hierachy)
else:
return family
def find(self, contours, hierachy):
count = 0
objects = []
temp_objects = []
objectsIds = []
objectsCandIds = []
for cnt in contours:
if hierachy[0][count][3] == -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]})
objectsCandIds.append(members)
count += 1
for family in objectsCandIds:
obj = []
for member in family:
area = cv2.contourArea(contours[member['id']])
perimeter = cv2.arcLength(contours[member['id']], True)
pi = 3.14159265359
Q = 0
if (perimeter > 0):
Q = 4*pi*area/(perimeter*perimeter)
if Q >= 0.7:
diameter = max(member['bbox'][2], member['bbox'][3])
self.maxDiameter = max(self.maxDiameter, diameter)
self.minDiameter = min(self.minDiameter, diameter)
member['diameter'] = diameter
member['pos'] = (int(member['bbox'][0] + member['bbox'][2]/2), int(member['bbox'][1] + member['bbox'][3]/2))
obj.append(member)
if obj:
temp_objects.append(obj)
for obj in temp_objects:
for member in obj:
if member['diameter'] < self.innerOuterRatio*self.maxDiameter:
member['isHole'] = True
else:
member['isHole'] = False
if len(obj) == 2:
self.meanThickness = int(abs(obj[0]['diameter'] - obj[1]['diameter'])/2)
objects.append({'thickness' : self.meanThickness, 'members' : obj})
return objects
def printStats(self):
print ("maxDiameter = " + str(self.maxDiameter) + " px")
print ("minDiameter = " + str(self.minDiameter) + " px")
print ("meanThickness = " + str(self.meanThickness) + " px")
# construct the argument parse and parse the arguments
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,
help="Whether or not frames should be displayed")
args = vars(ap.parse_args())
# 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)
fps = FPS().start()
findObjects = FindObjects()
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()
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
gray_blurred = cv2.medianBlur(gray,5)
# Canny edge detection
img1_canny = cv2.Canny(gray_blurred, 100, 50)
kernel = np.ones((1,1),np.uint8)
# img1_canny = cv2.blur(img1_canny,(3,3))
# img1_canny = cv2.dilate(img1_canny,kernel,iterations = 1)
# Thresholding
# ret,img1_thr = cv2.threshold(gray_blurred,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# img1_thr = cv2.adaptiveThreshold(gray_blurred,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,11,2)
# img1_thr = cv2.adaptiveThreshold(gray_blurred,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2)
# Contours
(_, contours, hierachy) = cv2.findContours(img1_canny.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
objects = findObjects.find(contours, hierachy)
# print (ids)
img1_objects = frame.copy()
img1_colors = np.zeros((height,width,3), np.uint8)
maskCenter = 4
roides = []
beads = []
for obj in objects:
memberCount = 0
radius = 0
roi = 0
for member in obj['members']:
# Draw bounding box
x,y,w,h = [member['bbox'][0], member['bbox'][1], member['bbox'][2], member['bbox'][3]];
if member['isHole']:
img1_objects = cv2.rectangle(img1_objects,(x,y),(x+w,y+h),(255,0,0),2)
thickness = obj['thickness']-maskCenter
diameter = member['diameter']+thickness+maskCenter
roi = frame[y-thickness:y+diameter, x-thickness:x+diameter]
pos = member['pos']
if diameter > 0:
mask = np.zeros((diameter,diameter,1), np.uint8)
mask = cv2.circle(mask,(int(diameter/2), int(diameter/2)),radius,255,thickness)
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)
else:
img1_objects = cv2.rectangle(img1_objects,(x,y),(x+w,y+h),(0,0,255),2)
memberCount += 1
for bead in beads:
beadColors.append(bead['color'])
# cv2.imshow('Thresholded',img1_thr)
cv2.imshow('detected colors', img1_colors)
cv2.imshow('Canny',img1_canny)
cv2.imshow('Objects',img1_objects)
cv2.waitKey(1)
# update the FPS counter
fps.update()
# stop the timer and display FPS information
fps.stop()
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()))
# Output stats
findObjects.printStats()
# Scatter plot of colors
numObjects = len(beadColors);
blue = np.zeros(numObjects)
green = np.zeros(numObjects)
red = np.zeros(numObjects)
plotColors = np.zeros((numObjects,3))
i = 0
for color in beadColors:
blue[i] = color[0]/255
green[i] = color[1]/255
red[i] = color[2]/255
plotColors[i] = [red[i], green[i], blue[i]]
i += 1
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(blue, green, red, zdir='z', s=50, facecolors=plotColors, lw = 0, depthshade=True)
plt.show()
# do a bit of cleanup
cv2.destroyAllWindows()