Files
opencv/circledetect_threaded.py
T
jens 5b73cd0e1d - added
git-svn-id: http://moon:8086/svn/software/trunk/projects/opencv@310 b431acfa-c32f-4a4a-93f1-934dc6c82436
2016-09-17 10:25:43 +00:00

195 lines
5.7 KiB
Python
Executable File

# 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
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})
# self.pp.pprint(objects)
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()
# 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_bluured = cv2.medianBlur(gray,5)
# Canny edge detection
img1_canny = cv2.Canny(gray_bluured, 100, 50)
# Thresholding
# ret,img1_thr = cv2.threshold(gray1,120,255,cv2.THRESH_BINARY)
# img1_thr = cv2.adaptiveThreshold(gray1,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,11,2)
# img1_thr = cv2.adaptiveThreshold(gray1,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 = 2
roides = []
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
radius = int((member['diameter']+thickness+maskCenter)/2)
roi = frame[y-thickness:y+2*radius, x-thickness:x+2*radius]
roides.append({'roi' : roi, 'pos' : member['pos'], 'radius' : radius, 'thickness' : thickness})
else:
img1_objects = cv2.rectangle(img1_objects,(x,y),(x+w,y+h),(0,0,255),2)
memberCount += 1
for r in roides:
if radius > 0:
radius = r['radius']
thickness = r['thickness']
roi = r['roi']
pos = r['pos']
mask = np.zeros((2*radius,2*radius,1), np.uint8)
mask = cv2.circle(mask,(radius, radius),radius,255,thickness)
mean_color = cv2.mean(roi)
center = (int(pos[0]),int(pos[1]))
img1_colors = cv2.circle(img1_colors,center,radius,mean_color,thickness)
cv2.imshow('detected colors', img1_colors)
# cv2.imshow('Thresholded',img1_thr)
cv2.imshow('Canny',img1_canny)
cv2.imshow('Objects',img1_objects)
cv2.waitKey(1)
# update the FPS counter
fps.update()
findObjects.printStats()
# 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()))
# do a bit of cleanup
cv2.destroyAllWindows()